Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to redraw a chart? #10

Open
moonlik opened this issue Mar 28, 2017 · 21 comments
Open

How to redraw a chart? #10

moonlik opened this issue Mar 28, 2017 · 21 comments

Comments

@moonlik
Copy link

moonlik commented Mar 28, 2017

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
Copy link

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
Copy link

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

@RSamal
Copy link

RSamal commented Jun 2, 2017

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

@MysteryAngle
Copy link

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

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

@ereyes01
Copy link

@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
Copy link

ereyes01 commented Aug 11, 2017

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
Copy link

dominikarnoldi commented Aug 15, 2017

This looks like it is not working for me. I can wait for the next DOM update but the this.$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
Copy link

MysteryAngle commented Aug 15, 2017

@nanoupper hey. can you paste some code?

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

@dominikarnoldi
Copy link

@MysteryAngle comment edited

@MysteryAngle
Copy link

@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
Copy link

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

@MysteryAngle
Copy link

Updated:

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

this code will work fine when you update data.

@tonywangcn
Copy link

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

@MysteryAngle
Copy link

@tonywangcn what mean of the double click?

@tonywangcn
Copy link

      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
Copy link

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

@tonywangcn
Copy link

<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
Copy link

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

@tonywangcn
Copy link

tonywangcn commented Sep 10, 2017 via email

@MysteryAngle
Copy link

MysteryAngle commented Sep 10, 2017

我是这么做的,首先,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
Copy link

tonywangcn commented Sep 10, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants