javascriptecharts

echartsInstance.dispatchAction in same instance with multiple series


I've applied echartsInstance.dispatchAction to separate instances, and it works very well (even with echarts.connect() the job is done well.

However, the problem occurs when, in the same instance, I need to manipulate several series at once. There seems to be some interference between them.

In my case, when I try to apply the action showTip it doesn't apply to the second series.

I would like the tooltip to be applied to option.series[1].data[0] when I hover over option.series[0].data[0].

See the code:

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
</head>

<div class="chart"></div>

<style>
    .chart {
        width: 100%;
        height: 100vh;
    }
</style>

<script>
    document.addEventListener("DOMContentLoaded", function() {

        const chartUse = echarts.init(document.getElementsByClassName("chart")[0]);

        const option = {

            tooltip: [{show: true}],

            series: [
                {
                    type: "gauge",
                    center: ["30%", "50%"],
                    data: [{value: 40}]
                },
                {
                    type: "gauge",
                    center: ["70%", "50%"],
                    data: [{value: 80, itemStyle: {color: "#f00"}}]
                }
            ]

        }

        chartUse.setOption(option);

        // events and actions
        chartUse.on("mouseover", {seriesIndex: 0, dataIndex: 0}, function() {
            chartUse.dispatchAction({
                type: "showTip",
                seriesIndex: 1,
                dataIndex: 0
            })
        })

        chartUse.on("mouseout", {seriesIndex: 0, dataIndex: 0}, function() {
            chartUse.dispatchAction({
                type: "hideTip",
                seriesIndex: 1,
                dataIndex: 0
            })
        })

    })
</script> 

I've tried another way (equivalent) but it doesn't work either:

        // events and actions
        chartUse.on("mouseover", (params) => {
            if (params.seriesIndex === 0 && params.dataIndex === 0) {
                chartUse.dispatchAction({
                    type: "showTip",
                    seriesIndex: 1,
                    dataIndex: 0
                })
            }
        })

        chartUse.on("mouseout", (params) => {
            if (params.seriesIndex === 0 && params.dataIndex === 0) {
                chartUse.dispatchAction({
                    type: "hideTip",
                    seriesIndex: 1,
                    dataIndex: 0
                })
            }
        })

Is there a solution to this or is it a possible bug?


Solution

  • The main interference/reason that prevents your code from working is the fact that there is only one tooltip per chart. Probably you already knew this, and intended to show only the right tooltip (for seriesIndex: 1) when the mouse is over the left or seriesIndex: 0 gauge indicator.

    The secondary reason is the fact that the "natural" tooltip is by default triggered by mousemove, not mouseover, see tooltip.triggerOn; since mousemove will fire after mouseover, the series 0 tooltip will override the series 1 tooltip opened programmatically, and will repeatedly do so on each tiny mouse move.

    The next snippet adds a timeout to the dispatchAction, for the sole purpose of showing what is happening. However, even without the timeout, the tooltip oscillates, and this is not fit for production:

    document.addEventListener("DOMContentLoaded", function() {
    
        const chartUse = echarts.init(document.getElementsByClassName("chart")[0]);
    
        const option = {
    
            tooltip: {
                show: true
            },
    
            series: [
                {
                    type: "gauge",
                    center: ["30%", "50%"],
                    data: [{value: 40}]
                },
                {
                    type: "gauge",
                    center: ["70%", "50%"],
                    data: [{value: 80, itemStyle: {color: "#f00"}}]
                }
            ]
    
        }
    
        chartUse.setOption(option);
    
        chartUse.on("mousemove", {seriesIndex: 0, dataIndex: 0}, function() {
            setTimeout(()=>chartUse.dispatchAction({
                type: "showTip",
                seriesIndex: 1,
                dataIndex: 0
            }), 500);
        })
    
        chartUse.on("mouseout", {seriesIndex: 0, dataIndex: 0}, function() {
            chartUse.dispatchAction({
                type: "hideTip"
            });
        })
    
    });
    .chart {
        width: 100%;
        height: 100vh;
    }
    <div class="chart"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>

    To obtain the desired effect, the original code will work by setting triggerOn: 'click' or triggerOn: 'none' for the tooltip option, with the drawback that the tooltip will now be shown only programmatically (or on click):

    document.addEventListener("DOMContentLoaded", function() {
    
        const chartUse = echarts.init(document.getElementsByClassName("chart")[0]);
    
        const option = {
    
            tooltip: {
                show: true,
                triggerOn: 'none'
            },
    
            series: [
                {
                    type: "gauge",
                    center: ["30%", "50%"],
                    data: [{value: 40}]
                },
                {
                    type: "gauge",
                    center: ["70%", "50%"],
                    data: [{value: 80, itemStyle: {color: "#f00"}}]
                }
            ]
        }
    
        chartUse.setOption(option);
    
        chartUse.on("mouseover", {seriesIndex: 0, dataIndex: 0}, function() {
            chartUse.dispatchAction({
                type: "showTip",
                seriesIndex: 1,
                dataIndex: 0
            });
        });
    
        chartUse.on("mouseout", {seriesIndex: 0, dataIndex: 0}, function() {
            chartUse.dispatchAction({
                type: "hideTip"
            });
        });
    
    });
    .chart {
        width: 100%;
        height: 100vh;
    }
    <div class="chart"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>