ECharts 如何实现 CPU 占用率的显示效果?

请问如何用 ECharts 实现这种图表慢慢向左移动的效果?

image.png

上如是 Chrome 开发工具 Monotor 的效果,我想用 ECharts 实现类似的效果,但是效果不理想。

谢谢。

阅读 339
avatarAI BotBETA

解决方案代码:

let baseTime = Date.now();
let data = [];

// 初始化图表
let chart = echarts.init(document.getElementById('main'));

// 配置项
let option = {
  xAxis: {
    type: 'value',
    min: 0,
    max: 10,
    show: false // 隐藏x轴
  },
  yAxis: {
    type: 'value',
    min: 0,
    max: 100,
    splitLine: { show: false } // 隐藏网格线
  },
  series: [{
    type: 'line',
    smooth: true,
    areaStyle: {
      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
        offset: 0, color: 'rgba(75, 162, 246, 0.6)'
      }, {
        offset: 1, color: 'rgba(75, 162, 246, 0.1)'
      }])
    },
    data: data
  }],
  animationDuration: 300, // 过渡动画时长
  animationEasing: 'linear'
};

// 实时更新函数
setInterval(() => {
  // 生成新数据(模拟CPU占用率)
  let newValue = Math.random() * 80 + 20;
  let timestamp = Date.now() - baseTime;
  
  // 保持数据长度(控制显示窗口)
  if (data.length > 50) {
    data.shift();
  }
  data.push([timestamp, newValue]);

  // 动态调整x轴范围(关键移动效果)
  option.xAxis.min = timestamp - 10000; // 10秒时间窗口
  option.xAxis.max = timestamp;
  
  chart.setOption(option);
}, 200); // 每200ms更新一次

实现原理说明:

  1. 动态数据更新机制
  2. 使用队列结构维护最近50个数据点(shift()移除旧数据,push()新增数据)
  3. 通过setInterval定时器模拟实时数据更新(实际使用时替换为真实数据源)
  4. 关键移动效果实现
  5. x轴使用时间戳作为坐标(需转换为相对时间)
  6. 每次更新时动态计算x轴范围(min/max),保持固定时间窗口
  7. 设置animationDuration: 300实现平滑过渡效果
  8. 视觉优化技巧
  9. 隐藏坐标轴和网格线(show: false)
  10. 使用渐变填充区域(areaStyle)
  11. 开启曲线平滑(smooth: true)

调试建议:

  1. 调整setInterval间隔(200ms)控制刷新频率
  2. 修改xAxis.min/max计算值改变时间窗口长度
  3. 通过修改data数组长度(50)控制显示数据密度

与Chrome Monitor的差异处理:

  1. 添加渐变背景增强层次感
  2. 建议设置grid布局去除边距:

    grid: {
      top: 0,
      right: 0,
      bottom: 0,
      left: 0
    }
2 个回答
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>CPU占用率监控</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
    <style>
        body {
            margin: 0;
            font-family: "Microsoft YaHei", sans-serif;
        }
        .container {
            display: flex;
            flex-direction: column;
            max-width: 1200px;
            margin: 20px auto;
            gap: 20px;
        }
        .header {
            text-align: center;
            margin-bottom: 10px;
        }
        .chart-row {
            display: flex;
            gap: 20px;
            flex-wrap: wrap;
        }
        .chart-container {
            flex: 1;
            min-width: 300px;
            height: 350px;
            border-radius: 8px;
            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
            padding: 10px;
            background-color: #fff;
        }
        #cpu-gauge {
            height: 350px;
        }
        #cpu-line {
            height: 350px;
        }
        #cpu-cores {
            height: 350px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>CPU占用率监控仪表盘</h1>
            <p>模拟数据实时展示</p>
        </div>
        
        <div class="chart-row">
            <div class="chart-container">
                <div id="cpu-gauge"></div>
            </div>
            <div class="chart-container">
                <div id="cpu-line"></div>
            </div>
        </div>
        
        <div class="chart-container">
            <div id="cpu-cores"></div>
        </div>
    </div>

    <script>
        // 初始化图表实例
        const gaugeChart = echarts.init(document.getElementById('cpu-gauge'));
        const lineChart = echarts.init(document.getElementById('cpu-line'));
        const coresChart = echarts.init(document.getElementById('cpu-cores'));
        
        // 仪表盘配置
        const gaugeOption = {
            title: {
                text: 'CPU总体使用率',
                left: 'center'
            },
            series: [{
                type: 'gauge',
                progress: {
                    show: true,
                    width: 18
                },
                axisLine: {
                    lineStyle: {
                        width: 18,
                        color: [
                            [0.3, '#67e0e3'],
                            [0.7, '#37a2da'],
                            [1, '#fd666d']
                        ]
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    length: 15,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 25,
                    color: '#999',
                    fontSize: 12
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 25,
                    itemStyle: {
                        borderWidth: 10
                    }
                },
                detail: {
                    valueAnimation: true,
                    formatter: '{value}%',
                    color: '#333',
                    fontSize: 30
                },
                data: [{
                    value: 0
                }]
            }]
        };
        
        // 折线图配置
        const lineOption = {
            title: {
                text: 'CPU使用率趋势',
                left: 'center'
            },
            tooltip: {
                trigger: 'axis'
            },
            xAxis: {
                type: 'category',
                data: [],
                boundaryGap: false
            },
            yAxis: {
                type: 'value',
                min: 0,
                max: 100,
                name: '使用率(%)'
            },
            series: [{
                name: 'CPU使用率',
                type: 'line',
                smooth: true,
                data: [],
                areaStyle: {
                    color: {
                        type: 'linear',
                        x: 0,
                        y: 0,
                        x2: 0,
                        y2: 1,
                        colorStops: [{
                            offset: 0,
                            color: 'rgba(58, 162, 235, 0.5)'
                        }, {
                            offset: 1,
                            color: 'rgba(58, 162, 235, 0.1)'
                        }]
                    }
                },
                itemStyle: {
                    color: '#3a82eb'
                }
            }]
        };
        
        // 多核心CPU使用率
        const coresOption = {
            title: {
                text: '各CPU核心使用率',
                left: 'center'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                data: ['已使用', '空闲'],
                top: 30
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                top: '70px',
                containLabel: true
            },
            xAxis: {
                type: 'value',
                max: 100,
                name: '使用率(%)'
            },
            yAxis: {
                type: 'category',
                data: ['核心1', '核心2', '核心3', '核心4', '核心5', '核心6', '核心7', '核心8']
            },
            series: [
                {
                    name: '已使用',
                    type: 'bar',
                    stack: 'total',
                    itemStyle: {
                        color: '#5470c6'
                    },
                    label: {
                        show: true,
                        formatter: '{c}%'
                    },
                    data: [0, 0, 0, 0, 0, 0, 0, 0]
                },
                {
                    name: '空闲',
                    type: 'bar',
                    stack: 'total',
                    itemStyle: {
                        color: '#91cc75'
                    },
                    label: {
                        show: true,
                        formatter: '{c}%'
                    },
                    data: [100, 100, 100, 100, 100, 100, 100, 100]
                }
            ]
        };
        
        // 应用图表配置
        gaugeChart.setOption(gaugeOption);
        lineChart.setOption(lineOption);
        coresChart.setOption(coresOption);
        
        // 时间数据
        const timeData = [];
        const cpuData = [];
        let currentTime = new Date();
        
        // 模拟数据更新函数
        function updateData() {
            // 生成随机CPU使用率
            const cpuValue = Math.floor(Math.random() * 45) + 20; // 20-65%范围
            
            // 更新仪表盘
            gaugeChart.setOption({
                series: [{
                    data: [{
                        value: cpuValue
                    }]
                }]
            });
            
            // 更新时间和数据数组
            currentTime = new Date();
            const timeStr = currentTime.getHours() + ':' + 
                            (currentTime.getMinutes() < 10 ? '0' + currentTime.getMinutes() : currentTime.getMinutes()) + ':' + 
                            (currentTime.getSeconds() < 10 ? '0' + currentTime.getSeconds() : currentTime.getSeconds());
            
            timeData.push(timeStr);
            cpuData.push(cpuValue);
            
            // 保持数据长度为20
            if (timeData.length > 20) {
                timeData.shift();
                cpuData.shift();
            }
            
            // 更新折线图
            lineChart.setOption({
                xAxis: {
                    data: timeData
                },
                series: [{
                    data: cpuData
                }]
            });
            
            // 更新各核心数据
            const coreUsages = [];
            const coreIdles = [];
            
            for (let i = 0; i < 8; i++) {
                const usage = Math.floor(Math.random() * 60) + 10; // 10-70%范围
                coreUsages.push(usage);
                coreIdles.push(100 - usage);
            }
            
            coresChart.setOption({
                series: [
                    {
                        data: coreUsages
                    },
                    {
                        data: coreIdles
                    }
                ]
            });
        }
        
        // 初始更新
        updateData();
        
        // 定时更新数据(2秒一次)
        setInterval(updateData, 2000);
        
        // 响应窗口大小变化
        window.addEventListener('resize', function() {
            gaugeChart.resize();
            lineChart.resize();
            coresChart.resize();
        });
    </script>
</body>
</html>

保存为 cpu.html 浏览器打开可以直接看到效果

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏