vue-bulma / chartjs

Chartjs component is based on chart.js for Vue Bulma
MIT License
64 stars 24 forks source link

How to redraw a chart? #10

Open moonlik opened 7 years ago

moonlik commented 7 years ago

My piechart uses data from the AJAX request, so the data comes after the chart is drawn. How can I redraw the chart based on the new data or make my piechart redraw automatically?

chafreaky commented 7 years ago

Until a better solution is presented, I was able to do this by going through the component as such:

<chart ref="chart" ...></chart>

and then

if(this.$refs.chart) {
    this.$refs.chart.chart.update();
}
MajorAxe commented 7 years ago

If .update() doesn't help, try .resetChart()

RSamal commented 7 years ago

I tried to call .resetChart() but it says method not found

MysteryAngle commented 7 years ago

if(this.$refs.chart) { this.$refs.chart. resetChart(); }

it's should be work. note the resetChart method belong to the Vue component.

ereyes01 commented 7 years ago

@MysteryAngle - that still doesn't quite work for me. I have data that sometimes changes more than once asynchronously (using axios http client talking to an API backend). What I observe is that the charts sometimes lag behind 1 update. In the success callback, I had code like what you suggested, and I found that sometimes this.$refs.chart was null/false. It seems like the chart itself has some asynchronous state that we have to manipulate via promises or something?

PS I've verified via the Vue debugger that all my data / computed values were correct while the chart was showing the "previous update" / version of the data. Unfortunately I can't post my exact code here.

ereyes01 commented 7 years ago

Ah, reading this component's code was instructive...

The watchers for type and options only call resetChart() like this:

this.$nextTick(() => this.resetChart())

So the following seems to work for me now, no matter how many times I load new data asynchronously:

this.$nextTick(() => {
  if (this.$refs.chart) {
    this.$refs.chart.resetChart()
  }
})

So it looks like we need to wait for a DOM update before trying to redraw the charts, which sorta makes sense I guess.

EDIT: this all seems to suggest that chart.update() doesn't quite work in an async situation right?

dominikarnoldi commented 7 years ago

This looks like it is not working for me. I can wait for the next DOM update but thethis.$refs.chart still is null/undefined ? Any idea ? For your information i have a similiar case, working with an asynchrone methode which gives data on an eventbus. The data is taken from the bus and put into the data object of the component. Now i want to refresh the chart with the new data. Component 1:

promise.then(function (val) {
        var data = {
          names: Object.keys(val).map(f => val[f].name),
          shares: Object.keys(val).map(f => val[f].share)

        }
        eventbus.$emit('SharesChanged', data)
        vm.Memberlist = val
      })

Component 2:

mounted () {
      eventbus.$on('SharesChanged', (data) => {
        this.pieChartdata = data.shares
        this.labels = data.names
        console.log(this.chart)
        console.log(this.labels, this.pieChartdata)
        this.$nextTick(() => {
          console.log('next tick...')
          if (this.$refs.chart) {
            this.$refs.chart.resetChart()
          }
        })
      })
MysteryAngle commented 7 years ago

@nanoupper hey. can you paste some code?

<chart ref="chart" ...></chart> do u declare property ref set name chart?

dominikarnoldi commented 7 years ago

@MysteryAngle comment edited

MysteryAngle commented 7 years ago

@nanoupper yes. i can see that. but in template should like this: <chart ref="chart" ...></chart> do you declare the <chart> tag property ref set name to chart?

dominikarnoldi commented 7 years ago

image thought it was already there. @MysteryAngle sorry for stealing your time. Thanks a lot !!

MysteryAngle commented 7 years ago

Updated:

this.$nextTick(() => {
  if (this.$refs.chart) {
    this.$refs.chart.resetChart()
  }
})

this code will work fine when you update data.

tonywangcn commented 7 years ago

Seems that only double click could update the chart, how to fix it?

MysteryAngle commented 7 years ago

@tonywangcn what mean of the double click?

tonywangcn commented 7 years ago
      this.$nextTick(() => {
        if (this.$refs.chart) {
          console.log('tick tick ...')
          console.log(this.$refs.chart)
          this.$refs.chart.resetChart()
          console.log(this.$refs.chart)
        }
      })

With the first click, nothing happened with chart. Only updated after second click. But log prints in console each time.

MysteryAngle commented 7 years ago

OK,老王,我发现最近这个组建好像更新了一些东西,不过这句代码应该是没问题的,你可能需要检查一下数据。如果仍然有问题,咱们周一在看下。:)

tonywangcn commented 7 years ago

<chart ref="chart" ....... v-if="isloaded"> data () { isloaded: false }

methods: { do_something () { this.$http.get() this.isloaded = true this.$nextTick(() this.isloaded = false } }

虽然可以通过这种方式暂时解决,但又出现了其他报错:

[Vue warn]: Error in nextTick: "TypeError: Cannot set property '_chartjs' of null"

MysteryAngle commented 7 years ago

好像不能直接通过v-if来进行设定,生命周期或者上下文会存在一些问题。

tonywangcn commented 7 years ago

嗯,但除此之外,还没找到更好的解决方案。

On Sat, Sep 9, 2017 at 1:32 AM Alex notifications@github.com wrote:

好像不能直接通过v-if来进行设定,生命周期或者上下文会存在一些问题。

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/vue-bulma/chartjs/issues/10#issuecomment-328166558, or mute the thread https://github.com/notifications/unsubscribe-auth/AC6kD5ZkUUHcC3p8ZNlXKzSE_eKbvSbvks5sgXoXgaJpZM4Mrc-t .

--

Tony Wang

Warm Regards

MysteryAngle commented 7 years ago

我是这么做的,首先,chart的数据是由computed属性提供的,当我更新数据的时候,computed会重新计算,然后我在computed中调用了刷新的方法,如下:

computed: {
    ...

    seriesData () {
      let data = {
        labels: this.rep1Labels
      }
      data.datasets = this.series.map((e, i) => {
        return {
          data: e.points,
          label: e.label,
          borderColor: this.backgroundColor[i].replace(/1\)$/, '.5)'),
          pointBackgroundColor: this.backgroundColor[i],
          backgroundColor: this.backgroundColor[i].replace(/1\)$/, '.5)')
        }
      })
      if (this.$refs.chart) {
        this.$nextTick(() => {
          this.$refs.chart.resetChart()
        })
      }
      return data
    }
}

一开始$nextTick这个是在组件内部调用的,但后来发现他去除了这个,所以我不得不自己去加一个,不然的话会导致死循环。

tonywangcn commented 7 years ago

多谢,这种解决方法不错

On Sun, Sep 10, 2017 at 5:04 PM Alex notifications@github.com wrote:

我是这么做的,首先,chart的数据是由computed属性提供的,当我更新数据的时候,computed会重新计算,然后我在computed中调用了刷新的方法,如下:

computed: { ...

seriesData () {
  let data = {
    labels: this.rep1Labels
  }
  data.datasets = this.series.map((e, i) => {
    return {
      data: e.points,
      label: e.label,
      borderColor: this.backgroundColor[i].replace(/1\)$/, '.5)'),
      pointBackgroundColor: this.backgroundColor[i],
      backgroundColor: this.backgroundColor[i].replace(/1\)$/, '.5)')
    }
  })
  if (this.$refs.chart) {
    this.$nextTick(() => {
      this.$refs.chart.resetChart()
    })
  }
  return data
}

}

一开始nextTick这个是在组件内部调用的,但后来发现他去除了这个,所以我不得自己去加一个,不然的话会导致死循环。

You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/vue-bulma/chartjs/issues/10#issuecomment-328329525, or mute the thread https://github.com/notifications/unsubscribe-auth/AC6kD68Y6l9XgvWjHCoHjJ0XXEeCEVOmks5sg6YDgaJpZM4Mrc-t .

--

Tony Wang

Warm Regards