Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading global plugin seems not to work #8

Closed
AndreasZaschka opened this issue Apr 2, 2019 · 3 comments
Closed

Loading global plugin seems not to work #8

AndreasZaschka opened this issue Apr 2, 2019 · 3 comments

Comments

@AndreasZaschka
Copy link

What is the best way to load a global plugin ?

In this case chartjs-plugin-datalabels (https://chartjs-plugin-datalabels.netlify.com/) and chartjs-plugin-annotation (https://github.com/chartjs/chartjs-plugin-annotation)

Trying to require it seems not to load the module as an global plugin or cant be registered.

package.json

"dependencies": {
        "chartjs-node-canvas": "2.x.x",
        "chart.js": "2.7.x",
        "chartjs-plugin-datalabels": "0.x.x",
        "chartjs-plugin-annotation": "0.x.x"
    }

index.js

const { CanvasRenderService } = require('chartjs-node-canvas');
require('chartjs-plugin-datalabels');
require('chartjs-plugin-annotation');

module.exports = async function (context, req) {
    const width = 400; //px
    const height = 400; //px
    const configuration = {
        ... // See https://www.chartjs.org/docs/latest/configuration
    };
    const canvasRenderService = new CanvasRenderService(width, height, (ChartJS) => {
        // See https://www.chartjs.org/docs/latest/configuration/#global-configuration
        ChartJS.defaults.global.responsive = true;
    });
    const image = await canvasRenderService.renderToBuffer(configuration);
    const dataUrl = await canvasRenderService.renderToDataURL(configuration); // image/png
    const stream = canvasRenderService.renderToStream(configuration);
}
@SeanSobey
Copy link
Owner

SeanSobey commented Apr 3, 2019

So the Chart JS plugin and specifically global plugin registration API is fairly new and unfortunately, a lot of plugins still use the old method of expecting a global Chart variable or require ChartJS themselves. chartjs-plugin-annotation returns a plugin object which should just work as a global plugin, while chartjs-plugin-datalabels does a require itself. I see there are some plans to maybe update chartjs-plugin-datalabels.

So you will have to address and load each plugin based on how its implemented, for example chartjs-plugin-datalabels:

Firstly, it retrieves its own reference to chart.js:

module.exports = factory(require('chart.js'))

Then it registers itself:

// TODO Remove at version 1, we shouldn't automatically register plugins.
// https://github.com/chartjs/chartjs-plugin-datalabels/issues/42
Chart.plugins.register(plugin);

And finally returns itself:

return plugin;

I have updated the package to allow for your use case and added to the readme to include some details about loading plugins.

For your requirements:

const freshRequire = require('fresh-require');

const callback = (ChartJS) => {

	ChartJS.plugins.register(freshRequire('chartjs-plugin-annotation', require));
};
const chartJsFactory = () => {
	const chartJS = require('chart.js');
	require('chartjs-plugin-datalabels');
	delete require.cache[require.resolve('chart.js')];
	delete require.cache[require.resolve('chartjs-plugin-datalabels')];
	return chartJS;
};
const canvasRenderService = new CanvasRenderService(width, height, callback, undefined, chartJsFactory);

See the tests for more details where I have each plugin working.

@AndreasZaschka
Copy link
Author

nice, the solutions works perfect 👍

thanks for the super fast support

@tsormonteSP
Copy link

Hello,

I tried your solution i got this issue :

TypeError: meta.controller.updateIndex is not a function
    at Chart.buildOrUpdateControllers (C:\dev\workspace\sp-export\node_modules\chart.js\dist\Chart.js:9565:21)
    at Chart.update (C:\dev\workspace\sp-export\node_modules\chart.js\dist\Chart.js:9626:27)
    at Chart.construct (C:\dev\workspace\sp-export\node_modules\chart.js\dist\Chart.js:9357:6)
    at new Chart (C:\dev\workspace\sp-export\node_modules\chart.js\dist\Chart.js:9294:7)
    at CanvasRenderService.renderChart (C:\dev\workspace\sp-export\node_modules\chartjs-node-canvas\dist\index.js:151:16)
    at CanvasRenderService.renderToDataURL (C:\dev\workspace\sp-export\node_modules\chartjs-node-canvas\dist\index.js:35:28)
    at ChartPdfExporter.renderChart (C:\dev\workspace\sp-export\dist\core\modules\export\modules\pdf\modules\template\exporters\chart.pdf.exporter.js:26:40)
    at SummaryGovernanceChartExporter.generate (C:\dev\workspace\sp-export\dist\satellite\modules\summary\modules\governance\exporters\governance-chart.pdf.exporter.js:26:55)
    at SummaryPdfExporter.generate (C:\dev\workspace\sp-export\dist\satellite\modules\summary\exporters\pdf\summary.pdf.exporter.js:31:79)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)`

I'm using TypeScript on NestJS :

 "dependencies": {
        "@nestjs/common": "^7.0.0",
        "@nestjs/core": "^7.0.0",
        "@nestjs/platform-express": "^7.0.0",
        "chart.js": "^2.9.3",
        "chartjs-node-canvas": "^3.0.6",
        "chartjs-plugin-datalabels": "^0.7.0
}

Here is my tsconfig :

"compilerOptions": {
        "module": "commonjs",
        "declaration": true,
        "removeComments": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es2017",
}

Is it because of the way Typescript resolves modules ?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants