我正在制作一个报告页面,其中将显示几个图形。当您进入页面时,它会请求通过API接收所有默认信息。之后的想法是让用户根据输入选择一些过滤器。
示例:初始-所有结果/带有过滤器-一些结果。
要实现此目的,我使用vuejs制作组件,使用vuex保存信息,使用Google图表制作图表。
我的问题是,当我实现一些过滤器时,即使状态更新,图形也不会更新。我放置了一个观察者,以检查状态是否发生了变化,但是只有在状态创建时才进入。
我的代码-
vuex-
import axios from 'axios';
const state = {
dataChart: {}
}
const mutations = {
'ADD_DATA_CHART'(state, data) {
state.dataChart[data.key] = [];
[].forEach.call(data.states, (s, i) => {
let obj = {};
obj.name = s;
obj.data = [];
[].forEach.call(data.value, d => {
obj.data.push([d.name, d[data.keys[i]].toFixed(2)]);
});
state.dataChart[data.key].push(obj);
});
}
}
const actions = {
fetchReporting({state, commit}, response) {
axios.post(response.endpoint, response.formData)
.then(({data}) => {
commit('ADD_DATA_CHART', {key: response.chart, value: data, states: response.states, keys: response.keys})
}).catch(err => {
console.log(err);
});
}
}
const getters = {
dataChart: state => state.dataChart
}
export default {
state,
mutations,
actions,
getters
}
组件-
<template>
<div class="box-content-white">
<div class="title">Chart</div>
<div id="stackedChart"></div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { mapActions } from 'vuex';
export default {
props: {
endpoint: String,
chart: String,
states: Array,
keys: Array
},
data() {
return {
data: []
}
},
methods: {
...mapActions({
fetchReporting: 'fetchReporting'
}),
loadChart() {
google.charts.load('current', {'packages':['corechart'],'language': 'pt'});
google.charts.setOnLoadCallback(this.drawChart);
},
drawChart() {
var stackedChart = new google.visualization.DataTable();
stackedChart.addColumn('string', this.states[0]);
stackedChart.addColumn('number', this.states[1]);
stackedChart.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
stackedChart.addColumn('number', this.states[2]);
stackedChart.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
stackedChart.addColumn('number', this.states[3]);
stackedChart.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
stackedChart.addRows(this.data);
var options = {
width: '100%',
height: 600,
chartArea: {width: '90%', height: '60%', left: 120},
isStacked: true,
colors: ['#e6a8b9','#cc5173', '#901c3c'],
tooltip: { isHtml: true },
legend: { position: 'bottom', alignment: 'start' },
animation: {
duration: 1000,
easing: 'out',
startup: true
}
};
new google.visualization.ColumnChart(document.getElementById('stackedChart')).draw(stackedChart, options);
},
drawHtmlTooltip(message, message2, message3, message4, url) {
return `<div class="content">
<div class="img">
<img src="url" alt="Cliente">
</div>
<div class="text">
<div><span class="info">Message</div>
<div><span class="info">Message2</div>
<div><span class="info">Message3</div>
<div><span class="info">Message4</div>
</div>
</div>`;
},
mountData() {
[].forEach.call(this.dataChart[this.chart], d => {
let htmlTooltip = this.drawHtmlTooltip(message, message2, message3, message4, url);
this.data.push([ // * it is necessary to repeat the tooltip, so that it is uniform in all bars
d.name,
parseInt(value),
htmlTooltip,
parseInt(value2),
htmlTooltip,
parseInt(value3),
htmlTooltip
]);
});
this.loadChart();
}
},
mounted() {
this.fetchReporting({endpoint: this.endpoint, chart: this.chart, formData: { state: 'negotiation' }})
.then(response => {
this.mountData();
}, error => {
console.log(error)
});
},
computed: {
...mapGetters({
dataChart: 'dataChart'
})
},
watch: {
dataChart: {
immediate: true, // so this runs initially
deep: true, // so it detects changes to properties only
handler(newVal, oldVal) {
console.log('selectedItem changed!', oldVal, '-->', newVal);
}
}
}
}
</script>
我没有解决办法,您对解决这个问题有什么建议吗?
答案 0 :(得分:1)
要使state.dataChart
具有反应性,您需要将其分配给新的对象引用。
ES6语法:
const mutations = {
'ADD_DATA_CHART'(state, data) {
var newDataItem = []
[].forEach.call(data.states, (s, i) => {
let obj = {};
obj.name = s;
obj.data = [];
[].forEach.call(data.value, d => {
obj.data.push([d.name, d[data.keys[i]].toFixed(2)]);
});
newDataItem.push(obj);
});
state.dataChart = {
...state.dataChart,
[data.key]: newDataItem
}
}
}