echarts: Problems when updating chart through echartsInstance.setOption()

When updating the charts through echartsInstance.setOption(), the series are not always correctly updated/drawn.

For example, when I initialize the chart (custom made funnel, but this happens with every chart type) with 3 series, it may look like this:

chart_1

It shows 3 series, which all display correctly. Now, when I create a new chart object with 6 series, and overwrite my current chart, it changes (and animates) to:

chart_2

This, also, looks good. The problem is when updating again, to a chart with less series then the current chart. See what happens when I update the chart to 3 series:

chart_3

It draws the 3 new series over the first old 3 series, and keeps series 4, 5 and 6.


When I output the chart object to console, it shows:

"option": {
    "title": {
        "show": false
    },
    "legend": {
        "show": false,
        "data": [
            {
                "name": "Smartphone",
                "icon": "circle"
            },
            {
                "name": "Desktop",
                "icon": "circle"
            },
            {
                "name": "Tablet",
                "icon": "circle"
            }
        ],
        "selected": {
            "Smartphone": true,
            "Desktop": true,
            "Tablet": true
        }
    },
    "grid": {
        "containLabel": false,
        "top": 0,
        "right": 2,
        "bottom": 20,
        "left": 0,
        "height": 190
    },
    "toolbox": {
        "show": false
    },
    "xAxis": {
        "type": "category",
        "boundaryGap": true,
        "axisLabel": {
            "textStyle": {
                "color": "#444"
            }
        },
        "axisTick": {
            "interval": "auto",
            "lineStyle": {
                "color": "#e5e5e5"
            }
        },
        "axisLine": {
            "lineStyle": {
                "color": "#e5e5e5"
            }
        },
        "splitLine": {
            "show": false,
            "interval": 0,
            "lineStyle": {
                "color": "#e5e5e5"
            }
        },
        "data": [
            {
                "value": "Bezoeken",
                "textStyle": {
                    "align": "center",
                    "fontSize": 10
                }
            },
            {
                "value": "Actief",
                "textStyle": {
                    "align": "center",
                    "fontSize": 10
                }
            },
            {
                "value": "Winkelwagens",
                "textStyle": {
                    "align": "center",
                    "fontSize": 10
                }
            },
            {
                "value": "Bestellingen",
                "textStyle": {
                    "align": "center",
                    "fontSize": 10
                }
            }
        ]
    },
    "yAxis": [
        {
            "boundaryGap": [
                0,
                "10%"
            ],
            "type": "value",
            "show": false,
            "min": 0,
            "axisLabel": {
                "textStyle": {
                    "color": "#444",
                    "fontSize": 10
                }
            },
            "axisTick": {
                "lineStyle": {
                    "color": "#e5e5e5"
                }
            },
            "axisLine": {
                "lineStyle": {
                    "show": false,
                    "color": "#fff"
                }
            },
            "splitLine": {
                "interval": 0,
                "show": false,
                "lineStyle": {
                    "color": "#e5e5e5"
                }
            },
            "data": [
                "Smartphone",
                "Desktop",
                "Tablet"
            ]
        }
    ],
    "series": [
        {
            "name": "Smartphone",
            "type": "bar",
            "stack": "metric",
            "label": {
                "normal": {
                    "show": true,
                    "position": "top",
                    "offset": [
                        0,
                        -10
                    ],
                    "textStyle": {
                        "color": "#444"
                    }
                }
            },
            "itemStyle": {
                "normal": {
                    "color": "#1AB394"
                }
            },
            "data": [
                185,
                89,
                8,
                0
            ]
        },
        {
            "name": "Desktop",
            "type": "bar",
            "stack": "metric",
            "label": {
                "normal": {
                    "show": true,
                    "position": "top",
                    "offset": [
                        0,
                        -10
                    ],
                    "textStyle": {
                        "color": "#444"
                    }
                }
            },
            "itemStyle": {
                "normal": {
                    "color": "#23C6C8"
                }
            },
            "data": [
                104,
                51,
                9,
                1
            ]
        },
        {
            "name": "Tablet",
            "type": "bar",
            "stack": "metric",
            "label": {
                "normal": {
                    "show": true,
                    "position": "top",
                    "offset": [
                        0,
                        -10
                    ],
                    "textStyle": {
                        "color": "#444"
                    }
                }
            },
            "itemStyle": {
                "normal": {
                    "color": "#F8AC59"
                }
            },
            "data": [
                38,
                25,
                4,
                0
            ]
        }
    ],
    "tooltip": {
        "trigger": "axis",
        "position": "inside",
        "axisPointer": {
            "shadowStyle": {
                "color": "#000",
                "shadowBlur": 0,
                "opacity": 0.07
            },
            "type": "shadow"
        },
        "textStyle": {
            "fontFamily": "Roboto"
        },
        "extraCssText": "padding: 8px 15px; font-size: 13px;"
    }
}

There is not a single mention of “Motorola”, “Huawei” or “Overig” in my code, but, when I add console.log(params) to charts.tooltip.formatter, it shows:

[
	{
		"componentType": "series",
		"componentSubType": "bar",
		"seriesType": "bar",
		"seriesIndex": 0,
		"seriesId": "\u0000Smartphone\u00000",
		"seriesName": "Smartphone",
		"name": "Bezoeken",
		"dataIndex": 0,
		"data": 185,
		"value": 185,
		"color": "#1AB394",
		"marker": "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:#1AB394;\"></span>",
		"$vars": [
			"seriesName",
			"name",
			"value"
		],
		"axisDim": "x",
		"axisIndex": 0,
		"axisType": "xAxis.category",
		"axisId": "\u0000\u0000-\u00000",
		"axisValue": "Bezoeken",
		"axisValueLabel": "Bezoeken"
	},
	{
		"componentType": "series",
		"componentSubType": "bar",
		"seriesType": "bar",
		"seriesIndex": 1,
		"seriesId": "\u0000Desktop\u00000",
		"seriesName": "Desktop",
		"name": "Bezoeken",
		"dataIndex": 0,
		"data": 104,
		"value": 104,
		"color": "#23C6C8",
		"marker": "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:#23C6C8;\"></span>",
		"$vars": [
			"seriesName",
			"name",
			"value"
		],
		"axisDim": "x",
		"axisIndex": 0,
		"axisType": "xAxis.category",
		"axisId": "\u0000\u0000-\u00000",
		"axisValue": "Bezoeken",
		"axisValueLabel": "Bezoeken"
	},
	{
		"componentType": "series",
		"componentSubType": "bar",
		"seriesType": "bar",
		"seriesIndex": 2,
		"seriesId": "\u0000Tablet\u00000",
		"seriesName": "Tablet",
		"name": "Bezoeken",
		"dataIndex": 0,
		"data": 38,
		"value": 38,
		"color": "#F8AC59",
		"marker": "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:#F8AC59;\"></span>",
		"$vars": [
			"seriesName",
			"name",
			"value"
		],
		"axisDim": "x",
		"axisIndex": 0,
		"axisType": "xAxis.category",
		"axisId": "\u0000\u0000-\u00000",
		"axisValue": "Bezoeken",
		"axisValueLabel": "Bezoeken"
	},
	{
		"componentType": "series",
		"componentSubType": "bar",
		"seriesType": "bar",
		"seriesIndex": 3,
		"seriesId": "\u0000Motorola\u00000",
		"seriesName": "Motorola",
		"name": "Bezoeken",
		"dataIndex": 0,
		"data": 7,
		"value": 7,
		"color": "#ED5565",
		"marker": "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:#ED5565;\"></span>",
		"$vars": [
			"seriesName",
			"name",
			"value"
		],
		"axisDim": "x",
		"axisIndex": 0,
		"axisType": "xAxis.category",
		"axisId": "\u0000\u0000-\u00000",
		"axisValue": "Bezoeken",
		"axisValueLabel": "Bezoeken"
	},
	{
		"componentType": "series",
		"componentSubType": "bar",
		"seriesType": "bar",
		"seriesIndex": 4,
		"seriesId": "\u0000Huawei\u00000",
		"seriesName": "Huawei",
		"name": "Bezoeken",
		"dataIndex": 0,
		"data": 4,
		"value": 4,
		"color": "#1C84C6",
		"marker": "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:#1C84C6;\"></span>",
		"$vars": [
			"seriesName",
			"name",
			"value"
		],
		"axisDim": "x",
		"axisIndex": 0,
		"axisType": "xAxis.category",
		"axisId": "\u0000\u0000-\u00000",
		"axisValue": "Bezoeken",
		"axisValueLabel": "Bezoeken"
	},
	{
		"componentType": "series",
		"componentSubType": "bar",
		"seriesType": "bar",
		"seriesIndex": 5,
		"seriesId": "\u0000Other\u00000",
		"seriesName": "Other",
		"name": "Bezoeken",
		"dataIndex": 0,
		"data": 9,
		"value": 9,
		"color": "#dedede",
		"marker": "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:#dedede;\"></span>",
		"$vars": [
			"seriesName",
			"name",
			"value"
		],
		"axisDim": "x",
		"axisIndex": 0,
		"axisType": "xAxis.category",
		"axisId": "\u0000\u0000-\u00000",
		"axisValue": "Bezoeken",
		"axisValueLabel": "Bezoeken"
	}
]

So, they are not in my chart object, but Echarts still draws them, and as you can see, they still exist in the tooltip params.

The chart does update well when using chartInstance.clear() before chartInstance.setOption(), but then I’ll lose all the nice transitions and animations, which make ECharts look so beautiful.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 20
  • Comments: 63 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I have the same problem recently , i solved it by set the series’s data = null which you do not want. Also you can try it setOption(option, true)

This is still a problem. And a very annoying one. I’d call it a bug rather than an enhancement, since it’s a very big problem when dealing with realtime data (calling setOption frequently) and building the chart from data in React. 😃

Same issue here. To resolve it I set notMerge to true in setOption() as per ECharts Documentation

It does not solve the problem for me.

Sorry to be late here. 5.0 introduces a new parameter replaceMerge that can remove series or any component without loosing interaction states from other components, like legend selection.

https://echarts.apache.org/en/api.html#echartsInstance.setOption

Example usage:

myChart.setOption({
  series: newSeriesHere
}, { replaceMerge: ['series'] })

I’ve solved it just clearing the chart variable before passing the options:

var myChart = echarts.init(document.getElementById("bar-chart"));
myChart.clear();
myChart.setOption(option, true), $(function () { ... }

It works nice.

I have the same problems and I agree with @sorenhoyer: I would also call it a bug. It should be possible to delete series with setOptions

setOption() is still leaving the old data on the chart BTW.

I solved this for React and only set “notMerge” to true.

<ReactECharts option={options} opts={{ renderer: 'svg' }} notMerge={true} />

In Angular using ngx-echarts. I solved it temporarily as follows.

First get a hold of your echarts instance. You can do this in your markup. Add “chartInit” and reference your desired function

<div echarts [options]="this.options" [merge]="updateOptions" (chartInit)="this.onChartInit($event)" class="chart"></div>

In your ts:

onChartInit(ec) {
    this.echartsInstance = ec;
    // do whatever you want here
}

So now this.echartsInstance can be used.

Then when updating your chart (in my case in the updateOptions function), I just added:

if (this.echartsInstance) {
      // Temp fix for bug, see: https://github.com/apache/incubator-echarts/issues/6202
      this.echartsInstance.clear();
      this.echartsInstance.setOption(this.options);
}

Same issue here. To resolve it I set notMerge to true in setOption() as per ECharts Documentation

Actually we can’t setOptions() fluently by using noMerge=true even chart.clear()cause it will resets the legends we selected before.

Yeah, I’m still experiencing this problem. Moreover, in my case optional parameter notMerge wasn’t helpful at all. Therefore, It would be really nice to have this bug fixed. Thank you for time and effort in advance!

the problem is still present when I try to switch the expandAndCollapse state in the tree viewer from true to false, it continues expanding and collapsing the tree, although it shouldn’t so the setOption still doesn’t work properly can you please look at this problem and try to fix it? would be really grateful!

@marccompte I have struggled with the same issue, replaceMerge works as you’d expect. Try this:

  chart.setOption(options, {
    replaceMerge: ["series", "yAxis", "xAxis", "grid"],
  });

Same issue here. To resolve it I set notMerge to true in setOption() as per ECharts Documentation

Setting True Fixes it. It preserves the transition animation too. http://jsfiddle.net/jeffersonswartz/r6vuo0pq/1/

I solved this for React and only set “notMerge” to true.

<ReactECharts option={options} opts={{ renderer: 'svg' }} notMerge={true} />

This help for me ❤️

A pending bug from 5 years ago in high priority, and it is still not fixed …

I tried all the suggested hacks listed above but I am getting the same error. I am using socket.io to update the data but I have no idea how to approach this issue after trying the suggested hacks. Any suggestions what the underlying cause of this problem might by?

This sounds like a bug to me, if you can add a series via setOption, then you should be able to remove a series as well. Here’s a quick reproducer of this bug:

http://jsfiddle.net/douykvbc/

Clicking on One Line and then Two Lines => works

Clicking on Two Lines and then One Line => doesn’t work

Are there any updates?

for someone who may meet this problem, you may have wrapped a component like this:

useEffect(() => {
if (!chartInstanceRef.current) return;
chartInstanceRef.current?.setOption(option, { notMerge: true }); // set notMerge true
}, [options])

I tried that but did not work. I’m trying other chart libraries now.

So is there a recommended way by now to remove a Series from the Chart, without losing every other config option?

Still a problem, especially on vue.js… Someone maybe can help with fix for vue.js?

Are people here using React with eCharts?

come on after 2 years still not fixed? I need to remove the series without refreshing the chart

Nearly two years and still no response to this. This isn’t an “enhancement” … it’s an extremely annoying and show stopping bug. Any idea on when this will be resolved? All these hacky solutions are mediocre at best and leave the potential for a future update to Echarts that fixes the problem to break the solution users have come up with on their own.

To me this is a serious defect, as it kills most of the animation feature from echarts, when morphing across changes. Doing a clear() inbetween all updates is destroying most of the nice rendering effects.

I’ve solved it creating two functions one only with myChart.clear and another for draw all the chart and allways first call de function wich clear the chart and after the ones for draw it.

@100pah I’ve noticed you added the new-feature label, but I believe this is a bug. Please see my post above.

Thanks for your suggestions!

Setting data = null on all the previous series may lead to a lot of code rewriting on my part, which is not my prefered option.

And, using setOption(option, true), is the same as calling refresh(), which removes the transition animations, which is what I like so much about ECharts. But for now, I’ll go with setOption(option, true) when changing data, until the ECharts team comes with a solution or fix. Thanks!