问题
I have a chart which axis contents and data will change with time. This happens in a Vue framework.
My idea was to use setData()
and setCategories()
to give the chart pointers to data which will be dynamic. This does not work: when data is updated, the chart is not.
The example is in Codepen.io and reproduced below for reference. Please note that this hangs my browser (but the codepen version is OK)
new Vue({
el: "#app",
data: {
config: {
chart: {
type: 'heatmap'
},
series: [{}]
},
src: ['a', 'b'],
dst: ['x', 'y'],
data: [[0, 0, 1], [0, 1, 2], [1, 0, 3], [1, 1, 4]],
chart: undefined
},
mounted() {
this.chart = Highcharts.chart('container', this.config)
console.log(this.chart)
// the content of the axis and the data will be dynamic
this.chart.series[0].setData(this.data, true)
this.chart.xAxis[0].setCategories(this.src, true)
this.chart.yAxis[0].setCategories(this.dst, true)
// simulation of some data changing after some time
setTimeout(() => {
this.data = [[0, 0, 10], [0, 1, 20], [1, 0, 30], [1, 1, 40]]
// console.log('updated')
}, 3000)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.6/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<div id="app">
<div id="container">
</div>
</div>
回答1:
To allow the chart to automatically update, you need to watch the vue variables using a watcher or by using them in the view.
I'm using the following steps:
Since Highcharts requires a real element on the page before it works, we cannot use them directly inside the view, and we need to use a watcher on the fields that can change.
We first extract our chart render code into a seperate function, this allows us to call the method from multiple places.
Then we add watchers for the variables our chart requires, and inside those watchers, we call our render function.
Finally, we render our chart inside the mounted method.
From this point, we can see that the library we use, Highcharts also supports updating the data dynamically on changes, we can use this in our advantage to prevent re rendering the full element, and save some CPU cycles here.
new Vue({
el: "#app",
data: {
chart: undefined,
config: {
chart: {
type: 'heatmap'
},
series: [{}]
},
src: ['a', 'b'],
dst: ['x', 'y'],
data: [[0, 0, 1], [0, 1, 2], [1, 0, 3], [1, 1, 4]]
},
mounted() {
this.render();
// simulation of some data changing after some time
setTimeout(() => {
this.data = [[0, 0, 10], [0, 1, 20], [1, 0, 30], [1, 1, 40]]
console.log('updated')
}, 3000)
},
watch: {
data() {
this.chart.series[0].setData(this.data, true)
},
config() {
this.render();
},
src() {
this.chart.xAxis[0].setCategories(this.src, true)
},
dst() {
this.chart.yAxis[0].setCategories(this.dst, true)
},
},
methods: {
render() {
this.chart = Highcharts.chart('container', this.config)
// the content of the axis and the data will be dynamic
this.chart.series[0].setData(this.data, true)
this.chart.xAxis[0].setCategories(this.src, true)
this.chart.yAxis[0].setCategories(this.dst, true)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.6/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<div id="app">
<div id="container">
</div>
</div>
来源:https://stackoverflow.com/questions/48707827/how-to-use-vue-bound-data-in-highcharts