在vue.js中使am4Charts具有反应性

时间:2019-08-20 11:02:11

标签: vue.js vuejs2 vue-component amcharts amcharts4

我正在尝试在am4chart中为vuejs构建一个组件,以便可以在不同的地方重新使用,我有一些搜索选项,它们可以将chartData的值更改为根据搜索结果。

当我的搜索页面加载时,它完美地显示了图表,但是当我尝试检查过滤器时,它并没有按照数据显示或更改。我在am4Chart部分中拥有与mounted相关的所有代码,因此我尝试将它们放在我的methods中,并尝试从那里在安装的部分中调用method。我还放置了一个watch函数,以便在数据更改时可以再次调用该函数。但是,当我将其放置在methods中时,整个chart都消失了,实际上,如果我将相同的代码放置在mountedmethods部分中,则它不会显示。

我已经通过控制台检查了method更改时正在调用我的chartData,但不知道如何使它响应。

VueJS版本2.6.10

am4Chart版本4.4.10

我的代码:

<template>
    <div ref="amchart_semi_pie_chart"></div>
</template>

<script>
    import * as am4core from "@amcharts/amcharts4/core";
    import * as am4charts from "@amcharts/amcharts4/charts";

    export default {
        name: "amchart-semi-pie-chart",
        props: {
            chartData: Object,
        },
        data() {
            return {
                chart: '',
            }
        },
        methods: {
            loadChart() {
                console.log('Values are changed')
            }
        },
        mounted() {
            //Creating charts
            let chart = am4core.create(this.$refs.amchart_semi_pie_chart, am4charts.PieChart);
            chart.hiddenState.properties.opacity = 0; // this creates initial fade-in

            chart.data = this.chartData.data;

            // Add and configure Series

            chart.radius = am4core.percent(70);
            chart.innerRadius = am4core.percent(40);
            chart.startAngle = 180;
            chart.endAngle = 360;

            let series = chart.series.push(new am4charts.PieSeries());
            series.dataFields.value = "value";
            series.dataFields.category = "label";

            series.slices.template.cornerRadius = 10;
            series.slices.template.innerCornerRadius = 7;
            series.slices.template.draggable = true;
            series.slices.template.inert = true;
            series.alignLabels = false;

            if(this.chartData.legends)
                chart.legend = new am4charts.Legend();

            this.chart = chart;

        },
        watch: {
            chartData: {
                handler: 'loadChart',
                deep: true
            }
        },
        beforeDestroy() {
            if (this.chart) {
                this.chart.dispose();
            }
        }
    }
</script>

2 个答案:

答案 0 :(得分:2)

遇到相同的问题,经过一番挖掘,我发现您可以使用 chart.invalidateRawData()刷新数据。

请参阅文档AMCharts Data - Dynamic Updates (Manipulating existing data points)

我将此方法应用于对我有用的道具的观看方法...

<template>
    <div ref="amchart_semi_pie_chart"></div>
</template>

<script>
    import * as am4core from "@amcharts/amcharts4/core";
    import * as am4charts from "@amcharts/amcharts4/charts";

    export default {
        name: "amchart-semi-pie-chart",
        props: {
            chartData: Object,
        },
        data() {
            return {
                chart: '',
            }
        },
        methods: {
            loadChart() {
                console.log('Values are changed')
                this.chart.invalidateRawData();
            }
        },
        mounted() {
            //Creating charts
            let chart = am4core.create(this.$refs.amchart_semi_pie_chart, am4charts.PieChart);
            chart.hiddenState.properties.opacity = 0; // this creates initial fade-in

            chart.data = this.chartData.data;

            // Add and configure Series

            chart.radius = am4core.percent(70);
            chart.innerRadius = am4core.percent(40);
            chart.startAngle = 180;
            chart.endAngle = 360;

            let series = chart.series.push(new am4charts.PieSeries());
            series.dataFields.value = "value";
            series.dataFields.category = "label";

            series.slices.template.cornerRadius = 10;
            series.slices.template.innerCornerRadius = 7;
            series.slices.template.draggable = true;
            series.slices.template.inert = true;
            series.alignLabels = false;

            if(this.chartData.legends)
                chart.legend = new am4charts.Legend();

            this.chart = chart;

        },
        watch: {
            chartData: {
                handler: 'loadChart',
                deep: true
            }
        },
        beforeDestroy() {
            if (this.chart) {
                this.chart.dispose();
            }
        }
    }
</script>

答案 1 :(得分:0)

我知道这很老了,您可能会继续进行该项目,但是从今天起,我遇到了同样的问题并找到了解决方案,我认为可以答复。 就我而言,不是使用道具,而是使用数据集的计算属性。 我已经尝试了一些方法,而对我有用的方法是将整个图表创建包装到一个方法中,并观察该计算属性(在您的情况下为prop)进行更改,然后再次启动该方法。可以看到,图表实际上是重新绘制的,不仅仅具有更改动画的效果,但现在可以正常工作了。

因此,您的代码应如下所示:

<template>
    <div ref="amchart_semi_pie_chart"></div>
</template>

<script>
    import * as am4core from "@amcharts/amcharts4/core";
    import * as am4charts from "@amcharts/amcharts4/charts";

    export default {
        name: "amchart-semi-pie-chart",
        props: {
            chartData: Object,
        },
        data() {
            return {
                chart: '',
            }
        },
        methods: {
            loadChart() {
                console.log('Values are changed')
            },
            renderChart() {
                //Creating charts
                let chart = am4core.create(this.$refs.amchart_semi_pie_chart, am4charts.PieChart);
                chart.hiddenState.properties.opacity = 0; // this creates initial fade-in

                chart.data = this.chartData.data;

                // Add and configure Series

                chart.radius = am4core.percent(70);
                chart.innerRadius = am4core.percent(40);
                chart.startAngle = 180;
                chart.endAngle = 360;

                let series = chart.series.push(new am4charts.PieSeries());
                series.dataFields.value = "value";
                series.dataFields.category = "label";

                series.slices.template.cornerRadius = 10;
                series.slices.template.innerCornerRadius = 7;
                series.slices.template.draggable = true;
                series.slices.template.inert = true;
                series.alignLabels = false;

                if(this.chartData.legends)
                    chart.legend = new am4charts.Legend();

                this.chart = chart;
            }
        },
        mounted() {
            renderChart();
        },
        watch: {
            chartData: {
                renderChart();
            }
        },
        beforeDestroy() {
            if (this.chart) {
                this.chart.dispose();
            }
        }
    }
</script>