Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Watch does not work in EChart chart data update in Vue

Tags:

vue.js

echarts

I am working with EChart and Vue 2, I made a simple EChart component.

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import * as echarts from 'echarts';
require('echarts/theme/macarons') // echarts theme
export default {
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '300px'
    },
    chartData: {
      type: Object,
      required: true
    },
    autoResize: {
        type: Boolean,
        default: true,
      },        
  },
  watch: {

    chartData: {
         deep: true,
         handler(val) {
          console.log('chartdata handler',val);

          this.setOptions(val.legend, val.data);
         }
    },
    width: {
         deep: true,
         handler(val) {
          console.log(' width',val);
        }
    }
  },  
  data() {
    return {
      chart: null
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose();
    this.chart = null;
    
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el, 'macarons');
      this.setOptions(
         ['pepper','rice'],
         [
              { value: 0, name: 'pepper' },
              { value: 0, name: 'rice' },
        ]
      );
    },

    setOptions( lengend, data ) {    
      this.chart.setOption({
          title: {
              left: 'center'
          },
          tooltip: {
            trigger: 'item'
          },
          legend: {
            top: '5%',
            left: 'center',
            data: lengend,
          },
          series: [
            {
              name: 'Access From',
              type: 'pie',
              radius: ['40%', '70%'],
              itemStyle: {
                borderRadius: [20, 5, 5, 10],
                borderColor: '#fff',
                borderWidth: 2
              },
              label: {
                show: false
              },
              data: data
            }
          ]
        });
    }
  }
}
</script>

I use this component in another parent.

   <PieChart ref="pieChart" :chartData="pieData" :width="'400px'"> </PieChart>

  data () {
    return {
        pieData: {
            name: 'crop distribution',
            data:[
                { value: 115, name: 'pepper' },
                { value: 128, name: 'rice' }
            ],
            legend:['pepper','rice']
        },
     }

However this code would never pass chartData to PieChart to update the graph. I looked into and found:

watch: {
    chartData: { deep: true,
         handler(val) {
          console.log('chartdata handler',val);
          this.setOptions(val.legend, val.data);
         }
    },
}

This watch function is not triggered, no console output yet. The watch is working well in other Vue application, but when integrating with EChart, there is no working here.

like image 776
user824624 Avatar asked Jan 19 '26 00:01

user824624


1 Answers

Pretty sure you are just missing immediate: true on the watcher:

  watch: {
    chartData: {
      handler(val) {
        console.log('chartdata handler',val);
        this.setOptions(val.legend, val.data);
      }
      deep: true,
      immediate: true,  // <--------------
    },
  }

Without it, watchers are not triggered during initialization, only afterwards when data changes. So if you never change data (and it does not look like you do), your watcher never runs.

Adding the property changes it into an eager watcher, which is run when data is set the first time. (Documentation on this is poor for v2, but it works the same in v3.)

Does that work?

like image 100
Moritz Ringler Avatar answered Jan 20 '26 18:01

Moritz Ringler