Chartjs 2 - Stacked bar and unstacked line on same chart with same y axis

只愿长相守 提交于 2020-01-31 03:37:05

问题


I've started using the latest beta of v2 of chart.js since I need to draw a chart that contains both a stacked bar chart and an unstacked line chart on the same chart. Here's an example of what I need:

In this chart the lines are not stacked and are all showing their natural values but the bar chart is stacked and shows the combined total of the values (including some negative values).

I've managed to get the two charts drawn together but so far I've only succeeded in either having both charts stacked or I've had to use two separate y-axis which ends up with 2 scales. There's an example of the separate y-axis in this fiddle:

yAxes: [{
    stacked: false,
    ticks: {
      beginAtZero: true
    }
  }, {
    id: "bar-y-axis",
    stacked: true,
    ticks: {
      beginAtZero: true
    },
    type: 'linear'
  }]

If I remove the first y-axis then I ended up with a single scale with the only problem being that the line chart is now stacked as well.

Is there any way to draw a chart like I need using chart.js?


回答1:


You can get this functionality with a combination of setting a different yAxisID (e.g. yAxisID: "bar-stacked") to each of your datasets, and then adding a second options.scales.yAxes object. So you would have this as a dataset:

{
  label: 'Promoters',
  backgroundColor: "#aad700",
  yAxisID: "bar-stacked",
  data: [
    50, 44, 52, 62, 48, 58, 59, 50, 51, 52, 53, 54
  ]
}

and then you would add an additional yAxes (the first one will be the collection of your line datasets [no yAxisId in the example below], the second will be all of the bars you want stacked):

yAxes: [{
  stacked: false,
  ticks: {
    beginAtZero: true,
    min: 0,
    max: 100
  }
}, {
  id: "bar-stacked",
  stacked: true,
  display: false, //optional if both yAxes use the same scale
  ticks: {
    beginAtZero: true,
    min: 0,
    max: 100
  },
  type: 'linear'
}]

Full example is as follows:

<!doctype html>
<html>

<head>
  <title>Stacked Bar Chart</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.js"></script>
  <style>
    canvas {
      -moz-user-select: none;
      -webkit-user-select: none;
      -ms-user-select: none;
    }
  </style>
</head>

<body>
  <div style="width: 100%">
    <canvas id="canvas"></canvas>
  </div>
  <script>
    var barChartData = {
      labels: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
      datasets: [{
        data: [
          50, 30, 60, 70, 80, 90, 95, 70, 90, 20, 60, 95
        ],
        type: 'line',
        label: 'This Year',
        fill: false,
        backgroundColor: "#fff",
        borderColor: "#70cbf4",
        borderCapStyle: 'butt',
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: 'miter',
        lineTension: 0.3,
        pointBackgroundColor: "#fff",
        pointBorderColor: "#70cbf4",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "#70cbf4",
        pointHoverBorderColor: "#70cbf4",
        pointHoverBorderWidth: 2,
        pointRadius: 4,
        pointHitRadius: 10
      }, {
        data: [
          25, 40, 30, 70, 60, 50, 40, 70, 40, 80, 30, 90
        ],
        type: 'line',
        label: 'Last Year',
        fill: false,
        backgroundColor: "#fff",
        borderColor: "#737373",
        borderCapStyle: 'butt',
        borderDash: [10, 10],
        borderDashOffset: 0.0,
        borderJoinStyle: 'miter',
        lineTension: .3,
        pointBackgroundColor: "#fff",
        pointBorderColor: "#737373",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "#737373",
        pointHoverBorderColor: "#737373",
        pointHoverBorderWidth: 2,
        pointRadius: 4,
        pointHitRadius: 10
      }, {
        label: 'Promoters',
        backgroundColor: "#aad700",
        yAxisID: "bar-y-axis",
        data: [
          50, 44, 52, 62, 48, 58, 59, 50, 51, 52, 53, 54
        ]
      }, {
        label: 'Passives',
        backgroundColor: "#ffe100",
        yAxisID: "bar-y-axis",
        data: [
          20, 21, 24, 25, 26, 17, 28, 19, 20, 11, 22, 33
        ]
      }, {
        label: 'Detractors',
        backgroundColor: "#ef0000",
        yAxisID: "bar-y-axis",
        data: [
          30, 35, 24, 13, 26, 25, 13, 31, 29, 37, 25, 13
        ]
      }]
    };

    window.onload = function() {
      var ctx = document.getElementById("canvas").getContext("2d");
      window.myBar = new Chart(ctx, {
        type: 'bar',
        data: barChartData,
        options: {
          title: {
            display: true,
            text: "Chart.js Bar Chart - Stacked"
          },
          tooltips: {
            mode: 'label'
          },
          responsive: true,
          scales: {
            xAxes: [{
              stacked: true,
            }],
            yAxes: [{
              stacked: false,
              ticks: {
                beginAtZero: true,
                min: 0,
                max: 100
              }
            }, {
              id: "bar-y-axis",
              stacked: true,
              display: false, //optional
              ticks: {
                beginAtZero: true,
                min: 0,
                max: 100
              },
              type: 'linear'
            }]
          }
        }
      });
    };
  </script>
</body>

</html>



回答2:


Another answer here - you can set a 'stack' identifier for the data you want to be cumulative (i.e. just the bars), and turn off 'fill' on the line graphs to draw just as a line rather than mountain range

Chart.js remove stacking



来源:https://stackoverflow.com/questions/34929095/chartjs-2-stacked-bar-and-unstacked-line-on-same-chart-with-same-y-axis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!