状态更改时更新Google图表-Vuex

时间:2018-06-26 17:05:30

标签: javascript vue.js google-visualization vue-component vuex

我正在制作一个报告页面,其中将显示几个图形。当您进入页面时,它会请求通过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>

我没有解决办法,您对解决这个问题有什么建议吗?

1 个答案:

答案 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
        }
    }
}