0
votes

I am pretty new to using Javascript, so forgive me if this is a nobish question.

I am trying to make a chart with 4 datasets, where 3rd dataset is stacked with 1st and 4th is stacked with 2nd. I've tried using the grouped stacked bar chart, but it just stacks 3rd and 4th on the 2nd.

I've tested using some standard inputs like in the link below.

The below approach works fine with 1 chart, just doesn't seem to work on multiple charts on the same page, as it tries to run the plugin on both charts as soon as the first one is done, which means the 2nd is not done rendering.

How to add an offset to a dataset in Chart js

I've tried using the inline plugin approach from the chart.js doc, but it still runs on both charts. Is there anyway to get the specific chart instance or is there some other approach to this?

var ctx = document.getElementById("myChartTEC").getContext("2d");
    var myChart = new Chart.Line(ctx, {
        type: 'line',
        data: {
            labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
            datasets: [{
                data: [5, 10.5, 18.2, 33.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                pointLabelFontSize: 4,
                borderWidth: 2,
                fill: false,
                lineTension: .3,
                borderColor: "#f37029",
                borderCapStyle: 'round',
                borderDash: [],
                borderDashOffset: 0.0,
                borderJoinStyle: 'bevel',
                pointBorderColor: "#f37029",
                pointBackgroundColor: "#f37029",
                pointBorderWidth: 1,
                pointHoverRadius: 4,
                pointHoverBackgroundColor: "rgba(220,220,220,1)",
                pointHoverBorderColor: "rgba(220,220,220,1)",
                pointHoverBorderWidth: 2,
                pointRadius: 4,
                pointHitRadius: 10,
                spanGaps: false,
            },
                {
                    data: [10, 20, 5.2, 35.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                    pointLabelFontSize: 4,
                    borderWidth: 2,
                    fill: false,
                    lineTension: .3,
                    borderColor: "#f37029",
                    borderCapStyle: 'round',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'bevel',
                    pointBorderColor: "#f37029",
                    pointBackgroundColor: "#f37029",
                    pointBorderWidth: 1,
                    pointHoverRadius: 4,
                    pointHoverBackgroundColor: "rgba(220,220,220,1)",
                    pointHoverBorderColor: "rgba(220,220,220,1)",
                    pointHoverBorderWidth: 2,
                    pointRadius: 4,
                    pointHitRadius: 10,
                    spanGaps: false,
                }
            ]
        },
        plugins: [{
            afterUpdate: function (chart) {
                var dataset = chart.config.data.datasets[0];
                var offset = -20;

                for (var i = 0; i < dataset._meta[0].data.length; i++) {
                    var model = dataset._meta[0].data[i]._model;
                    model.x += offset;
                    model.controlPointNextX += offset;
                    model.controlPointPreviousX += offset;
                }

                var dataset2 = chart.config.data.datasets[1];
                var offset2 = 20;

                for (var o = 0; o < dataset2._meta[0].data.length; o++) {
                    var model2 = dataset2._meta[0].data[o]._model;
                    model2.x += offset2;
                    model2.controlPointNextX += offset2;
                    model2.controlPointPreviousX += offset2;
                }
            }
        }],
        options: {
            scales: {
                xAxes: [{
                    gridLines: {
                        offsetGridLines: true,
                        display: false,
                        borderDash: [6, 2],
                        tickMarkLength: 5
                    },
                    ticks: {
                        fontSize: 8,
                        labelOffset: 10,
                        maxRotation: 0
                    }
                }],
                yAxes: [{
                    gridLines: {
                        display: false
                    },
                    ticks: {
                        beginAtZero: true,
                        max: 200,
                        min: 0,
                        stepSize: 20,
                        fontSize: 8
                    }
                }]
            },
            legend: {
                display: false
            },
            responsive: false,
            maintainAspectRatio: true
        }
    });
    var ctx = document.getElementById("myChart").getContext("2d");
    var myChart = new Chart.Line(ctx, {
        type: 'line',
        data: {
            labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
            datasets: [{
                data: [5, 10.5, 18.2, 33.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                pointLabelFontSize: 4,
                borderWidth: 2,
                fill: false,
                lineTension: .3,
                borderColor: "#f37029",
                borderCapStyle: 'round',
                borderDash: [],
                borderDashOffset: 0.0,
                borderJoinStyle: 'bevel',
                pointBorderColor: "#f37029",
                pointBackgroundColor: "#f37029",
                pointBorderWidth: 1,
                pointHoverRadius: 4,
                pointHoverBackgroundColor: "rgba(220,220,220,1)",
                pointHoverBorderColor: "rgba(220,220,220,1)",
                pointHoverBorderWidth: 2,
                pointRadius: 4,
                pointHitRadius: 10,
                spanGaps: false,
            },
                {
                    data: [10, 20, 5.2, 35.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                    pointLabelFontSize: 4,
                    borderWidth: 2,
                    fill: false,
                    lineTension: .3,
                    borderColor: "#f37029",
                    borderCapStyle: 'round',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'bevel',
                    pointBorderColor: "#f37029",
                    pointBackgroundColor: "#f37029",
                    pointBorderWidth: 1,
                    pointHoverRadius: 4,
                    pointHoverBackgroundColor: "rgba(220,220,220,1)",
                    pointHoverBorderColor: "rgba(220,220,220,1)",
                    pointHoverBorderWidth: 2,
                    pointRadius: 4,
                    pointHitRadius: 10,
                    spanGaps: false,
                }]
        },
// This part is not working. Uncaught TypeError: Cannot read property 'data' of undefined
        plugins: [{
            afterUpdate: function (chart) {
                var dataset = chart.config.data.datasets[0];
                var offset = -20;

                for (var i = 0; i < dataset._meta[0].data.length; i++) {
                    var model = dataset._meta[0].data[i]._model;
                    model.x += offset;
                    model.controlPointNextX += offset;
                    model.controlPointPreviousX += offset;
                }

                var dataset2 = chart.config.data.datasets[1];
                var offset2 = 20;

                for (var o = 0; o < dataset2._meta[0].data.length; o++) {
                    var model2 = dataset2._meta[0].data[o]._model;
                    model2.x += offset2;
                    model2.controlPointNextX += offset2;
                    model2.controlPointPreviousX += offset2;
                }
            }
        }],
        options: {
            scales: {
                xAxes: [{
                    gridLines: {
                        offsetGridLines: true,
                        display: false,
                        borderDash: [6, 2],
                        tickMarkLength: 5
                    },
                    ticks: {
                        fontSize: 8,
                        labelOffset: 10,
                        maxRotation: 0
                    }
                }],
                yAxes: [{
                    gridLines: {
                        display: false
                    },
                    ticks: {
                        beginAtZero: true,
                        max: 200,
                        min: 0,
                        stepSize: 20,
                        fontSize: 8
                    }
                }]
            },
            legend: {
                display: false
            },
            responsive: false,
            maintainAspectRatio: true
        }
    });
1
Provide some code to understand your problem better.kk.
Added the code I am using for testing. It works on the first chart, but breaks on the 2nd.DennisSchou
I haven't solved it. The problem is that it's working on the 1st chart that is loading (not nessesarily the 1st chart in the code). The problem seems to be that the afterUpdate event triggers on both charts even though it's put as an inline plugin. So when it fires on the 1st chart it tries to run on the 2ns chart as well, but fails because it's not done loading.DennisSchou

1 Answers

0
votes

The issue is, whenever you create an inline-plugin for a new chart instance, you would also need to increase the index number of _meta[index] in both the for loops. SO, for the first chart it will be _meta[0] , second chart _meta[1] , third chart _meta[2] and so on ...

Here is the working version of your code ...

var ctx = document.getElementById("myChartTEC").getContext("2d");
var myChart = new Chart.Line(ctx, {
  type: 'line',
  data: {
    labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
    datasets: [{
      data: [5, 10.5, 18.2, 33.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
      pointLabelFontSize: 4,
      borderWidth: 2,
      fill: false,
      lineTension: .3,
      borderColor: "#f37029",
      borderCapStyle: 'round',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'bevel',
      pointBorderColor: "#f37029",
      pointBackgroundColor: "#f37029",
      pointBorderWidth: 1,
      pointHoverRadius: 4,
      pointHoverBackgroundColor: "rgba(220,220,220,1)",
      pointHoverBorderColor: "rgba(220,220,220,1)",
      pointHoverBorderWidth: 2,
      pointRadius: 4,
      pointHitRadius: 10,
      spanGaps: false,
    }, {
      data: [10, 20, 5.2, 35.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
      pointLabelFontSize: 4,
      borderWidth: 2,
      fill: false,
      lineTension: .3,
      borderColor: "#f37029",
      borderCapStyle: 'round',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'bevel',
      pointBorderColor: "#f37029",
      pointBackgroundColor: "#f37029",
      pointBorderWidth: 1,
      pointHoverRadius: 4,
      pointHoverBackgroundColor: "rgba(220,220,220,1)",
      pointHoverBorderColor: "rgba(220,220,220,1)",
      pointHoverBorderWidth: 2,
      pointRadius: 4,
      pointHitRadius: 10,
      spanGaps: false,
    }]
  },
  plugins: [{
    afterUpdate: function(chart) {
      var dataset = chart.config.data.datasets[0];
      var offset = -20;

      for (var i = 0; i < dataset._meta[0].data.length; i++) {
        var model = dataset._meta[0].data[i]._model;
        model.x += offset;
        model.controlPointNextX += offset;
        model.controlPointPreviousX += offset;
      }

      var dataset2 = chart.config.data.datasets[1];
      var offset2 = 20;

      for (var o = 0; o < dataset2._meta[0].data.length; o++) {
        var model2 = dataset2._meta[0].data[o]._model;
        model2.x += offset2;
        model2.controlPointNextX += offset2;
        model2.controlPointPreviousX += offset2;
      }
    }
  }],
  options: {
    scales: {
      xAxes: [{
        gridLines: {
          offsetGridLines: true,
          display: false,
          borderDash: [6, 2],
          tickMarkLength: 5
        },
        ticks: {
          fontSize: 8,
          labelOffset: 10,
          maxRotation: 0
        }
      }],
      yAxes: [{
        gridLines: {
          display: false
        },
        ticks: {
          beginAtZero: true,
          max: 200,
          min: 0,
          stepSize: 20,
          fontSize: 8
        }
      }]
    },
    legend: {
      display: false
    },
    responsive: false,
    maintainAspectRatio: true
  }
});

var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart.Line(ctx, {
  type: 'line',
  data: {
    labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
    datasets: [{
      data: [5, 10.5, 18.2, 33.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
      pointLabelFontSize: 4,
      borderWidth: 2,
      fill: false,
      lineTension: .3,
      borderColor: "#f37029",
      borderCapStyle: 'round',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'bevel',
      pointBorderColor: "#f37029",
      pointBackgroundColor: "#f37029",
      pointBorderWidth: 1,
      pointHoverRadius: 4,
      pointHoverBackgroundColor: "rgba(220,220,220,1)",
      pointHoverBorderColor: "rgba(220,220,220,1)",
      pointHoverBorderWidth: 2,
      pointRadius: 4,
      pointHitRadius: 10,
      spanGaps: false,
    }, {
      data: [10, 20, 5.2, 35.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
      pointLabelFontSize: 4,
      borderWidth: 2,
      fill: false,
      lineTension: .3,
      borderColor: "#f37029",
      borderCapStyle: 'round',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'bevel',
      pointBorderColor: "#f37029",
      pointBackgroundColor: "#f37029",
      pointBorderWidth: 1,
      pointHoverRadius: 4,
      pointHoverBackgroundColor: "rgba(220,220,220,1)",
      pointHoverBorderColor: "rgba(220,220,220,1)",
      pointHoverBorderWidth: 2,
      pointRadius: 4,
      pointHitRadius: 10,
      spanGaps: false,
    }]
  },

  plugins: [{
    afterUpdate: function(chart) {
      var dataset = chart.config.data.datasets[0];
      var offset = -20;

      for (var i = 0; i < dataset._meta[1].data.length; i++) {
        var model = dataset._meta[1].data[i]._model;
        model.x += offset;
        model.controlPointNextX += offset;
        model.controlPointPreviousX += offset;
      }

      var dataset2 = chart.config.data.datasets[1];
      var offset2 = 20;

      for (var o = 0; o < dataset2._meta[1].data.length; o++) {
        var model2 = dataset2._meta[1].data[o]._model;
        model2.x += offset2;
        model2.controlPointNextX += offset2;
        model2.controlPointPreviousX += offset2;
      }
    }
  }],
  options: {
    scales: {
      xAxes: [{
        gridLines: {
          offsetGridLines: true,
          display: false,
          borderDash: [6, 2],
          tickMarkLength: 5
        },
        ticks: {
          fontSize: 8,
          labelOffset: 10,
          maxRotation: 0
        }
      }],
      yAxes: [{
        gridLines: {
          display: false
        },
        ticks: {
          beginAtZero: true,
          max: 200,
          min: 0,
          stepSize: 20,
          fontSize: 8
        }
      }]
    },
    legend: {
      display: false
    },
    responsive: false,
    maintainAspectRatio: true
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="myChartTEC"></canvas>
<canvas id="myChart"></canvas>