chartjs / chartjs-plugin-datalabels

Chart.js plugin to display labels on data elements
https://chartjs-plugin-datalabels.netlify.app
MIT License
863 stars 459 forks source link

Integrate the plugin with requirejs from the chartjs and chartjs-datalabels files #303

Open Funky89 opened 2 years ago

Funky89 commented 2 years ago

Hello everyone,

I want to integrate the datalabels plugin with my requirejs But I am having problems when defining datalabels in my js file, here is the error message.

Previously I don't use the cdns but I downloaded the Chart.js v3.6.2 and chartjs-plugin-datalabels v2.0.0 files

404 error: https://192.168.1.70/script/chart.js/helpers.js

Uncaught Error: Script error for "../script/chart.js/helpers", needed by: datalabels

Can you tell me where I am wrong and how to get the plugin to work properly without using cdn?

Best regards

Here is my code:

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script>
<canvas id="myChart" width="850" height="520"></canvas>
<script>

requirejs.config({
    paths: {
        chart: "../script/chart",
    datalabels: "../script/chartjs-plugin-datalabels",
    },  
    map: {
        datalabels: {
          "chart.js": "../script/chart.js"
        }
    },
    waitSeconds: 30
});

require(["chart", "datalabels"], function(chart, datalabels) {
  var ctx = document.getElementById('myChart');
  //console.log(ChartDataLabels)
  //Chart.register(ChartDataLabels); // first way of registering the plugin, registers them for all your charts

  var myChart = new Chart(ctx, {
    type: 'doughnut',
    //plugins: [ChartDataLabels], // second way of registering plugin, register plugin for only this chart
    data: {
      labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
      datasets: [{
        data: [12, 19, 3, 5, 2, 3],
        label: 'Advisor Closed MTD',
        backgroundColor: 'rgb(192,111,94)',
        barThickness: 25,
        datalabels: {
          color: '#FFCE56'
        }

      }],
    },
    options: {
      responsive: false,
      plugins: {
        datalabels: {
          formatter: function(value, context) {
          return context.chart.data.labels[context.dataIndex];
        },
          labels: {
            value: {
              color: 'blue'
            }
          }

        }
      }
    }
  });
});

</script>
LeeLenaleee commented 2 years ago

Can you try if it works if you nest the requires as shown in this example so you are sure chart.js is fully loaded when the datalabels tries to acces it

https://www.chartjs.org/docs/master/getting-started/integration.html#require-js

Funky89 commented 2 years ago

@LeeLenaleee Hello and thank you, I just tested for nesting and I have the same problem Cannot load helper function

It still tries to read the file: https://192.168.1.70/script/chart.js/helpers.js

Except that in the datalabel file we use factory (require ('chart.js / helpers'), require ('chart.js'))

On the other hand, no problem if I do not use requireJS but simply the cdns

Funky89 commented 2 years ago

Hello, I am coming back because here is the new code which "works" but does not suit me.

require.config({
  paths: {
    chart: "../script/chart",
    datalabels: "../script/chartjs-plugin-datalabels"
  },
  shim: {
    chartjs: {
      exports: "C"
    },
    datalabels: {
      exports: "C",
      deps: ["chart"]
    }
  },
  map: {
    datalabels: {
      "chart.js": "chart",
      "chart.js/helpers": "chart"
    }
  }
});

The problem comes from the map part, during the chart.js/helpers

Do you have a solution to indicate in the map to use chart.js/helper?

If I use my code I have to modify the code of the "chartjs-plugin-datalabels" file

Here is the line that I add:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('chart.js/helpers'), require('chart.js')) :
  typeof define === 'function' && define.amd ? define(['chart.js/helpers', 'chart.js'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ChartDataLabels = factory(global.Chart.helpers, global.Chart));
  }(this, (function (helpers, chart_js) { 'use strict';
////////////////////////////////////////////////////
  helpers = helpers.helpers; // This line
///////////////////////////////////////////////////
  var devicePixelRatio = (function() {
    if (typeof window !== 'undefined') {
      if (window.devicePixelRatio) {
        return window.devicePixelRatio;
      }

      // devicePixelRatio is undefined on IE10
      // https://stackoverflow.com/a/20204180/8837887
      // https://github.com/chartjs/chartjs-plugin-datalabels/issues/85
      var screen = window.screen;
      if (screen) {
        return (screen.deviceXDPI || 1) / (screen.logicalXDPI || 1);
      }
    }

    return 1;
  }());

Best regards

LeeLenaleee commented 2 years ago

Might needs to be the same as in the rollup config: https://github.com/chartjs/chartjs-plugin-datalabels/blob/master/rollup.config.js#L24

So instead of:

 map: {
    datalabels: {
      "chart.js": "chart",
      "chart.js/helpers": "chart"
    }
  }

You get:

 map: {
    datalabels: {
      "chart.js": "chart", // Not sure if it also needs to be capatalized C as in the rollup config
      "chart.js/helpers": "chart.helpers" // Not sure if it also needs to be capatalized C as in the rollup config
    }
  }
Funky89 commented 2 years ago

@LeeLenaleee Hello, I had already tried and I get the same error mentioned above. Impossible to do the relation directly from the require, I don't know why

kevinamixys commented 1 year ago

did you find any solution ? I got the same problem with another plugin (annotation) @LeeLenaleee