本文作者:咔咔

JS实时画走势图怎么做?

咔咔 2025-11-30 2 抢沙发
JS实时画走势图怎么做?摘要: 核心概念无论使用哪种库,实现实时走势图的核心逻辑都是一样的:数据源: 你需要一个提供实时数据的地方,这可以是一个 WebSocket 连接、Server-Sent Events (...

核心概念

无论使用哪种库,实现实时走势图的核心逻辑都是一样的:

  1. 数据源: 你需要一个提供实时数据的地方,这可以是一个 WebSocket 连接、Server-Sent Events (SSE)、或通过定时器 (setInterval) 模拟的 API 轮询。
  2. 数据存储: 你需要一个地方来存储图表的数据,通常是一个数组,它会随着新数据的到来而不断更新。
  3. 图表库: 你需要一个 JavaScript 库来将数据可视化,我们重点介绍最流行的几个。
  4. 更新机制: 当新数据到达时,你需要更新图表,这通常意味着:
    • 追加数据: 将新数据点添加到数据数组的末尾。
    • 移除旧数据: 为了防止数组无限增长,你需要移除最旧的数据点(只保留最新的 100 个点)。
    • 重绘图表: 通知图表库使用新的数据集重新渲染。

使用 ECharts (推荐,功能强大,生态完善)

ECharts 是百度开源的一个非常强大的可视化库,它功能全面,配置灵活,非常适合复杂的图表需求。

JS实时画走势图怎么做?
(图片来源网络,侵删)

准备工作

在 HTML 中引入 ECharts 的库文件。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">ECharts 实时走势图</title>
    <!-- 引入 ECharts 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
    <div id="main" style="width: 800px;height:400px;"></div>
    <script src="app.js"></script>
</body>
</html>

实现代码 (app.js)

我们将模拟一个 WebSocket 数据源,并实现图表的实时更新。

// 1. 初始化图表
const chartDom = document.getElementById('main');
const myChart = echarts.init(chartDom);
let option;
// 2. 准备数据
const dataX = []; // X轴数据 (时间)
const dataY = []; // Y轴数据 (数值)
const maxDataPoints = 50; // 最多显示的数据点数量
// 3. 模拟实时数据源 (这里用 setInterval 模拟 WebSocket)
// 在实际应用中,这里会是 WebSocket.onmessage 或 SSE.onmessage
function generateData() {
    const now = new Date();
    const timeStr = now.toLocaleTimeString(); // 获取当前时间字符串
    const value = Math.random() * 100; // 生成一个随机值
    // 追加新数据
    dataX.push(timeStr);
    dataY.push(value);
    // 移除旧数据,保持数据点数量恒定
    if (dataX.length > maxDataPoints) {
        dataX.shift();
        dataY.shift();
    }
    // 更新图表配置
    option = {
        title: {
            text: '实时数据走势图'
        },
        tooltip: {
            trigger: 'axis'
        },
        xAxis: {
            type: 'category',
            data: dataX,
            boundaryGap: false // 去除轴间距,使线条穿过
        },
        yAxis: {
            type: 'value',
            boundaryGap: [0, '10%'] // Y轴留出10%的空间
        },
        series: [{
            name: '数据值',
            type: 'line', // 折线图
            data: dataY,
            smooth: true, // 平滑曲线
            symbol: 'none', // 去掉数据点上的小圆点
            areaStyle: { // 填充区域
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    { offset: 0, color: 'rgba(128, 255, 165, 0.3)' },
                    { offset: 1, color: 'rgba(1, 191, 236, 0.1)' }
                ])
            }
        }]
    };
    // 4. 使用新数据更新图表
    myChart.setOption(option);
}
// 初始化时先画一次
generateData();
// 设置定时器,每隔 1 秒生成一次新数据
setInterval(generateData, 1000);
// 确保在窗口大小改变时,图表也能自适应
window.addEventListener('resize', () => {
    myChart.resize();
});

使用 Chart.js (轻量级,易于上手)

Chart.js 是另一个非常流行的库,以其轻量级和易用性著称。

准备工作

引入 Chart.js 库。

JS实时画走势图怎么做?
(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">Chart.js 实时走势图</title>
    <!-- 引入 Chart.js 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <canvas id="myChart" width="800" height="400"></canvas>
    <script src="app-chart.js"></script>
</body>
</html>

实现代码 (app-chart.js)

// 1. 获取 canvas 上下文
const ctx = document.getElementById('myChart').getContext('2d');
// 2. 初始化图表
const myChart = new Chart(ctx, {
    type: 'line', // 图表类型
    data: {
        labels: [], // X轴标签 (时间)
        datasets: [{
            label: '实时数据',
            data: [], // Y轴数据 (数值)
            borderColor: 'rgb(75, 192, 192)',
            backgroundColor: 'rgba(75, 192, 192, 0.2)',
            tension: 0.4, // 使线条平滑
            fill: true // 填充线下区域
        }]
    },
    options: {
        responsive: true, // 响应式
        scales: {
            y: {
                beginAtZero: true // Y轴从0开始
            }
        },
        animation: {
            duration: 0 // 关闭动画,使更新更流畅
        }
    }
});
// 3. 模拟实时数据源
const maxDataPoints = 50;
function updateChart() {
    const now = new Date();
    const timeStr = now.toLocaleTimeString();
    const newValue = Math.random() * 100;
    // 更新数据
    myChart.data.labels.push(timeStr);
    myChart.data.datasets[0].data.push(newValue);
    // 移除旧数据
    if (myChart.data.labels.length > maxDataPoints) {
        myChart.data.labels.shift();
        myChart.data.datasets[0].data.shift();
    }
    // 4. 更新图表
    myChart.update('none'); // 'none' 模式可以不触发动画,性能更好
}
// 初始化时先画一次
updateChart();
// 设置定时器
setInterval(updateChart, 1000);

使用原生 Canvas (性能极致,但复杂度高)

如果你的应用对性能有极致要求,并且图表非常简单,可以考虑使用原生 Canvas API,这种方式不依赖任何第三方库,但所有逻辑都需要自己实现。

准备工作

一个 <canvas> 元素。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">原生 Canvas 实时走势图</title>
    <style>
        canvas { border: 1px solid #ccc; }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="800" height="400"></canvas>
    <script src="app-native.js"></script>
</body>
</html>

实现代码 (app-native.js)

这个实现稍微复杂一些,需要处理坐标转换、绘制坐标轴、绘制线条等。

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const maxDataPoints = 50;
const data = [];
// 绘制函数
function drawChart() {
    // 清空画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    // 设置样式
    ctx.strokeStyle = '#007bff';
    ctx.lineWidth = 2;
    ctx.fillStyle = 'rgba(0, 123, 255, 0.1)';
    ctx.beginPath();
    // 如果没有数据,则不绘制
    if (data.length === 0) return;
    const padding = 40; // 内边距
    const chartWidth = canvas.width - 2 * padding;
    const chartHeight = canvas.height - 2 * padding;
    // 找出数据范围
    const maxValue = Math.max(...data);
    const minValue = Math.min(...data);
    const valueRange = maxValue - minValue || 1; // 避免除以0
    // 绘制数据点和连线
    data.forEach((value, index) => {
        const x = padding + (index / (maxDataPoints - 1)) * chartWidth;
        // Y轴需要翻转,因为canvas的Y轴向下
        const y = padding + chartHeight - ((value - minValue) / valueRange) * chartHeight;
        if (index === 0) {
            ctx.moveTo(x, y);
        } else {
            ctx.lineTo(x, y);
        }
    });
    // 绘制线条
    ctx.stroke();
    // 绘制填充区域
    ctx.lineTo(padding + chartWidth, padding + chartHeight);
    ctx.lineTo(padding, padding + chartHeight);
    ctx.closePath();
    ctx.fill();
    // (可选) 绘制坐标轴和标签
    ctx.fillStyle = 'black';
    ctx.font = '12px Arial';
    ctx.fillText(`Max: ${maxValue.toFixed(2)}`, padding, padding - 10);
    ctx.fillText(`Min: ${minValue.toFixed(2)}`, padding, canvas.height - padding + 20);
}
// 模拟数据源
function addData() {
    const newValue = Math.random() * 100;
    data.push(newValue);
    if (data.length > maxDataPoints) {
        data.shift();
    }
    drawChart();
}
// 初始化
addData();
// 定时更新
setInterval(addData, 1000);

如何连接真实数据源?

上面的例子都使用了 setInterval 来模拟数据,在实际项目中,你通常会使用 WebSocket 或 SSE。

WebSocket 示例

假设你有一个 WebSocket 服务器,它在每次有新数据时都会推送消息。

// 在 ECharts 或 Chart.js 的代码中,替换 setInterval 部分
// 1. 创建 WebSocket 连接
const socket = new WebSocket('wss://your-websocket-server.com');
// 2. 连接打开后
socket.onopen = function(event) {
    console.log('WebSocket 连接已建立!');
};
// 3. 接收消息
socket.onmessage = function(event) {
    // event.data 是服务器推送的数据,通常是 JSON 字符串
    const newData = JSON.parse(event.data);
    // 假设 newData 是 { time: '10:00:01', value: 55.5 }
    const timeStr = newData.time;
    const value = newData.value;
    // --- 以下是更新图表的逻辑,与之前完全相同 ---
    dataX.push(timeStr);
    dataY.push(value);
    if (dataX.length > maxDataPoints) {
        dataX.shift();
        dataY.shift();
    }
    myChart.setOption(option); // 或 myChart.update();
};
// 4. 处理错误
socket.onerror = function(error) {
    console.error('WebSocket 错误:', error);
};
// 5. 连接关闭
socket.onclose = function(event) {
    if (event.wasClean) {
        console.log(`WebSocket 连接正常关闭,代码=${event.code} 原因=${event.reason}`);
    } else {
        console.error('WebSocket 连接被异常中断');
    }
};

总结与选择

特性 ECharts Chart.js 原生 Canvas
易用性 中等,配置项多 ,非常直观 ,需要自己实现所有逻辑
功能丰富度 极高,支持各种复杂图表、3D、地图等 高,能满足大部分需求 仅限你实现的功能
性能 良好 良好 极高,无任何库开销
生态/文档 非常完善,社区活跃 非常完善,社区活跃 依赖 MDN 和自身经验
适用场景 专业数据可视化、复杂图表、报表 快速开发、中小型项目、对性能要求不极致的场景 游戏渲染、超高性能要求、定制化极高的场景

给你的建议:

  • 绝大多数情况下,首选 ECharts。 它功能强大,文档齐全,能满足你几乎所有的需求,是专业开发者的首选。
  • 如果你的项目很简单,或者你希望快速集成,Chart.js 是一个很好的选择
  • 只有在确认性能是瓶颈,并且你愿意投入更多开发时间时,才考虑使用 原生 Canvas
文章版权及转载声明

作者:咔咔本文地址:https://jits.cn/content/19025.html发布于 2025-11-30
文章转载或复制请以超链接形式并注明出处杰思科技・AI 股讯

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,2人围观)参与讨论

还没有评论,来说两句吧...