当chartData被替换、更新等时,vue.js vue-chartjs图表不更新

p4tfgftt  于 2022-11-06  发布在  Chart.js
关注(0)|答案(3)|浏览(263)

我正在尝试使用vue-chartjs制作一个vue。我已经遵循了所有相关文档中关于在chartData属性更新时重新呈现图表的说明。我的图表只有在调整浏览器窗口大小后才会更新。
我父母测试图表.vue文件:

<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文件

<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最初加载时,我收到以下错误:'未捕获的类型错误:无法读取null'的属性'transition'。但这似乎不会产生任何影响,因为调整窗口大小将呈现图表的初始显示。更新数据changetestthing方法确实会正确更新datacollection(chartData),但除非我调整窗口大小,否则它不会重新呈现。
如何强制图表重新呈现?如何在父级中获取对TestChart组件的引用??这。TestChart未定义。我只是想从引用中获取引用,以防我可以手动对其调用'renderChart'。谢谢。

***更新

我能够通过以下修改更新图表:
我从changetestthing方法中删除了以下代码行:

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

并将数据集合赋值语句更改为:

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

我不能肯定地说这是最好的实践。

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,这些更改就会被触发。我仍然不确定为什么它们没有被mixin或手动监视触发。感谢您的评论。

svdrlsy4

svdrlsy41#

一种有效的方法是在图表中添加一个观察器,

props: ['chartData', 'options'],
mounted () {
  this.renderChart(this.chartData, this.options)
},
watch: {
  'chartData' (to, from) {
    this.renderChart(this.chartData, this.options)
  }
},

请参见示例CodePen

编辑-观察程序不工作

您的代码和工作的CodePen之间的区别在于,CodePen会改变传递到图表中的变量,因此它的观察器会做出React。
您的程式码会变更变数的.datasets属性-这个ref有一个已知的问题:混合似乎不会触发图表#44的刷新。
尝试替换

this.datacollection.datasets = [];
this.datacollection.labels = [];

与此(两个位置)

this.datacollection = { datasets: [], labels: [] };
2w3rbyxf

2w3rbyxf2#

比利·简最后一个音符对我很管用

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})
   }
})

这是在我的视图.vue文件:

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,并在我的视图中生成。

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

希望这对VUE.js -〉Vue-chartjs.js中的任何人都有帮助

r7s23pms

r7s23pms3#

Alexis Poo发布的代码为我指明了正确的方向。
在我的例子中,我需要稍微修改watch对象。
当试图通过调用this._chart.destroy()销毁图表时,当选项更改时,我收到一条错误消息:cannot read property 'destroy' of undefined .
为了解决这个问题,我必须改为执行this.$data._chart.destroy()
希望能有所帮助。

相关问题