From 45cb36271f629a3df3d0a078ddae037da813c1aa Mon Sep 17 00:00:00 2001 From: Slava Terekhov Date: Thu, 21 Apr 2022 15:18:04 +0400 Subject: [PATCH] fix(legacycharts): fix update for multiple reactive charts in one page (#818) Fix bug updating multiple reactive charts on one page, except when using the chartjs-plugin-annotation and Vue 2 simultaneously. --- legacy/src/Charts.js | 68 ++++++++++++++++++++++++++++---------- website/src/guide/index.md | 4 +++ 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/legacy/src/Charts.js b/legacy/src/Charts.js index b7feb1b0..c24fd296 100644 --- a/legacy/src/Charts.js +++ b/legacy/src/Charts.js @@ -22,6 +22,8 @@ import { ChartEmits } from '../../src/utils' +const ANNOTATION_PLUGIN_KEY = 'annotation' + export function generateChart(chartId, chartType, chartController) { let _chartRef = null @@ -64,6 +66,21 @@ export function generateChart(chartId, chartType, chartController) { default: () => [] } }, + data() { + return { + _chart: null + } + }, + computed: { + hasAnnotationPlugin() { + return ( + Object.keys(this.chartOptions).length > 0 && + 'plugins' in this.chartOptions && + Object.keys(this.chartOptions.plugins).length > 0 && + ANNOTATION_PLUGIN_KEY in this.chartOptions.plugins + ) + } + }, created() { ChartJS.register(chartController) }, @@ -82,8 +99,10 @@ export function generateChart(chartId, chartType, chartController) { }, methods: { renderChart(data, options) { - if (_chartRef?.current !== null) { - chartDestroy(_chartRef.current) + const currentChart = this.getCurrentChart() + + if (currentChart !== null) { + chartDestroy(currentChart) this.$emit(ChartEmits.ChartDestroyed) } @@ -95,35 +114,38 @@ export function generateChart(chartId, chartType, chartController) { const canvasEl2DContext = this.$refs.canvas.getContext('2d') if (canvasEl2DContext !== null) { - _chartRef.current = new ChartJS(canvasEl2DContext, { - type: chartType, - data: chartData, - options, - plugins: this.plugins - }) + this.setCurrentChart( + new ChartJS(canvasEl2DContext, { + type: chartType, + data: chartData, + options, + plugins: this.plugins + }) + ) } } }, chartDataHandler(newValue, oldValue) { const newData = { ...newValue } const oldData = { ...oldValue } + const currentChart = this.getCurrentChart() if (Object.keys(oldData).length > 0) { const isEqualLabelsAndDatasetsLength = compareData(newData, oldData) - if (isEqualLabelsAndDatasetsLength && _chartRef?.current !== null) { - setChartDatasets(_chartRef.current.data, newData, this.datasetIdKey) + if (isEqualLabelsAndDatasetsLength && currentChart !== null) { + setChartDatasets(currentChart.data, newData, this.datasetIdKey) if (newData.labels !== undefined) { - setChartLabels(_chartRef.current, newData.labels) + setChartLabels(currentChart, newData.labels) this.$emit(ChartEmits.LabelsUpdated) } - chartUpdate(_chartRef.current) + chartUpdate(currentChart) this.$emit(ChartEmits.ChartUpdated) } else { - if (_chartRef?.current !== null) { - chartDestroy(_chartRef.current) + if (currentChart !== null) { + chartDestroy(currentChart) this.$emit(ChartEmits.ChartDestroyed) } @@ -131,19 +153,29 @@ export function generateChart(chartId, chartType, chartController) { this.$emit(ChartEmits.ChartRendered) } } else { - if (_chartRef?.current !== null) { - chartDestroy(_chartRef.current) + if (currentChart !== null) { + chartDestroy(currentChart) this.$emit(ChartEmits.ChartDestroyed) } chartCreate(this.renderChart, this.chartData, this.chartOptions) this.$emit(ChartEmits.ChartRendered) } + }, + getCurrentChart() { + return this.hasAnnotationPlugin ? _chartRef.current : this.$data._chart + }, + setCurrentChart(chart) { + this.hasAnnotationPlugin + ? (_chartRef.current = chart) + : (this.$data._chart = chart) } }, beforeDestroy() { - if (_chartRef?.current !== null) { - chartDestroy(_chartRef.current) + const currentChart = this.getCurrentChart() + + if (currentChart !== null) { + chartDestroy(currentChart) this.$emit(ChartEmits.ChartDestroyed) } }, diff --git a/website/src/guide/index.md b/website/src/guide/index.md index 6156bc1f..06a57d62 100644 --- a/website/src/guide/index.md +++ b/website/src/guide/index.md @@ -243,6 +243,10 @@ Charts will emit events if the data changes. You can listen to them in the chart - `chart:updated` - if the update handler performs an update instead of a re-render - `labels:updated` - if new labels were set +### chartjs-plugin-annotation + +When using [chartjs-plugin-annotation](https://www.chartjs.org/chartjs-plugin-annotation/latest/) and **Vue 2** simultaneously, you will not be able to place multiple reactive charts on one page. + ## Examples ### Chart with props