【问题标题】:Chart.js with dual axis on bar and line graphChart.js 在条形图和折线图上具有双轴
【发布时间】:2021-02-09 18:32:13
【问题描述】:

我正在使用来自本主题 Chart.js how to get Combined Bar and line charts? 的 Quince 的 Chart.js 版本。条形图和折线图看起来非常漂亮。无论如何,轴必须分成 Y1 和 Y2,我找不到 Quince 的版本支持。

我再次搜索并找到了这个主题How to add second Y-axis for Bar and Line chart in Chart.js?,它建议使用可以处理双轴的 Khertan 的 Chart.js,但我找不到在一个图中组合条形和线的方法。

我尝试将此选项输入到 Quince 的版本中,但没有成功。

scaleUse2Y: true,

有什么办法可以做到吗?感谢您的热心帮助。

<script>
Chart.defaults.global.templateInterpolators = {
    start: "[[",
    end: "]]"
};
Chart.defaults.global.scaleLabel = "[[= value ]]";
Chart.defaults.global.tooltipTemplate = "[[if (label){]][[= label ]]:     [[}]][[= value ]]";
Chart.defaults.global.multiTooltipTemplate = "[[= value ]]";


var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
        label: "My First dataset",
        color:"#F7464A",
        //new option, barline will default to bar as that what is used to create the scale
        type: "line",
        fillColor: "rgba(220,220,220,0.2)",  //White
        strokeColor: "rgba(220,220,220,1)", //gray
        pointColor: "rgba(220,220,220,1)",  //gray
        pointStrokeColor: "#fff",
        pointHighlightFill: "#fff",
        pointHighlightStroke: "rgba(220,220,220,1)",
        data: [65, 20, 43, 81, 56, 55, 40]
    }, {
        label: "My First dataset",
        color:"#F7464A",
        //new option, barline will default to bar as that what is used to create the scale
        type: "bar",
        fillColor: "rgba(255, 187, 0, 1)",
        strokeColor: "rgba(255, 187, 0, 1)",
        pointColor: "rgba(255, 187, 0, 1)",
        pointStrokeColor: "#fff",
        pointHighlightFill: "#fff",
        pointHighlightStroke: "rgba(220,220,220,1)",
        data: [32, 25, 43, 22, 12, 92, 33]
    }]
};

//canvases
var lineBar = document.getElementById("line-bar").getContext("2d");

//charts
var myLineBarChart = new Chart(lineBar).Overlay(data);

在这个 HTML 中

<ul class="tabs"><li><input type="radio" name="tabs" id="tab1"checked />
<label for="tab1" onclick="rePlot(1,3)">2015</label>
<div id="tab-content1" class="tab-content" onclick="rePlot(1,3)">
<canvas group="canvas" id="line-bar" height="450" width="600" style="background-color:#8CDFD3;"></canvas>
</div>
</li>

<li><input type="radio" name="tabs" id="tab2" /><label for="tab2" onclick="rePlot(2,3)">2014</label>
<div id="tab-content2" class="tab-content" onclick="rePlot(2,3)">

<canvas group="canvas" id="line-bar" height="450" width="600" style="background-color:#8CDFD3;"></canvas>
</div>
</li>

<li><input type="radio" name="tabs" id="tab3" /><label for="tab3" onclick="rePlot(3,3)">2013</label>
<div id="tab-content3" class="tab-content" onclick="rePlot(3,3)">

<canvas group="canvas" id="line-bar" height="450" width="600" style="background-color:#8CDFD3;"></canvas>
</div>
</li>
</ul>

【问题讨论】:

标签: javascript charts tabs chart.js


【解决方案1】:

我终于将我的多轴功能端口推送到了这个 fork 上的 master 上。作为对正在发生的事情的一个非常简短的概述,我在比例尺中添加了一组轴。每个轴都能够根据 y 相对于它自己的比例计算一个值的位置。开发人员现在唯一需要做的就是说明每个数据集需要属于哪个轴组。每个轴也可以被告知它应该是什么颜色以及它应该出现在图表的哪一侧。

如何使用它 - 在每个数据集中声明一个名为 yAxesGroup 的新属性

 datasets: [{
         label: "My First dataset",
         type: "bar",
         yAxesGroup: "1", //any with same group will appear in the same axis, also this can be anything as long as you always refer to it with the same name
         fillColor: "rgba(151,137,200,0.5)",
         strokeColor: "rgba(151,137,200,0.8)",
         highlightFill: "rgba(151,137,200,0.75)",
         highlightStroke: "rgba(151,137,200,1)",
         data: [28, 48, 40, 19, 86, 27, 90]
     },

然后为该轴提供更多选项,为数据添加一个名为yAxis 的额外属性,这是一个轴选项数组。默认情况下,每个轴将在左侧显示一个比例,并以默认颜色或您已设置为整体字体颜色的任何颜色显示,但在这里您可以覆盖它们

 var overlayData = {
     labels: ["January", "Februarya", "March", "April", "May", "Jun", "July"],
     datasets: [{
         label: "My First dataset",
         type: "bar",
         yAxesGroup: "1",
         fillColor: "rgba(151,137,200,0.5)",
         strokeColor: "rgba(151,137,200,0.8)",
         highlightFill: "rgba(151,137,200,0.75)",
         highlightStroke: "rgba(151,137,200,1)",
         data: [28, 48, 40, 19, 86, 27, 90]
     }, {
         label: "My Second dataset",
         type: "line",
         yAxesGroup: "2",
         fillColor: "rgba(151,187,205,0.5)",
         strokeColor: "rgba(151,187,205,0.8)",
         highlightFill: "rgba(151,187,205,0.75)",
         highlightStroke: "rgba(151,187,205,1)",
         data: [8, 38, 30, 29, 46, 67, 80]
     }],
     yAxes: [{
         name: "1",
         scalePositionLeft: false,
         scaleFontColor: "rgba(151,137,200,0.8)"
     }, {
         name: "2",
         scalePositionLeft: true,
         scaleFontColor: "rgba(151,187,205,0.8)"
     }]
 };

现在此图表将有 2 个轴,一个在左侧,一个在右侧。

有几点需要注意,如果任何值低于 0,则需要将 scaleBeginAtZero 的整体属性设置为 false,否则会有点混乱。此外,每个轴都有自己的 0 基线,因此两侧不会对齐。这是我决定的,因为我决定你有两个轴的原因是因为它们显示不同的比例,所以为了让所有东西都很好地坐在 0 中,每个轴需要在不同的位置。

我已经完成并测试了它的回归与我添加的其他功能,这一切似乎都很好,但如果你确实使用它并注意到任何奇怪的东西,请告诉我。

此外,我还无法将其编写为 chartjs 的插件,因为在核心中涉及了太多内容,因此您将从 fork 构建的版本而不只是覆盖 chartjs 的原始版本没有意义。

总的来说这是它会产生的效果

 var overlayData = {
     labels: ["January", "Februarya", "March", "April", "May", "Jun", "July"],
     datasets: [{
         label: "My First dataset",
         type: "bar",
         yAxesGroup: "1",
         fillColor: "rgba(151,137,200,0.5)",
         strokeColor: "rgba(151,137,200,0.8)",
         highlightFill: "rgba(151,137,200,0.75)",
         highlightStroke: "rgba(151,137,200,1)",
         data: [28, 48, 40, 19, 86, 27, 90]
     }, {
         label: "My Second dataset",
         type: "line",
         yAxesGroup: "2",
         fillColor: "rgba(151,187,205,0.5)",
         strokeColor: "rgba(151,187,205,0.8)",
         highlightFill: "rgba(151,187,205,0.75)",
         highlightStroke: "rgba(151,187,205,1)",
         data: [8, 38, 30, 29, 46, 67, 80]
     }],
     yAxes: [{
         name: "1",
         scalePositionLeft: false,
         scaleFontColor: "rgba(151,137,200,0.8)"
     }, {
         name: "2",
         scalePositionLeft: true,
         scaleFontColor: "rgba(151,187,205,0.8)"
     }]
 };

 window.onload = function () {
     window.myOverlayChart = new Chart(document.getElementById("canvas").getContext("2d")).Overlay(overlayData, {
         populateSparseData: true,
         overlayBars: false,
         datasetFill: true,
     });
 }
<script src="https://raw.githack.com/leighquince/Chart.js/master/Chart.js"></script>

<canvas id="canvas" height="300" width="300"></canvas>

【讨论】:

  • 谢谢昆斯,你太棒了。 :)
  • 有没有办法将刻度放在“刻度点”而不是中间?我将它用于带有 2 个 y 轴的 2 个折线图,所以当线条没有一直走到尽头时,它现在看起来很奇怪。
  • 如果您使用折线图而不是叠加图(如果您只想要线条),那么应该可以使用