chartjs/chartjs-plugin-datalabels

pie chart - data labels - ERROR

kevinjamesbaker opened this issue ยท 14 comments

"chart.js": "2.8.0",
"chartjs-node-canvas": "2.4.0",
"chartjs-plugin-datalabels": "^0.6.0"

{"type":"pie","data":{"labels":["Managed Ca..","Medicare A","Private"],"datasets":[{"data":[101,102,103],"label":"Daily Census","backgroundColor":["rgba(54, 162, 235, 0.2)","rgba(255, 206, 86, 0.2)","rgba(75, 192, 192, 0.2)"],"borderColor":["rgba(54, 162, 235, 1)","rgba(255, 206,
86, 1)","rgba(75, 192, 192, 1)"],"borderWidth":0,"format":"0.00a"}]},"options":null}

function orient(point, origin) {
var x0 = origin.x; <-- TypeError: Cannot read property 'x' of null
var y0 = origin.y;

@kevinjamesbaker "options": null looks quite suspect but can't test it, please provide a codepen that reproduces your issue.

Closing as outdated, feel free to re-open with the requested additional info.

I've recently faced the same issue. Here's Codepen script which demonstrates the issue in action. See browser console for the errors there.

The chart sometimes renders fine, but if you're lucky enough it will stuck at animation. But even if it's rendered properly the same error occurs whenever you hover the doughnut areas with a mouse pointer.

Hope you'll be able to shed some light on the issue, cause it looks like the one which is very hard to debug properly without a deep knowledge of the library sources.

The issue seems to be that with doughnut/pie charts the vScale is optional, per the Chartjs docs and if there's no scale, the origin is null

function getScaleOrigin(el, context) {
  var scale = context.chart.getDatasetMeta(context.datasetIndex).vScale;

  if (!scale) {
    return null;
  }
...

So when the x/y properties are grabbed off the null origin, explosion

function orient(point, origin) {
  var x0 = origin.x;
  var y0 = origin.y;
...
KELs7 commented

So what's the work around of vScale property for pie charts?

I am using chartjs in nodejs using chartjs-node-canvas to generate charts and facing same issue when trying to generate multiple charts.

First chart rendering perfectly. When I am trying to generate the second chart its throwing error var x0 = origin.x;

Same problem here with pie and doughnut charts.
"chart.js": "4.2.1",
"chartjs-plugin-datalabels": "2.2.0",
"react-chartjs-2": "5.2.0",
Any idea how to solve?


Edit:
The same code works on codepen, but not in my project, the origin is always null.

Same problem here when using Pie Chart:

TypeError: Cannot read properties of null (reading 'x')
  at orient(webpack-internal:///../../../../node_modules/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js:121:19)
  at Object.fallback(webpack-internal:///../../../../node_modules/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js:345:13)
  at coordinates(webpack-internal:///../../../../node_modules/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js:841:21)
  at Object.draw(webpack-internal:///../../../../node_modules/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js:1012:18)
  at Object.afterDatasetsDraw(webpack-internal:///../../../../node_modules/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js:1307:12)
  at callback(webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.mjs:172:15)
  at PluginService._notify(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:5037:80)
  at PluginService.notify(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:5024:25)
  at Chart.notifyPlugins(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:6173:26)
  at Chart._drawDatasets(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:5920:10)
  at Chart.draw(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:5891:10)
  at eval(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:113:15)
  at Map.forEach(<anonymous>)
  at Animator._update(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:91:18)
  at eval(webpack-internal:///./node_modules/chart.js/dist/chart.mjs:82:12)

Any solution?

Hello, I'm having the same issue:

TypeError: Cannot read properties of null (reading 'x')
      at orient (H:\GUI\New Devs\chatbot-bolt\node_modules\chartjs-plugin-datalabels\dist\chartjs-plugin-datalabels.js:121:19)
      at Object.fallback [as positioner] (H:\GUI\New Devs\chatbot-bolt\node_modules\chartjs-plugin-datalabels\dist\chartjs-plugin-datalabels.js:345:13)
      at coordinates (H:\GUI\New Devs\chatbot-bolt\node_modules\chartjs-plugin-datalabels\dist\chartjs-plugin-datalabels.js:841:21)
      at Object.draw (H:\GUI\New Devs\chatbot-bolt\node_modules\chartjs-plugin-datalabels\dist\chartjs-plugin-datalabels.js:1012:18)
      at Object.afterDatasetsDraw (H:\GUI\New Devs\chatbot-bolt\node_modules\chartjs-plugin-datalabels\dist\chartjs-plugin-datalabels.js:1305:12)
      at callback (file:///H:/GUI/New%20Devs/chatbot-bolt/node_modules/chart.js/dist/chunks/helpers.segment.js:79:19)
      at PluginService._notify (file:///H:/GUI/New%20Devs/chatbot-bolt/node_modules/chart.js/dist/chart.js:5063:17)
      at PluginService.notify (file:///H:/GUI/New%20Devs/chatbot-bolt/node_modules/chart.js/dist/chart.js:5046:29)
      at Chart.notifyPlugins (file:///H:/GUI/New%20Devs/chatbot-bolt/node_modules/chart.js/dist/chart.js:6301:30)
      at Chart._drawDatasets (file:///H:/GUI/New%20Devs/chatbot-bolt/node_modules/chart.js/dist/chart.js:6044:14)

This only happens to me when using the ES2015 syntax (import ChartDataLabels from 'chartjs-plugin-datalabels';).
With CommonJS syntax (const { ChartDataLabels } = require('chartjs-plugin-datalabels');) seems to work properly...

Versions installed:
npm list chart.js chartjs-plugin-datalabels
+-- chart.js@4.2.1
+-- chartjs-adapter-date-fns@3.0.0
| -- chart.js@4.2.1 deduped +-- chartjs-adapter-moment@1.0.1 | -- chart.js@4.2.1 deduped
-- chartjs-plugin-datalabels@2.2.0 -- chart.js@4.2.1 deduped

any solution, guys. Don't believe that do a downgrade is the way.

The problem occurs at the getPositioner function.

function getPositioner(el) {
    if (el instanceof chart_js.ArcElement) {
      return positioners.arc;
    }
    if (el instanceof chart_js.PointElement) {
      return positioners.point;
    }
    if (el instanceof chart_js.BarElement) {
      return positioners.bar;
    }
    return positioners.fallback;
  }

In this function when using Pie or Doughnut charts at the first if should return but it happens that the condition el instanceof chart_js.ArcElement isn't evaluated to true, because chart_js (that is require(chart.js)) is not equal to the chart.js which calling this plugin.

As a workaround I rewrite that function as below and it works fine.

function getPositioner(el) {
    if (el.constructor.name === 'ArcElement') {
      return positioners.arc;
    }
    if (el.constructor.name === 'PointElement') {
      return positioners.point;
    }
    if (el.constructor.name === 'BarElement') {
      return positioners.bar;
    }
    return positioners.fallback;
  }

The problem occurs at the getPositioner function.

function getPositioner(el) {
    if (el instanceof chart_js.ArcElement) {
      return positioners.arc;
    }
    if (el instanceof chart_js.PointElement) {
      return positioners.point;
    }
    if (el instanceof chart_js.BarElement) {
      return positioners.bar;
    }
    return positioners.fallback;
  }

In this function when using Pie or Doughnut charts at the first if should return but it happens that the condition el instanceof chart_js.ArcElement isn't evaluated to true, because chart_js (that is require(chart.js)) is not equal to the chart.js which calling this plugin.

As a workaround I rewrite that function as below and it works fine.

function getPositioner(el) {
    if (el.constructor.name === 'ArcElement') {
      return positioners.arc;
    }
    if (el.constructor.name === 'PointElement') {
      return positioners.point;
    }
    if (el.constructor.name === 'BarElement') {
      return positioners.bar;
    }
    return positioners.fallback;
  }

I can issue a PR for this, this is the fix

When will the new release be on npmjs. Or is there another way to get this fixed version?

I was going to post an issue I am having using chartjs-plugin-datalabels with an ESM project in node. It works fine as a CommonJS module but changing the syntax to ESM standard and I get the same issue in getPositioner with the "instanceof" failing. Patched the module as noted above by @libnine and it all works fine now. Definitely like this patch. It also works with the CommonJS code as well.