简体   繁体   中英

Highcharts in Vue.js component

I'm trying to create graphical components using Highcharts and Vue.js. I would like to pass the id attribute of the element to be used by Highcharts, but I can not get the attribute.

How can I set the id dynamically?

This is the HTML:

 <objective-chart :element="'brick-chart'"></objective-chart> 

And the javascript code:

 <template> <div id="{{element}}"></div> </template> <script> import Highcharts from 'highcharts'; export default{ props: ['element'], ready(){ $(function () { new Highcharts.Chart({ chart: { renderTo: this.element, type: 'bar', height: 200, margin: [0, 20, 0, 40] }, title: { text: null }, xAxis: { lineColor: null, labels: { rotation: -90 }, categories: [ 'Brick' ] }, yAxis: [{ min: 0, max:100, endOnTick: true, maxPadding: 0.02, gridLineColor: null, title: { text: null }, labels: { y: -50 }, }], legend: { shadow: false, verticalAlign: 'bottom' }, tooltip: { shared: true, followPointer: true }, plotOptions: { column: { grouping: true, shadow: false, borderWidth: 0 } }, credits: { enabled: false }, series: [{ name: 'Objetivo', color: 'rgba(224,224,224,1)', data: [100], pointPadding: 0.3, pointPlacement: -0.2 }, { name: 'Realizado', color: 'rgba(106,166,46,.9)', data: [76], pointPadding: 0.4, pointPlacement: 0.1 }, { type:'spline', name: 'Projeção', color: 'rgba(106,166,46,.9)', top: 10, pointPlacement: -0.05, data: [95], marker: { radius: 8, lineColor: '#666666', lineWidth: 1 } }] }); }); } } </script> 

vue.js 2.0 example (Vue start to use virtual dom):
1) npm install highcharts
2) var Highcharts = require('highcharts');
3) Highcharts.chart( this.$el , {...}) in "mounted" method because this.$el isn't available before "mounted"
4) the Instance of highcharts should be destroyed in "beforeDestroy" method.

 <template> <div><div> </template> <script> var Highcharts = require('highcharts'); export default { name : "Chart", props : { series : { type: Array, required: true } }, data : function() { return { target: undefined } }, mounted : function() { this.target = Highcharts.chart(this.$el, { title: { text: 'Monthly Average Temperature', x: -20 //center }, subtitle: { text: 'Source: WorldClimate.com', x: -20 }, xAxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] }, yAxis: { title: { text: 'Temperature (°C)' }, plotLines: [{ value: 0, width: 1, color: '#808080' }] }, tooltip: { valueSuffix: '°C' }, legend: { layout: 'vertical', align: 'right', verticalAlign: 'middle', borderWidth: 0 }, series: this.series }); }, beforeDestroy: function() { this.target.destroy(); }, } </script> 

And the parent component is:

 <template> <div id="app"> <h1>{{ msg }}</h1> <Chart :series = "initSeries"></Chart> </div> </template> <script> import Chart from './Chart.vue'; export default { name: 'app', components : {Chart}, data () { return { msg: 'Welcome to Your Vue.js App', } }, computed : { initSeries : function() { return [{ name: 'Tokyo', data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] }, { name: 'New York', data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5] }, { name: 'Berlin', data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0] }, { name: 'London', data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8] }]; } } } </script> 

Edit: Check out the Vue 2 example from @Tody.Lu which is a great solution

You need to use renderTo: "#" + this.element to get a properly formatted ID selector.

I believe you can also use renderTo: this.$el without having an ID at all.

Edit: I checked my Highcharts component and this is how I have it:

$(this.$el).highcharts(data);

No need for an ID this way.

If you're using a central data store like Vuex, you can include chart increment property that stores the number of charts created, and increments when there is a new one.

Then you'd set the ID using a computed property:

computed: {
  id () {
    return 'highchart-' + idvar
  }
}

You could just as easily keep it in a global variable, but that's a bad idea.

Another option (one I've used in the past) is to create a random string in your component. I've used the UUID generator found at this answer .

if I use UUID function UUID.generate() to return a random string:

data () {
  return {
    uid: UUID.generate()
  } 
}

then use the generated uid property in a computed property:

computed: {
  id () {
    return 'chart-' + this.uid
  }
}

Then you'd use {{ id }} in your VM.

Take care, in your template you have:

<template>
    <div><div>
</template>

You need to have:

<template>
    <div></div>
</template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM