替换,更新chartData时,vue.js vue-chartjs图表未更新 [英] vue.js vue-chartjs chart not updating when chartData replaced, updated etc

查看:196
本文介绍了替换,更新chartData时,vue.js vue-chartjs图表未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用vue-chartjs进行验证.我已经关注了所有相关文档,以在chartData属性更新时重新呈现图表.只有在调整浏览器窗口的大小之后,我的图表才会更新.

I am attempting to make a vue with vue-chartjs. I have followed all the associated documentation with regards to re-rendering the chart when the chartData prop is updated. My chart will only update after i resize the browser window.

我的parenttestchart.vue文件:

my parenttestchart.vue file:

<template>
    <div>
        <h1>Chart datacollection update test</h1>

        <p>This component demonstrates fetching data from the server.</p>

        <p v-if="!datacollection"><em>Loading...</em></p>

        <b-form-select 
                    v-model="testthingSelect.selected"
                    text="Select testthing"
                    variant="primary"
                    :options="testthingSelect.options"
                    :on-change="changetestthing"
                    class="m-md-2">                   
        </b-form-select>     
       <test-chart v-cloak :chart-data="datacollection" :chart-option="options"></test-chart>

    </div>
</template>

<script>

    import TestChart from './TestChart'

    export default {
        components: {
            TestChart 
        },
        data() {
            return {
                yAxisValues: [],
                datacollection: {},
                options: {
                    scales: {
                        yAxes: [{
                            ticks: {
                                beginAtZero: false
                            },
                            gridLines: {
                                display: true
                            }
                        }],
                        xAxes: [{
                            type: "date",
                            display:true,
                            gridLines: {
                                display: false
                            }
                        }]
                    },
                    legend: {
                        display: true
                    },
                    responsive: true,
                    maintainAspectRatio: false
                },
                testthingSelect: {
                    selected: "EIA/COAL",
                    disabled: false,
                    readonly: false,
                    visible: true,
                    color: "",
                    options: [
                        {
                            value: null,
                            text: 'Select a testthing'
                        },
                        {
                            value: "item1",
                            text: "item1"
                        },
                        {
                            value: "item1",
                            text: "item1"
                        },
                        {
                            value: "item1",
                            text: "item1"
                        }
                    ]
                }
            }
        },        
        methods: {
            changetestthing: async function () {
                try {

                    let response = await this.$http.get(url for my data);
                    this.datacollection.datasets = [];
                    this.datacollection.labels = [];

                    ...required data transformations

                    this.$set(this.datacollection, "labels", labels);
                    this.$set(this.datacollection, "datasets", datasets);
                   // this.datacollection.labels = labels;
                  //  this.datacollection.datasets = datasets;

                } catch (error) {
                    console.log(error)
                }
            }
        },
        watch: {
            'commoditySelect.selected': function () { this.changeCommodity(); }

        },
        async created() {
            // ES2017 async/await syntax via babel-plugin-transform-async-to-generator
            // TypeScript can also transpile async/await down to ES5            

            try {               
                let response = await this.$http.get(url for my data);
                            this.datacollection.datasets = [];
                            this.datacollection.labels = [];

                            ...required data transformations

                            this.$set(this.datacollection, "labels", labels);
                            this.$set(this.datacollection, "datasets", datasets);
                           // this.datacollection.labels = labels;
                          //  this.datacollection.datasets = datasets;



                    } catch (error) {
                        console.log(error)
            }
        } catch (error) {
            console.log(error)
        }
    }
}

我的TestChart.vue文件

my TestChart.vue file

<script>
    import { Line, mixins } from 'vue-chartjs'
    const { reactiveProp } = mixins

    //Exporting this so it can be used in other components
    export default {
        extends: Line,
        mixins: [reactiveProp],
        props: ['chartData', 'options'],        
        mounted() {
            this.renderChart(this.chartData, this.options)
        }
    }
</script>

因此,这在选择和更改父Vue中的数据收集方面起作用.除非我重新调整窗口大小,但图表不会重新显示.当parenttestchart.vue最初加载时,我收到以下错误:'Uncaught TypeError:无法读取null的属性'transition'.但这似乎没有任何效果,因为调整窗口大小将呈现图表的初始显示.更新数据changetestthing方法不会正确更新datacollection(chartData),但是除非我调整窗口大小,否则它不会重新呈现.

So this is working in terms of selecting and changing the datacollection within the parent vue. Unless i resize the window though the chart does not re-render. When the parenttestchart.vue initially loads i am receiving the following error: 'Uncaught TypeError: Cannot read property 'transition' of null' . But this does not seem to effect anything, as resizing the window will render the initial display of the chart. Updating the data changetestthing method does update the datacollection (chartData) correctly but unless i resize the window it does not re-render.

如何强制重新绘制图表?我如何获得对父级中的TestChart组件的引用? this.TestChart是未定义的.我只是很好奇要从引用中获取引用,我可以在其上手动调用"renderChart".谢谢.

How can I force the chart to re-render? How can i get a reference to the TestChart component in the parent?? this.TestChart is undefined. I'm only curious about getting the reference in case from the reference i can manually call 'renderChart' on it. thanks.

***更新

我能够通过以下修改来更新图表:

I was able to get the chart to update with the following modifications:

我从changetestthing方法中删除了以下几行:

I removed the following lines from the changetestthing method:

this.datacollection.datasets = null;
this.datacollection.labels = null;

并将数据收集值分配语句更改为此:

And changed the datacollection value assignment statement to this:

this.datacollection = Object.assign({}, this.datacollection, { labels: labels, datasets: datasets });

我不能肯定地说这是最佳实践.根据vue.js文档( https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats )

I can't say for sure that this is the best practice. According to vue.js documentation (https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats)

new properties added to the object will not trigger changes. In such
cases, create a fresh object with properties from both the original
object and the mixin object

因此,我相信通过不将datacollection.labels和.datasets属性设置为null,然后使用Object.assign来触发更改.我仍然不确定为什么没有使用mixins或手动手表来触发它们.任何评论表示赞赏.

So I believe by not setting the datacollection.labels and .datasets properties to null and then using the Object.assign the changes are triggered. I'm still not sure why they weren't triggered using the mixins or manual watch. Any comments appreciated.

推荐答案

Billy Jean最后的注释对我有用PIECHART.JS:

Billy Jean final note worked for me PIECHART.JS:

import {
 Pie,
 mixins
} from 'vue-chartjs'
const {
reactiveProp
} = mixins

export default Pie.extend({
   mixins: [reactiveProp],
   props: ['options'],
watch: {
'options': {
  handler(newOption, oldOption) {
    this._chart.destroy()
    this.renderChart(this.chartData, this.options)
  },
  deep: true
}
    },
  mounted() {      
    this.renderChart(this.chartData, {responsive: true, maintainAspectRadio: 
    false})
   }
})

这在我的view.vue文件中:

This is in my view.vue File:

 let datasets = []
  let colorlist = [ '#4e5fa4', '#5e5fa4', '#6e5fa4',
  '#7e5fa4', '#8e5fa4', '#a08be4', '#b08bd4']
        datasets.push({
          label: this.data_by_city_label,
          data: this.data_by_city_data,
          fill: false,
          backgroundColor: colorlist,
          pointBorderWidth: 1,
          borderWidth: 1,
          pointRadius: 0
        })
  this.CityDatac = Object.assign({}, this.datasets, {labels: this.data_by_city_label, datasets: datasets})

这样我可以将我的数据发送到PIECHART js并在view.vue中生成 如此:

With this i can send my data to the PIECHART js and generated in my view.vue as so:

   <pie-chart-city :chartData="CityDatac" :width="300" :height="250"></pie-chart-city>

希望可以帮助VUE.js中的任何人-> Vue-chartjs.js

Hope that helps anyone in VUE.js -> Vue-chartjs.js

这篇关于替换,更新chartData时,vue.js vue-chartjs图表未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆