mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-06 12:19:08 +02:00
Provide method to lookup a chart from a canvas (#7843)
* Provide method to lookup a chart from a canvas * Throw an error during construction if a canvas is in use * Migration docs for new constructor behaviour
This commit is contained in:
parent
df0b79b9cc
commit
8438da9e84
@ -204,3 +204,11 @@ Sets the visibility for the given dataset to true. Updates the chart and animate
|
||||
```javascript
|
||||
chart.show(1); // shows dataset at index 1 and does 'show' animation.
|
||||
```
|
||||
|
||||
## Static: getChart(key)
|
||||
|
||||
Finds the chart instance from the given key. If the key is a `string`, it is interpreted as the ID of the Canvas node for the Chart. The key can also be a `CanvasRenderingContext2D` or an `HTMLDOMElement`. This will return `undefined` if no Chart is found. To be found, the chart must have previously been created.
|
||||
|
||||
```javascript
|
||||
const chart = Chart.getChart("canvas-id")
|
||||
```
|
@ -21,6 +21,7 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released
|
||||
* Distributed files are now in lower case. For example: `dist/chart.js`.
|
||||
* Chart.js is no longer providing the `Chart.bundle.js` and `Chart.bundle.min.js`. Please see the [installation](installation.md) and [integration](integration.md) docs for details on the recommended way to setup Chart.js if you were using these builds.
|
||||
* `moment` is no longer specified as an npm dependency. If you are using the `time` or `timeseries` scales, you must include one of [the available adapters](https://github.com/chartjs/awesome#adapters) and corresponding date library. You no longer need to exclude moment from your build.
|
||||
* The `Chart` constructor will throw an error if the canvas/context provided is already in use
|
||||
* Chart.js 3 is tree-shakeable. So if you are using it as an `npm` module in a project, you need to import and register the controllers, elements, scales and plugins you want to use. You will not have to call `register` if importing Chart.js via a `script` tag, but will not get the tree shaking benefits in this case. Here is an example of registering components:
|
||||
|
||||
```javascript
|
||||
|
@ -222,6 +222,14 @@ class Chart {
|
||||
|
||||
config = initConfig(config);
|
||||
const initialCanvas = getCanvas(item);
|
||||
const existingChart = Chart.getChart(initialCanvas);
|
||||
if (existingChart) {
|
||||
throw new Error(
|
||||
'Canvas is already in use. Chart with ID \'' + existingChart.id + '\'' +
|
||||
' must be destroyed before the canvas can be reused.'
|
||||
);
|
||||
}
|
||||
|
||||
this.platform = me._initializePlatform(initialCanvas, config);
|
||||
|
||||
const context = me.platform.acquireContext(initialCanvas, config);
|
||||
@ -1155,6 +1163,11 @@ Chart.instances = {};
|
||||
Chart.registry = registry;
|
||||
Chart.version = version;
|
||||
|
||||
Chart.getChart = (key) => {
|
||||
const canvas = getCanvas(key);
|
||||
return Object.values(Chart.instances).filter((c) => c.canvas === canvas).pop();
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
const invalidatePlugins = () => each(Chart.instances, (chart) => chart._plugins.invalidate());
|
||||
|
||||
|
@ -10,6 +10,33 @@ describe('Chart', function() {
|
||||
expect(chart instanceof Chart).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should throw an error if the canvas is already in use', function() {
|
||||
var config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2, 3, 4]
|
||||
}],
|
||||
labels: ['A', 'B', 'C', 'D']
|
||||
}
|
||||
};
|
||||
var chart = acquireChart(config);
|
||||
var canvas = chart.canvas;
|
||||
|
||||
function createChart() {
|
||||
return new Chart(canvas, config);
|
||||
}
|
||||
|
||||
expect(createChart).toThrow(new Error(
|
||||
'Canvas is already in use. ' +
|
||||
'Chart with ID \'' + chart.id + '\'' +
|
||||
' must be destroyed before the canvas can be reused.'
|
||||
));
|
||||
|
||||
chart.destroy();
|
||||
expect(createChart).not.toThrow();
|
||||
});
|
||||
|
||||
describe('config initialization', function() {
|
||||
it('should create missing config.data properties', function() {
|
||||
var chart = acquireChart({});
|
||||
@ -1440,4 +1467,48 @@ describe('Chart', function() {
|
||||
expect(chart.getDataVisibility(1)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getChart', function() {
|
||||
it('should get the chart from the canvas ID', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'pie',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2, 3]
|
||||
}]
|
||||
}
|
||||
});
|
||||
chart.canvas.id = 'myID';
|
||||
|
||||
expect(Chart.getChart('myID')).toBe(chart);
|
||||
});
|
||||
|
||||
it('should get the chart from an HTMLCanvasElement', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'pie',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2, 3]
|
||||
}]
|
||||
}
|
||||
});
|
||||
expect(Chart.getChart(chart.canvas)).toBe(chart);
|
||||
});
|
||||
|
||||
it('should get the chart from an CanvasRenderingContext2D', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'pie',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [1, 2, 3]
|
||||
}]
|
||||
}
|
||||
});
|
||||
expect(Chart.getChart(chart.ctx)).toBe(chart);
|
||||
});
|
||||
|
||||
it('should return undefined when a chart is not found or bad data is provided', function() {
|
||||
expect(Chart.getChart(1)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
1
types/core/index.d.ts
vendored
1
types/core/index.d.ts
vendored
@ -302,6 +302,7 @@ export declare class Chart<
|
||||
static readonly version: string;
|
||||
static readonly instances: { [key: string]: Chart };
|
||||
static readonly registry: Registry;
|
||||
static getChart(key: string | CanvasRenderingContext2D | HTMLCanvasElement) : Chart | undefined;
|
||||
static register(...items: IChartComponentLike[]): void;
|
||||
static unregister(...items: IChartComponentLike[]): void;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user