Search code examples
chart.jschartjs-plugin-annotation

Chart.JS - multiple - box - annotations - displays only the last box


I am using Chart.Js and chartjs-plugin-annotation to display multiple line graphs and annotations to split the chart area in seven zones of different colors.

Right now I am trying with two boxes to start with.

X-Axis - displays time - in HH:m format. Y-Axis - displays values - for the four series.

Problem I face is I see only the second box, and not the first one.

Also the second box occupies entire chart area.

Here is the JSFiddle for the issue I am facing - https://jsfiddle.net/marathepa/16th0x3d/14/

I use the following code for the annotations -




var options = {
    scales: {
        xAxes: [{
            type: 'time',
            time: {
                displayFormats: timeFormat,
            }
        }]
    },
    plugins: {
        annotation: {
            annotations: {
                box1: {
                    type: "box",
                    drawTime: "beforeDatasetsDraw",
                    xMin: Val1,
                    xMax: Val2,
                    yMin: Val3,
                    yMax: Val4,
                    backgroundColor: XXXXXXXXXXXXX,
                    xScaleID: 'x-axis-0'

                },
                box2: {
                    type: "box",
                    drawTime: "beforeDatasetsDraw",
                    xMin: Val5,
                    xMax: Val6,
                    yMin: Val3,
                    yMax: Val4,
                    backgroundColor: Val3,
                    xScaleID: 'x-axis-0'
                }

            }
        }
    }
};

If I give the annotations - yScaleID - it doesn't show anything for the boxes.

Val1, Val2, Val5 and Val6 use the same time format format as used by lables (x-axis)

When I hard code Val1, Val2, Val5 and Val6 to specific values, I see only the second box.

Issues seems to be the date values for - labels. Labels are date values and I need to use subset of those on the xMin: Val1,xMax: Val2 and Val5 and Val6 on the annotations.

Links explaining the issue -

https://github.com/chartjs/chartjs-plugin-annotation/issues/438#event-4976403966

https://github.com/chartjs/chartjs-plugin-annotation/discussions/439#discussioncomment-966664


Solution

  • 2 things. First you tried defining the scales config in the v2 way, this doesnt work anymore. You shouldnt define your scale as time since you dont use time objects, to use the timeScale you need to provide moment/luxon or any other date lib objects and the corresponding date adapter so chart.js can automatically make ticks for the scale.

    Also as defined in the chart.js annotation docs (https://www.chartjs.org/chartjs-plugin-annotation/guide/types/box.html#configuration) you need to provide a number for the xMin and xMax prop so you can give it the label, you give it the index of where it needs to draw it.

    Live example:

    var timeFormat = {
      'millisecond': 'HH:mm',
      'second': 'HH:mm',
      'minute': 'HH:mm',
      'hour': 'HH:mm',
      'day': 'HH:mm',
      'week': 'HH:mm',
      'month': 'HH:mm',
      'quarter': 'HH:mm',
      'year': 'HH:mm',
    };
    
    
    const options = {
      type: 'line',
      data: {
        labels: ['6:38', '6:38', '6:38', '6:38', '6:39', '6:39', '6:39', '6:39', '6:39', '6:39', '6:40', '6:40', '6:40', '6:40', '6:40', '6:40', '6:41', '6:41', '6:41', '6:41', '6:41', '6:41', '6:42', '6:42', '6:42', '6:42', '6:42', '6:42', '6:43', '6:43', '6:43', '6:43', '6:43', '6:43', '6:44', '6:44', '6:44', '6:44', '6:44', '6:44', '6:45', '6:45', '6:45', '6:45', '6:45', '6:45', '6:46', '6:46', '6:46', '6:46', '6:46', '6:46', '6:47', '6:47', '6:47', '6:47', '6:47', '6:47', '6:48', '6:48', '6:48', '6:48', '6:48', '6:48', '6:49', '6:49', '6:49', '6:49', '6:49', '6:49', '6:50', '6:50', '6:50', '6:50', '6:50', '6:50', '6:51', '6:51', '6:51', '6:51', '6:51', '6:51', '6:52', '6:52', '6:52', '6:52', '6:52', '6:52', '6:53', '6:53', '6:53', '6:53', '6:53', '6:53', '6:54', '6:54', '6:54', '6:54', '6:54', '10:54'],
    
    
    
        datasets: [{
          label: '# of Votes',
          data: [12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 2, 19, 3, 5, 2, 2, 19, 3, 5, 2, 2, 19, 3, 5, 2, 3],
          borderWidth: 1
        }]
      },
      options: {
        scales: {
          // New way of defining scales
          x: {
            grid: {
              color: 'red'
            }
          },
          y: {}
        },
        plugins: {
          annotation: {
            annotations: {
              box1: {
                type: "box",
                drawTime: "beforeDatasetsDraw",
                xMin: '6:39', // doesnt work, needs point index
                xMax: '7:00', // doesnt work, needs point index
                yMin: 2,
                yMax: 10,
                backgroundColor: "red",
    
    
              },
              box2: {
                type: "box",
                drawTime: "beforeDatasetsDraw",
                xMin: 7,
                xMax: 10.14,
                yMin: 2,
                yMax: 10,
                backgroundColor: "blue",
    
              }
            }
          }
        }
      }
    }
    
    const ctx = document.getElementById('chartJSContainer').getContext('2d');
    const chart = new Chart(ctx, options);
    
    document.getElementById("tt").addEventListener("click", () => {
      chart.options.plugins.annotation.annotations.box1.yMax = 16;
      chart.update();
    });
    
    document.getElementById("rr").addEventListener("click", () => {
      chart.options.plugins.annotation.annotations.box1.yMax = 8;
      chart.update();
    });
    <body>
      <canvas id="chartJSContainer" width="600" height="400"></canvas>
      <button id="tt">Update annotation to 16</button>
      <button id="rr">Update annotation to 8</button>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/1.0.2/chartjs-plugin-annotation.js"></script>
    </body>

    Basic fiddle with example of the time scale implementation with moment: https://jsfiddle.net/Leelenaleee/bza0v3rc/11/