代码之家  ›  专栏  ›  技术社区  ›  martinho

状态更改时更新google图表-vuex

  •  0
  • martinho  · 技术社区  · 6 年前

    我正在做一个报告页面,其中会出现几个图表。当您进入页面时,它会发出一个请求,要求通过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 回复  |  直到 6 年前
        1
  •  1
  •   ittus    6 年前

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