javascriptecharts

Universal transition does not occur smoothly


I have 6 graphics that make a universal transition. However, the bar chart doesn't produce a smooth animation between the gauge and pie charts. I would like the smoothing to occur smoothly, not abruptly as it does.

The graph works as follows: when you click on the button, the animation starts, and when you click again, it stops (and it always will - toggle).

How can I ensure that the transitions always occur smoothly? I'd like to know about rules for configuring one graph to the next, whether to use any updates in the graphs, how to apply getOption() and setOption to ensure that the transition is always seamless and not abrupt.

document.addEventListener("DOMContentLoaded", function() {
      function chartSystem () {
        return {
            "source": [
                [90, 50]
            ]
        }
    }

    const dfInit = chartSystem();

    // create instance and methods
    const chartUse = echarts.init(document.getElementsByClassName("chart")[0]);

    // Series
    const serie0 = {
        type: "gauge",
        id: 'Score',
        center: ["68%", "50%"],
        radius: "50%",
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        universalTransition: {
            enabled: true
        },
        data: [{ value: dfInit.source[0][0] }, { value: dfInit.source[0][1] }]
    };

    const serie00 = {
        type: "gauge",
        id: 'Score1',
        center: ["28%", "50%"],
        radius: "50%",
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        universalTransition: {
            enabled: true
        },
        data: [{ value: dfInit.source[0][0] }, { value: dfInit.source[0][1] }]
    };

    const serie1 = {
        type: "pie",
        id: 'Score',
        center: ["68%", "50%"],
        radius: "56%",
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        universalTransition: {
            enabled: true
        },
        data: [{ value: dfInit.source[0][0] }, { value: dfInit.source[0][1] }]
    };

    const serie11 = {
        type: "pie",
        id: 'Score1',
        center: ["28%", "50%"],
        radius: "56%",
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        universalTransition: {
            enabled: true
        },
        data: [{ value: dfInit.source[0][0] }, { value: dfInit.source[0][1] }]
    };

    // New bar series
    const serie2 = {
        type: "bar",
        id: 'Score',
        xAxisIndex: 0,
        yAxisIndex: 0,
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        universalTransition: {
            enabled: true
        },
        data: [dfInit.source[0][0], dfInit.source[0][1]]
    };

    const serie22 = {
        type: "bar",
        id: 'Score1',
        xAxisIndex: 1,
        yAxisIndex: 1,
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        universalTransition: {
            enabled: true
        },
        data: [dfInit.source[0][0], dfInit.source[0][1]]
    };

    // Switchers

    function switch0() {
        chartUse.setOption({ 
            series: [serie0, serie00]
        }, { replaceMerge: ['xAxis', 'yAxis', 'grid'] } );
    }

    function switch1() {
        chartUse.setOption({ 
            series: [serie1, serie11]
        });
    }

    const xAxis0 = {
        show: true,
        type: 'category',
        data: ['A', 'B'],
        gridIndex: 0
    }

    const xAxis1 = {
        show: true,
        type: 'category',
        data: ['C', 'D'],
        gridIndex: 1
    }

    const yAxis0 = {
        show: true,
        type: 'value',
        gridIndex: 0
    }

    const yAxis1 = {
        show: true,
        type: 'value',
        gridIndex: 1
    }

    const grid0 = {
        left: '15%', 
        width: '40%'
    }

    const grid1 = {
        left: '55%', 
        width: '40%'
    }

    function switch2() {
        chartUse.setOption({
            series: [serie2, serie22],
            xAxis: [xAxis0, xAxis1],
            yAxis: [yAxis0, yAxis1],
            grid: [grid0, grid1]
        });
    }

  // Initial display
  switch0();

  // alternate button
  const bttnUniv = document.getElementsByClassName("univTrans")[0];
  let intervalId;
  let currentSwitch = 0;

  // alternate between three states
  function execute() {
    intervalId = setInterval(() => {
      currentSwitch = (currentSwitch + 1) % 3; // Cycle between 0, 1, 2

      if (currentSwitch === 0) {
        switch0();
      } else if (currentSwitch === 1) {
        switch1();
      } else {
        switch2();
      }
    }, 2000);
  };

  bttnUniv.addEventListener("click", function() {
    this.classList.toggle("start");

    if (this.classList.contains("start")) {
      execute();
    } else {
      clearInterval(intervalId);
    }
  });

});
.chart {
  width: 100%;
  height: 100vh;
}
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
<button class="univTrans">Toggle Transitions</button>
<div class="chart"></div>


Solution

  • For echarts to know which data items to transition into each other you need to specify a data.grouId (atleast in more complex scenarios). I took your example and gave items that correspond to each other the same groupId.

    Example:

    const serie0 = {
      type: 'gauge',
      id: 'Score',
      center: ['68%', '50%'],
      radius: '50%',
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'quinticInOut',
      universalTransition: {
        enabled: true
      },
      data: [
        { value: 90, groupId: '00' },
        { value: 50, groupId: '01' }
      ]
    };
    
    const serie00 = {
      type: 'gauge',
      id: 'Score1',
      center: ['28%', '50%'],
      radius: '50%',
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'quinticInOut',
      universalTransition: {
        enabled: true
      },
      data: [
        { value: 90, groupId: '10' },
        { value: 50, groupId: '11' }
      ]
    };
    
    const serie1 = {
      type: 'pie',
      id: 'Score',
      center: ['68%', '50%'],
      radius: '56%',
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'quinticInOut',
      universalTransition: {
        enabled: true
      },
      data: [
        { value: 90, groupId: '00' },
        { value: 50, groupId: '01' }
      ]
    };
    
    const serie11 = {
      type: 'pie',
      id: 'Score1',
      center: ['28%', '50%'],
      radius: '56%',
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'quinticInOut',
      universalTransition: {
        enabled: true
      },
      data: [
        { value: 90, groupId: '10' },
        { value: 50, groupId: '11' }
      ]
    };
    
    // New bar series
    const serie2 = {
      type: 'bar',
      id: 'Score',
      xAxisIndex: 0,
      yAxisIndex: 0,
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'quinticInOut',
      universalTransition: {
        enabled: true
      },
      data: [
        { value: 90, groupId: '00' },
        { value: 50, groupId: '01' }
      ]
    };
    
    const serie22 = {
      type: 'bar',
      id: 'Score1',
      xAxisIndex: 1,
      yAxisIndex: 1,
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'quinticInOut',
      universalTransition: {
        enabled: true
      },
      data: [
        { value: 90, groupId: '10' },
        { value: 50, groupId: '11' }
      ]
    };
    
    // Switchers
    
    function switch0() {
      myChart.setOption(
        {
          series: [serie0, serie00]
        },
        { replaceMerge: ['xAxis', 'yAxis', 'grid'] }
      );
    }
    
    function switch1() {
      myChart.setOption({
        series: [serie1, serie11]
      });
    }
    
    const xAxis0 = {
      show: true,
      type: 'category',
      data: ['A', 'B'],
      gridIndex: 0
    };
    
    const xAxis1 = {
      show: true,
      type: 'category',
      data: ['C', 'D'],
      gridIndex: 1
    };
    
    const yAxis0 = {
      show: true,
      type: 'value',
      gridIndex: 0
    };
    
    const yAxis1 = {
      show: true,
      type: 'value',
      gridIndex: 1
    };
    
    const grid0 = {
      left: '15%',
      width: '40%'
    };
    
    const grid1 = {
      left: '55%',
      width: '40%'
    };
    
    function switch2() {
      myChart.setOption({
        series: [serie2, serie22],
        xAxis: [xAxis0, xAxis1],
        yAxis: [yAxis0, yAxis1],
        grid: [grid0, grid1]
      });
    }
    
    switch0();
    
    let currentSwitch = 0;
    
    setInterval(() => {
      currentSwitch = (currentSwitch + 1) % 3; // Cycle between 0, 1, 2
    
      if (currentSwitch === 0) {
        switch0();
      } else if (currentSwitch === 1) {
        switch1();
      } else {
        switch2();
      }
    }, 2000);