apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
60.69k stars 19.62k forks source link

[Bug] 实时曲线,当离开echarts页面打开1~2分钟后,重新回到echart页面查看数据,发现这离开的时段数据不更新或者丢失 #20454

Open lycfr opened 4 weeks ago

lycfr commented 4 weeks ago

Version

4.9.0

Link to Minimal Reproduction

https://jsfiddle.net/coderun/vhxcf2mt/3/

Steps to Reproduce

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Echarts Demo</title>
        <!-- 引入Echarts库 -->
        <script src="https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.min.js"></script>
    </head>
    <body>
        <!-- 用于渲染图表的div -->
        <div id="chart" style="width: 600px; height: 400px;"></div>
        <div id="avg">
            <div id="app_avg">app平均值:</div>
            <div id="system_avg">system平均值:</div>
        </div>
        <div>
            <button onclick="exportData()">获取区间数据</button>
        </div>
        <script>
            // 初始化图表
            var myChart = echarts.init(document.getElementById('chart'));
            // 生成随机数
            function generateRandomValue() {
                return Math.floor(Math.random() * 100);
            }
            // 设置图表的配置项和数据
            var option = {
                title: {
                    name: 'CPU',
                    left: 'center'
                },
                legend: {
                    orient: 'horizontal',
                    x: 'right', //可设定图例在左、右、居中
                    y: 'top', //可设定图例在上、下、居中
                    data: ['Private', 'Real']
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        animation: false
                    },
                },
                xAxis: {
                    type: 'time',
                    axisLabel: {
                        formatter: function(value) {
                            var date = new Date(value);
                            var hours = date.getHours();
                            var minutes = "0" + date.getMinutes();
                            var seconds = "0" + date.getSeconds();
                            return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
                        }
                    }
                },
                yAxis: {
                    type: 'value'
                },
                dataZoom: [{
                        type: 'slider',
                        show: true,
                        xAxisIndex: [0],
                        start: 0,
                        end: 100,
                    },
                    {
                        type: 'inside',
                        show: true,
                        xAxisIndex: [0],
                        start: 0,
                        end: 100,
                    }
                ],
                series: [{
                        name: 'app',
                        data: [],
                        type: 'line',
                    },
                    {
                        name: 'system',
                        data: [],
                        type: 'line'
                    }
                ]
            };
            // 使用配置项和数据显示图表
            myChart.setOption(option);
            let app_data = [];
            let system_data = [];
            let lastUpdateTime = Date.now();

            function updateData(time) {
                var now = time || new Date(); // 使用传入的时间或当前时间
                var app_value = {
                    name: now.toString(),
                    value: [
                        now,
                        generateRandomValue(),
                    ]
                };
                var system_value = {
                    name: now.toString(),
                    value: [
                        now,
                        generateRandomValue(),
                    ]
                };
                app_data.push(app_value);
                system_data.push(system_value);
                myChart.setOption({
                    series: [{
                            name: 'app',
                            data: app_data,
                            type: 'line',
                            markPoint: {
                                data: app_data.length != 0 ? [{
                                        type: 'max',
                                        name: '最大值'
                                    },
                                    {
                                        type: 'min',
                                        name: '最小值'
                                    },
                                    {
                                        type: 'point',
                                        name: '当前值',
                                        value: app_value.value[1],
                                        xAxis: app_value.value[0],
                                        yAxis: app_value.value[1]
                                    }
                                ] : [],
                                label: {
                                    position: 'inside',
                                    formatter: function(param) {
                                        if (param.data.type != 'point') {
                                            return param.data.type + ":" + param.value
                                        }
                                    }
                                }
                            },
                            markLine: {
                                data: [{
                                    type: 'average',
                                    name: '平均值'
                                }],
                                label: {
                                    formatter: function(param) {
                                        return "avg:" + param.value
                                    }
                                }
                            }
                        },
                        {
                            name: 'system',
                            data: system_data,
                            type: 'line',
                            markPoint: {
                                data: system_data.length != 0 ? [{
                                        type: 'max',
                                        name: '最大值'
                                    },
                                    {
                                        type: 'min',
                                        name: '最小值'
                                    },
                                    {
                                        type: 'point',
                                        name: '当前值',
                                        value: system_value.value[1],
                                        xAxis: system_value.value[0],
                                        yAxis: system_value.value[1]
                                    }
                                ] : [],
                                label: {
                                    position: 'inside',
                                    formatter: function(param) {
                                        if (param.data.type != 'point') {
                                            return param.data.type + ":" + param.value
                                        }
                                    }
                                }
                            },
                            markLine: {
                                data: [{
                                    type: 'average',
                                    name: '平均值'
                                }],
                                label: {
                                    formatter: function(param) {
                                        return "avg:" + param.value
                                    }
                                }
                            }
                        }
                    ]
                });
                lastUpdateTime = Date.now();
            }
            // 每秒更新一次数据
            var intervalId = setInterval(updateData, 1000);
            listen_dataZoom(myChart);

            function listen_dataZoom(chart) {
                chart.on('dataZoom', function(params) {
                    let startIndex = Math.floor(params.start * chart.getOption().series[0].data.length / 100);
                    let endIndex = Math.floor(params.end * chart.getOption().series[0].data.length / 100);
                    chart.getOption().series.forEach(function(series) {
                        let sum = 0;
                        let count = endIndex - startIndex;
                        for (var i = startIndex; i < endIndex; i++) {
                            sum += series.data[i].value[1];
                        }
                        let avg = sum / count;
                        if (series.name === 'app') {
                            app_avg.innerHTML = "app平均值:" + avg.toFixed(2);
                        } else if (series.name === 'system') {
                            system_avg.innerHTML = "system平均值:" + avg.toFixed(2);
                        }
                    })
                });
            };
            // 当页面获得和失去焦点时保存和恢复数据
            document.addEventListener('visibilitychange', function () {
                if (document.hidden) {
                    localStorage.setItem('echartsData', JSON.stringify(data));
                } else {
                    var savedData = JSON.parse(localStorage.getItem('echartsData'));
                    if (savedData) {
                        data = savedData;
                        myChart.setOption({
                            series: [{
                                data: data
                            }]
                        });
                    }
                }
            });
        </script>
    </body>
</html>
image

Current Behavior

离开页面后,数据丢失

Expected Behavior

程序还在运行,数据应该还可以持续加载

Environment

- OS:
- Browser:
- Framework:

Any additional comments?

No response

echarts-bot[bot] commented 4 weeks ago

@lycfr It seems you are not using English, I've helped translate the content automatically. To make your issue understood by more people and get helped, we'd like to suggest using English next time. 🤗

TRANSLATED
**TITLE** [Bug] Real-time curve, when you leave the echarts page and open it for 1~2 minutes, you go back to the echart page to view the data, and find that the data of the left period is not updated or lost **BODY** ### Version 4.9.0 ### Link to Minimal Reproduction https://jsfiddle.net/coderun/vhxcf2mt/3/ ### Steps to Reproduce ``` Echarts Demo
app average:
system average:
``` image ### Current Behavior Data is lost after leaving the page ### Expected Behavior The program is still running and the data should continue to load. ### Environment ```markdown -OS: -Browser: - Framework: ``` ### Any additional comments? _No response_
Ovilia commented 3 weeks ago

This doesn't seem to be a problem related to ECharts. Make sure the x value is as expected and ECharts should render the data passed in.

lycfr commented 3 weeks ago

这个离开了页面,像是生命周期停止了,重新渲染了,数据又恢复,但是中间数据就丢失没了

helgasoft commented 2 weeks ago

@lycfr, apparently browsers stop executing scripts in inactive tabs, see this. To keep your script alive in Chrome, there are at least 3 options :

jm821323 commented 2 weeks ago

请问这个问题解决了吗?我也遇到了这个问题,echarts的数据通过WebScoket实时数据,浏览器最小化以后几分钟再回到页面,数据是不正常的。