Skip to content

Commit

Permalink
fix(legacycharts): fix update for multiple reactive charts in one page (
Browse files Browse the repository at this point in the history
#818)

Fix bug updating multiple reactive charts on one page, except when using the
chartjs-plugin-annotation and Vue 2 simultaneously.
  • Loading branch information
thabarbados committed Apr 21, 2022
1 parent 51170b5 commit 45cb362
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
68 changes: 50 additions & 18 deletions legacy/src/Charts.js
Expand Up @@ -22,6 +22,8 @@ import {
ChartEmits
} from '../../src/utils'

const ANNOTATION_PLUGIN_KEY = 'annotation'

export function generateChart(chartId, chartType, chartController) {
let _chartRef = null

Expand Down Expand Up @@ -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)
},
Expand All @@ -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)
}

Expand All @@ -95,55 +114,68 @@ 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)
}

chartCreate(this.renderChart, this.chartData, this.chartOptions)
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)
}
},
Expand Down
4 changes: 4 additions & 0 deletions website/src/guide/index.md
Expand Up @@ -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
Expand Down

0 comments on commit 45cb362

Please sign in to comment.