问题描述
我正在尝试使用 vue-chartjs 制作一个 vue.当 chartData 道具更新时,我已遵循所有有关重新渲染图表的相关文档.我的图表只会在我调整浏览器窗口大小后更新.
我的 parenttestchart.vue 文件:
<模板><h1>图表数据收集更新测试</h1><p>这个组件演示了从服务器获取数据.</p><p v-if="!datacollection"><em>加载中...</em></p>我的 TestChart.vue 文件
从 'vue-chartjs' 导入 { Line, mixins }const { reactiveProp } = mixins//导出这个,以便它可以在其他组件中使用导出默认{延伸:线,混合:[reactiveProp],道具:['chartData', 'options'],挂载(){this.renderChart(this.chartData, this.options)}}</脚本>
所以这在选择和更改父 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;
并将datacollection赋值语句改成这样:
this.datacollection = Object.assign({}, this.datacollection, { 标签:标签,数据集:数据集 });
我不能肯定这是最佳做法.根据 vue.js 文档(https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats)
添加到对象的新属性不会触发更改.在这样的情况下,创建一个新对象,其属性来自原始对象对象和mixin对象
所以我相信通过不将 datacollection.labels 和 .datasets 属性设置为 null 然后使用 Object.assign 触发更改.我仍然不确定为什么没有使用 mixins 或手动手表触发它们.任何意见表示赞赏.
解决方案 Billy Jean 最后的笔记对我有用 PIECCHART.JS:
导入{馅饼,混入来自'vue-chartjs'常量 {反应道具} = 混合导出默认 Pie.extend({混合:[reactiveProp],道具:['选项'],手表: {'选项': {处理程序(新选项,旧选项){this._chart.destroy()this.renderChart(this.chartData, this.options)},深:真}},挂载(){this.renderChart(this.chartData, {responsive: true, maintainAspectRadio:错误的})}})
这是在我看来.vue 文件:
让 datasets = []让 colorlist = [ '#4e5fa4', '#5e5fa4', '#6e5fa4','#7e5fa4'、'#8e5fa4'、'#a08be4'、'#b08bd4']数据集.push({标签:this.data_by_city_label,数据:this.data_by_city_data,填充:假,背景颜色:颜色列表,点边框宽度:1,边框宽度:1,点半径:0})this.CityDatac = Object.assign({}, this.datasets, {labels: this.data_by_city_label, datasets: datasets})
有了这个,我可以将我的数据发送到 PIECCHART js 并在我的 view.vue 中生成像这样:
<饼图城市 :chartData="CityDatac" :width="300" :height="250"></饼图城市>
希望对 VUE.js 中的任何人有所帮助 -> Vue-chartjs.js
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.
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)
}
}
}
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>
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.
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.
*** Update
I was able to get the chart to update with the following modifications:
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 });
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
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 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})
}
})
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})
With this i can send my data to the PIECHART js and generated in my view.vueas so:
<pie-chart-city :chartData="CityDatac" :width="300" :height="250"></pie-chart-city>
Hope that helps anyone in VUE.js -> Vue-chartjs.js
这篇关于vue.js vue-chartjs 图表在 chartData 替换、更新等时不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
08-06 20:28