vue.js vue-chartjs 图表在更换、更新图表数据等时不会更新

2024-03-29

我正在尝试使用 vue-chartjs 制作 vue。我已遵循所有有关在更新 ChartData 属性时重新渲染图表的相关文档。我的图表只会在调整浏览器窗口大小后更新。

我的parenttestchart.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最初加载时,我收到以下错误: 'Uncaught TypeError: Cannot read property 'transition' of null' 。但这似乎不会产生任何影响,因为调整窗口大小将呈现图表的初始显示。更新数据changetestthing方法确实会正确更新数据集合(chartData),但除非我调整窗口大小,否则它不会重新渲染。

如何强制图表重新渲染?我如何获得对父级中 TestChart 组件的引用? this.TestChart 未定义。我只是好奇如何从参考中获取参考,以便我可以在其上手动调用“renderChart”。谢谢。

*** 更新

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

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

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

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

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

我不能肯定地说这是最佳实践。根据 vue.js 文档(https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats https://v2.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 或手动手表触发它们。任何意见表示赞赏。


一种可行的方法是将观察者添加到图表中,

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

参见示例CodePen https://codepen.io/RMatsen/pen/QOKNYj


编辑-观察者不工作

您的代码与正在运行的 CodePen 之间的区别在于,CodePen 会改变传递到图表中的变量,因此观察者会做出反应。
你的代码改变了.datasets变量的属性 - 此引用存在一个已知问题:Mixins 似乎不会触发图表的刷新 #44 https://github.com/apertureless/vue-chartjs/issues/44#issuecomment-283203422.

尝试更换

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

与此(两个地方)

this.datacollection = { datasets: [], labels: [] };
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue.js vue-chartjs 图表在更换、更新图表数据等时不会更新 的相关文章

随机推荐