Chart.js: [FEATURE] Charts as modules

Created on 4 Jul 2017  ·  10Comments  ·  Source: chartjs/Chart.js

I think that a modern chart library should work in the following way:

import PieChart from 'chart/pie';
new PieChart(/necessary stuff/);

Prós:

  • The page only requests js for a specific chart.
  • Better use of single responsibility pattern.
  • Better IntelliSense??
  • ...

What you think guys?

Thanks.

breaking change enhancement

Most helpful comment

I believe the API doesn't need to change in order to have partial imports.

For example, RxJS have more then one usage approach for it, one of then is the follow:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';

Observable.of(1,2,3).map(x => x + '!!!'); // etc

Chart.js could use a similar approach like:

import { Chart } from 'Chart.js/Chart';
import 'Chart.js/add/pie';

var mychart = new Chart(ctx, {
  type: 'pie'
});

All 10 comments

Definitely a good enhancement to consider that makes some things simpler. Would definitely be a breaking change though

@simonbrunel said in https://github.com/chartjs/Chart.js/issues/4303 that he was going to cleanup the modules and switch them to ES6. Would we want to implement something like this as part of that change?

@etimberg, not necessary a breaking change, this can be completely optional, as it is now a days with https://github.com/ReactiveX/rxjs

The breaking change is that right now we have no concept of a different class for each chart type. I'm wary of breaking things with a change that introduces that

For example, would these return the same classes?

var mychart = new Chart(ctx, {
  type: 'pie'
});
var mychart = new PieChart(ctx, {});

Another potential question: how would we handle mixed chart types?

I believe the API doesn't need to change in order to have partial imports.

For example, RxJS have more then one usage approach for it, one of then is the follow:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';

Observable.of(1,2,3).map(x => x + '!!!'); // etc

Chart.js could use a similar approach like:

import { Chart } from 'Chart.js/Chart';
import 'Chart.js/add/pie';

var mychart = new Chart(ctx, {
  type: 'pie'
});

@willgm that style of imports would definitely work well with our code. We could even do the same for importing new scale types (log, time, etc).

I found a workaround for this issue. The code is on Typescript:

import * as core from 'chart.js/src/core/core.js';
import * as helpers from 'chart.js/src/core/core.helpers';
import * as platform from 'chart.js/src/platforms/platform.js';
import * as canvasHelpers from 'chart.js/src/core/core.canvasHelpers';
import * as element from 'chart.js/src/core/core.element';
import * as plugin from 'chart.js/src/core/core.plugin';
import * as animation from 'chart.js/src/core/core.animation';
import * as controller from 'chart.js/src/core/core.controller';
import * as datasetController from 'chart.js/src/core/core.datasetController';
import * as layoutService from 'chart.js/src/core/core.layoutService';
import * as scaleService from 'chart.js/src/core/core.scaleService';
import * as ticks from 'chart.js/src/core/core.ticks';
import * as scale from 'chart.js/src/core/core.scale';
import * as interaction from 'chart.js/src/core/core.interaction';
import * as tooltip from 'chart.js/src/core/core.tooltip';
import * as arc from 'chart.js/src/elements/element.arc';
import * as line from 'chart.js/src/elements/element.line';
import * as linearbase from 'chart.js/src/scales/scale.linearbase';
import * as category from 'chart.js/src/scales/scale.category';
import * as linear from 'chart.js/src/scales/scale.linear';
import * as doughnut from 'chart.js/src/controllers/controller.doughnut';
import * as Doughnut from 'chart.js/src/charts/Chart.Doughnut';

const Chart = core();
helpers(Chart);
platform(Chart);
canvasHelpers(Chart);
element(Chart);
plugin(Chart);
animation(Chart);
controller(Chart);
datasetController(Chart);
layoutService(Chart);
scaleService(Chart);
ticks(Chart);
scale(Chart);
interaction(Chart);
tooltip(Chart);

arc(Chart);
line(Chart);
linearbase(Chart);
category(Chart);
linear(Chart);
doughnut(Chart);
Doughnut(Chart);

Then:

const doughnutChart = new Chart(ctx, {
      type: 'doughnut',
      data: data,
      options: options
});

ChartJS is on package.json
The current setup only uses Doughnut chart

When will 3.0 arrive? Any beta available?

BTW: Here is a related closed issue: https://github.com/chartjs/Chart.js/issues/5179

I placed a comment in https://github.com/chartjs/Chart.js/issues/5179#issuecomment-417889559 which shows how to build a module from chart.js via a rollup with chart.js as a commonjs module. Let me know if it works for you.

Bottom line: with a simple rollup.config and two plugins, chart.js seems to be converted to an esm.

I'm closing this in favor of https://github.com/chartjs/Chart.js/issues/7371 which has much more information on the current state of things and how it could be implemented. We'd love volunteers to help with it. As much as I'd love to see it, I'm not sure it'll make it into 3.0 without someone stepping up to implement it

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JAIOMP picture JAIOMP  ·  3Comments

lizbanach picture lizbanach  ·  3Comments

akashrajkn picture akashrajkn  ·  3Comments

gabrieldesouza picture gabrieldesouza  ·  3Comments

longboy picture longboy  ·  3Comments