How to dynamically add points to a bar/pie chart i

2019-07-14 02:58发布

问题:

I would like to bootstrap a Highcharts bar chart and later add some points to it (in a Vue container). The documentation mentions addPoint(), setData() and update() as means to achieve that, but none of the incantations I tried worked.

The demo for a post-updated pie chart makes it simple to use setData():

var chart = Highcharts.chart('container', {
  chart: {
    type: 'pie'
  },

  series: [{
    data: []
  }]
});


// the button action
$('#button').click(function() {
  chart.series[0].setData([129.2, 144.0, 176.0]);
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>

<div id="container" style="height: 400px"></div>
<button id="button" class="autocompare">Set new data</button>

I tried to replicate this in a Vue context but the chart is never updated

var chart = Highcharts.chart('container', {
  chart: {
    type: 'pie'
  },

  series: [{
    data: []
  }]
});


new Vue({
  el: "#app",
  data: {},
  mounted() {
    chart.series[0].setData([129.2, 144.0, 176.0]);
    chart.redraw()
  }
})
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <div id="container" style="height: 400px"></div>
</div>

回答1:

It appears that calling Highlights.chart queries the DOM immediately, so doing so before Vue's mounted callback is called will fail, since the element doesn't exist yet. That, or it gets overwritten by Vue's rendering. Instead, you'll want to call that function after Vue has mounted.

As a bonus, here's a little demo (that I had way too much fun with) which shows how the library can play along with Vue. It uses a watcher to redraw the chart when the corresponding property is changed.

function createChart() {
  return Highcharts.chart('container', {
    chart: {
      type: 'pie'
    },
    series: [{
      data: []
    }]
  })
}


new Vue({
  el: "#app",
  data: {
    chartData: []
  },
  mounted() {
    this.chart = createChart()
    this.setData([100, 100, 100])
  },
  methods: {
    setData(data){
      this.chartData = data
    }
  },
  watch: {
    chartData(data) {
      this.chart.series[0].setData(data)
      this.chart.redraw()
    }
  }
})
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <button @click="setData([129.2, 144.0, 176.0])">Show First Dataset</button>
  <button @click="setData([180, 100.0, 20.0])">Show Second Dataset</button>
  <div id="container" style="height: 400px"></div>
</div>