chartjs / chartjs-plugin-annotation

Annotation plugin for Chart.js
MIT License
603 stars 326 forks source link

Setting resizeDelay to non-zero value gives "Cannot read properties of undefined (reading 'left')" on clipArea error #909

Open edwardmjackson opened 1 year ago

edwardmjackson commented 1 year ago

Using chart.js@4.40 and chartjs-plugin-annotation@3.0.1, an error is generated "Cannot read properties of undefined (reading 'left') on clipArea" when the resizeDelay option is set to non-zero.

JSFiddle: here (or just copy and paste this into a new fiddle)

<div>
  <canvas id="myChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@3.0.1"></script>

<script>
  const ctx = document.getElementById('myChart');

  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: [1, 2, 3, 4, 5, 6],

      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      },      
      resizeDelay: 100,
      annotation: {
        annotations: {
          box1: {
            // Indicates the type of annotation
            type: 'box',
            xMin: 1,
            xMax: 2,
            yMin: 8,
            yMax: 10,
            backgroundColor: 'rgba(255, 99, 132, 0.25)'
          }
        }
      }
    }
  });
</script>

If you comment and uncomment line 28, resizeDelay: 100, the JSFiddle shows "script error" appear when resizeDelay is set.

The error appears to be in the Draw function

https://github.com/chartjs/chartjs-plugin-annotation/blob/193e4ceba18c4d242e8e7d30bcc2ee78b135894f/src/annotation.js#L151-L167

Where clipArea(ctx, chartArea) is called but chartArea is not yet defined, hence the chart.js helper at https://github.com/chartjs/Chart.js/blob/master/src/helpers/helpers.canvas.ts#L327 fails.

My guess at a possible solution could be to only draw if ctx and chartArea are defined?

alternatively, it may be one for the maintainers of chartJS to fix for all users of plugin helprs. It only seems to affect chartjs-plugin-annotation however, not other plugins we're currently using such as chartjs-plugin-zoom

stockiNail commented 1 year ago

@edwardmjackson thank you for issue. I have tried your code both in JSFiddle and Codepen but I don't have any issue, both enabling and disabling resizeDelay.

You can see my codepen https://codepen.io/stockinail/pen/YzdELbx. Anyway I see that the box annotation looks like to be configured in the wrong place, in chart options. The annotation plugin options must be located in the "plugins" node of chart options.

If I have done something wrong for reproducing your issue, let me know.

edwardmjackson commented 1 year ago

This is very curious. I reproduced at work, which is using Chrome. At home, Firefox (at least v 117.0.1) doesn't have the same issue though. The Chrome build is Version 116.0.5845.188 (64-bit) on Windows.

Hopefully this ScreenToGif works to show what I'm seeing. Animation

stockiNail commented 1 year ago

uhmm... It's really weird. I have tried with Chrome Version 117.0.5938.88 (Official Build) (and before with FF 117.0.1) and no issue doing the same things you showed me in the img. Let me take time (I'm very busy on other stuff in this period) to try reproducing the issue.

stockiNail commented 1 year ago

I was able to reproduce it. JSFiddle + Chrome. With FF works and on Codepen works on both browser. Anyway, let me report here the exception:

Uncaught TypeError: Cannot read properties of undefined (reading 'left')
    at Object.Ie [as clipArea] (chart.js@4.4.0:19:18340)
    at Jt (chartjs-plugin-annotation@3.0.1:7:33797)
    at Object.beforeDraw (chartjs-plugin-annotation@3.0.1:7:33031)
    at d (chart.js@4.4.0:13:1113)
    at sn._notify (chart.js@4.4.0:19:82974)
    at sn.notify (chart.js@4.4.0:19:82795)
    at An.notifyPlugins (chart.js@4.4.0:19:101789)
    at An.draw (chart.js@4.4.0:19:97016)
    at An.render (chart.js@4.4.0:19:96791)
    at An._resize (chart.js@4.4.0:19:91846)