javascriptecharts

Updating two parameters separately in the same argument (ECHARTS)


I need to update two arguments inside series.data, the name and the value. The problem is that I can't separate this update in a formal way. I even manage to do it, for example, by creating another echarts leaving the rest of the chart invisible and leaving only one argument in this new series.

What I need is to update the name and value without them interfering with each other. For example:

(1) If I change the name, the value can't be updated

(2) If I change the value, the name cannot be updated

This is because they have different events (one is change and the other is click on different HTML tags).

Code:

// initialize echarts
let echartsGaugeDropUse = echarts.init(document.getElementById('gaugeChart'));

// create dataset
function getDataset() {
  let name1 = document.getElementById('nameInput').innerText;
  let value1 = Number(document.getElementById('valueInput').value);

  return {
    'source': [
      ['name', name1],
      ['value', value1]
    ]
  };
}

// init config
function update1() {
  let option = {
    title: [{
      text: "BEER",
      top: '30%',
      left: 'center'
    }],
    series: [{
      type: 'gauge',
      min: 0,
      max: 100,
      progress: {
        show: true,
        overlap: true,
        roundCap: true,
        clip: false,
        width: 20
      }
    }]
  };

  echartsGaugeDropUse.setOption(option);
}

update1();

// update funcion 
function updateGaugeData() {

  let newName = document.getElementById('changeInput').value;
  document.getElementById('nameInput').innerText = newName;

  let dataset = getDataset();

  let gaugeData = [{
    name: dataset.source[0][1],
    value: dataset.source[1][1],
    title: {
      color: 'red'
    },
    itemStyle: {
      emphasis: {
        shadowBlur: 10,
        shadowColor: 'green',
        borderColor: 'lime'
      }
    }
  }];

  echartsGaugeDropUse.setOption({
    series: [{
      data: gaugeData
    }]
  });
}

// value only
document.getElementById('valueInput').addEventListener('change', function() {
  updateGaugeData();
});

// name only
document.getElementById('changeButton').addEventListener('click', function() {
  updateGaugeData();
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ECharts Gauge Example</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.2.2/echarts.min.js"></script>
</head>

<body>

  <!--INITIAL NAME-->
  <span id='nameInput' style='display: none;'>SPAN</span>

  <!--NEW NAME-->
  <input id='changeInput' type='text'>

  <!--BUTTON TO CHANGE NAME-->
  <button id='changeButton'>Change name</button>

  <!--VALUE-->
  <input id='valueInput' type='range' min='0' max='100' value='50'>

  <!--PLOT-->
  <div id="gaugeChart" style="width: 600px; height: 400px;"></div>

</body>

</html>

As it is, the change in one interferes with the other. I know this because the same update function is being used in the events. I would like to know if there is a formal way to change the two parameters separately, instead of having to update both simultaneously.

I tried it too:

    // initialize echarts
    let echartsGaugeDropUse = echarts.init(document.getElementById('gaugeChart'));
    
    // create dataset
    function getDataset() {
      let name1 = document.getElementById('nameInput').innerText;
      let value1 = Number(document.getElementById('valueInput').value);
    
      return {
        'source': [
          ['name', name1],
          ['value', value1]
        ]
      };
    }
    
    // init config
    function update1() {
      let option = {
        title: [{
          text: "BEER",
          top: '30%',
          left: 'center'
        }],
        series: [{
          type: 'gauge',
          min: 0,
          max: 100,
          progress: {
            show: true,
            overlap: true,
            roundCap: true,
            clip: false,
            width: 20
          }
        }]
      };
    
      echartsGaugeDropUse.setOption(option);
    }
    
    update1();
    
    // update funcion 
    // update function 
    function updateGaugeData(eventType) {
      // Check the event type
      if (eventType === 'name') {
        let newName = document.getElementById('changeInput').value;
        document.getElementById('nameInput').innerText = newName;
      } else if (eventType === 'value') {
        let dataset = getDataset();
    
        let gaugeData = [{
          name: dataset.source[0][1],
          value: dataset.source[1][1],
          title: {
            color: 'red'
          },
          itemStyle: {
            emphasis: {
              shadowBlur: 10,
              shadowColor: 'green',
              borderColor: 'lime'
            }
          }
        }];
    
        echartsGaugeDropUse.setOption({
          series: [{
            data: gaugeData
          }]
        });
      }
    }
    
    // value only
    document.getElementById('valueInput').addEventListener('change', function() {
      updateGaugeData('value');
    });
    
    // name only
    document.getElementById('changeButton').addEventListener('click', function() {
      updateGaugeData('name');
    }); 

But it doesn't work.


Solution

  • I am not sure I fully understand what you are trying to achieve. If you want to avoid the animation of the pointer from zero when you change the name (and possibly to be able to initialize the name without an initialization of the value/pointer), since you can't partially update a data point, as @Matthias Mertens stated in the comments, you're left with the option to separate the value (+pointer and progress) in a data point and the name in another:

    // initialize echarts
    const echartsGaugeDropUse = echarts.init(document.getElementById('gaugeChart'));
    
    // init config
    function update1() {
        let option = {
            title: [{
                text: "BEER",
                top: '30%',
                left: 'center'
            }],
            series: [{
                type: 'gauge',
                min: 0,
                max: 100,
                progress: {
                    show: true,
                    overlap: true,
                    roundCap: true,
                    clip: false,
                    width: 20
                }
            }]
        };
    
        echartsGaugeDropUse.setOption(option);
    }
    
    update1();
    
    // update funcion
    function updateGaugeData(eventType) {
        const data = echartsGaugeDropUse.getOption().series[0].data ?? [];
        if (eventType === 'name') {
            let newName = document.getElementById('changeInput').value;
            document.getElementById('nameInput').innerText = newName;
            if(data.length <= 1){
                data.push({ // initialization of name data item
                    detail:{
                        show: false
                    },
                    progress: {
                        show: false
                    },
                    itemStyle:{
                        opacity: 0
                    },
    
                    name: newName,
                    value: 0,
                    title: {
                        color: 'red'
                    }
                });
            }
            else{
                data[1].name = newName;
            }
        }
        else{ // if (eventType === 'value') {
            const newValue = Number(document.getElementById('valueInput').value);
            if(data.length <= 1){ // initialization of value data item
                data.unshift({});
            }
            data[0].value = newValue;
        }
    
        echartsGaugeDropUse.setOption({
            series: [{
                data
            }]
        });
    }
    
    // value only
    document.getElementById('valueInput').addEventListener('change', function() {
        updateGaugeData('value');
    });
    
    // name only
    document.getElementById('changeButton').addEventListener('click', function() {
        updateGaugeData('name');
    });
    <!--INITIAL NAME-->
    <span id='nameInput' style='display: none;'>SPAN</span>
    
    <!--NEW NAME-->
    <input id='changeInput' type='text'>
    
    <!--BUTTON TO CHANGE NAME-->
    <button id='changeButton'>Change name</button>
    
    <!--VALUE-->
    <input id='valueInput' type='range' min='0' max='100' value='50'>
    
    <!--PLOT-->
    <div id="gaugeChart" style="width: 600px; height: 400px;"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.2.2/echarts.min.js"></script>

    Possibly excessive, but with the advantage of simplicity, you can even separate the value and name into two different series:

    // initialize echarts
    const echartsGaugeDropUse = echarts.init(document.getElementById('gaugeChart'));
    
    // init config
    function update1() {
        let option = {
            title: [{
                text: "BEER",
                top: '30%',
                left: 'center'
            }],
            series: [{
                type: 'gauge',
                min: 0,
                max: 100,
                progress: {
                    show: true,
                    overlap: true,
                    roundCap: true,
                    clip: false,
                    width: 20
                }
            }]
        };
    
        echartsGaugeDropUse.setOption(option);
    }
    
    update1();
    
    // update funcion
    function updateGaugeData(eventType) {
        const opts = echartsGaugeDropUse.getOption();
        const series = opts.series;
        if (eventType === 'name') {
            let newName = document.getElementById('changeInput').value;
            document.getElementById('nameInput').innerText = newName;
            if(series.length === 1){
                series.push({
                    ...series[0],
                    anchor: {
                        show: false
                    },
                    detail:{
                        show: false
                    },
                    progress: {
                        show: false
                    },
                    pointer: {
                        show: false
                    },
                    data: [{
                        name: newName,
                        value: 0,
                        title: {
                            color: 'red'
                        }
                    }]
                });
            }
            else{
                series[1].data[0].name = newName;
            }
        }
        else{
            const newValue = Number(document.getElementById('valueInput').value);
    
            if(!series[0].data || series[0].data.length === 0){
                series[0].data = [{}];
            }
            series[0].data[0].value = newValue;
        }
    
        echartsGaugeDropUse.setOption({
            series: series
        });
    }
    
    // value only
    document.getElementById('valueInput').addEventListener('change', function() {
        updateGaugeData();
    });
    
    // name only
    document.getElementById('changeButton').addEventListener('click', function() {
        updateGaugeData('name');
    });
    <span id='nameInput' style='display: none;'>SPAN</span>
    
    <!--NEW NAME-->
    <input id='changeInput' type='text'>
    
    <!--BUTTON TO CHANGE NAME-->
    <button id='changeButton'>Change name</button>
    
    <!--VALUE-->
    <input id='valueInput' type='range' min='0' max='100' value='50'>
    
    <!--PLOT-->
    <div id="gaugeChart" style="width: 600px; height: 400px;"></div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.2.2/echarts.min.js"></script>