1、x轴和数据都动态增加
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>股票折线图-无缝衔接11:30和13:00</title>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<style>
body { margin: 0; padding: 20px; }
#stock-chart {
width: 100%;
min-width: 800px;
height: 600px;
border: 1px solid #eee;
box-sizing: border-box;
}
</style>
</head>
<body>
<h2 style="text-align: center;">股票实时行情(无缝衔接午间休市)</h2>
<div id="stock-chart"></div>
<script>
// 检查ECharts加载
if (typeof echarts === 'undefined') {
alert('ECharts加载失败,请检查网络!');
}
// 初始化图表
const myChart = echarts.init(document.getElementById('stock-chart'));
// 基础配置
const option = {
title: {
text: '股票实时行情(9:30-11:30/13:00-15:00)',
left: 'center'
},
tooltip: {
trigger: 'axis',
formatter: (params) => {
// 提示框显示真实时间和价格
const realTime = params[0].data[2]; // 第三个值存真实时间字符串
return `${realTime}<br/>价格:${params[0].data[1].toFixed(2)}元`;
}
},
grid: {
left: '5%', right: '5%', top: '15%', bottom: '10%', containLabel: true
},
xAxis: {
type: 'category', // 改用分类轴,手动控制显示
name: '交易时间',
axisLabel: { fontSize: 11 },
data: [] // 存储显示用的时间标签(真实时间)
},
yAxis: {
type: 'value',
name: '价格(元)',
min: 95,
max: 105
},
series: [{
name: '股价',
type: 'line',
smooth: true,
lineStyle: { width: 2 },
data: [] // [虚拟索引, 价格, 真实时间字符串]
}]
};
myChart.setOption(option);
// ========== 核心:时间映射与数据生成 ==========
class StockSimulator {
constructor() {
this.basePrice = 100;
this.currentPrice = this.basePrice;
// 生成所有真实交易时间点(9:30-11:30, 13:00-15:00)
this.realTimePoints = this.generateRealTimePoints();
// 虚拟时间轴(连续的索引,对应X轴的分类)
this.virtualTimeIndex = 0;
// 存储处理后的数据
this.chartData = [];
this.xAxisLabels = [];
this.timer = null;
}
// 生成所有真实的交易时间点(分钟级)
generateRealTimePoints() {
const timePoints = [];
// 上午:9:30-11:30
for (let h = 9; h <= 11; h++) {
const startMin = h === 9 ? 30 : 0;
const endMin = h === 11 ? 31 : 60; // 11:30包含,11:31停止
for (let m = startMin; m < endMin; m++) {
const timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
timePoints.push(timeStr);
}
}
// 下午:13:00-15:00
for (let h = 13; h < 15; h++) {
for (let m = 0; m < 60; m++) {
const timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
timePoints.push(timeStr);
}
}
// 15:00最后一个点
timePoints.push('15:00');
return timePoints;
}
// 生成随机股价
generatePrice() {
const randomChange = (Math.random() - 0.5) * 0.8;
this.currentPrice = Math.max(95, Math.min(105, this.currentPrice + randomChange));
return this.currentPrice;
}
// 启动动态更新
startUpdate() {
this.timer = setInterval(() => {
// 停止条件:所有时间点更新完毕
if (this.virtualTimeIndex >= this.realTimePoints.length) {
clearInterval(this.timer);
alert('今日交易结束!');
return;
}
// 获取当前真实时间点
const realTime = this.realTimePoints[this.virtualTimeIndex];
// 生成价格
const price = this.generatePrice();
// 添加到数据数组:[虚拟索引, 价格, 真实时间]
this.chartData.push([this.virtualTimeIndex, price, realTime]);
// 添加X轴显示标签(真实时间)
this.xAxisLabels.push(realTime);
// 每10个点显示一个标签,避免X轴文字拥挤
const showLabelXAxis = this.xAxisLabels.map((label, idx) => {
return idx % 10 === 0 ? label : '';
});
// 更新图表
myChart.setOption({
xAxis: { data: showLabelXAxis },
series: [{ data: this.chartData }]
});
// 推进虚拟索引
this.virtualTimeIndex++;
}, 200); // 200ms更新一次,更快看到效果
}
}
// 启动模拟
window.onload = function() {
const simulator = new StockSimulator();
simulator.startUpdate();
};
// 窗口自适应
window.addEventListener('resize', () => myChart.resize());
</script>
</body>
</html>
2、x轴时间固定,数据动态前进,只是11:30 到 13:00 出现数据空白 比较突兀
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>股票实时行情-可正常显示版</title>
<!-- 更换为更稳定的ECharts CDN -->
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<style>
/* 强制设置容器尺寸,避免布局问题 */
body {
margin: 0;
padding: 20px;
}
#stock-chart {
width: 100%;
min-width: 800px;
height: 600px;
border: 1px solid #eee; /* 加边框,确认容器存在 */
box-sizing: border-box;
}
</style>
</head>
<body>
<h2 style="text-align: center;">股票实时行情模拟</h2>
<div id="stock-chart"></div>
<script>
// 第一步:先确认ECharts是否加载成功
if (typeof echarts === 'undefined') {
alert('ECharts加载失败,请检查网络或CDN链接!');
}
// 初始化图表(增加异常捕获)
let myChart;
try {
const chartDom = document.getElementById('stock-chart');
// 打印容器尺寸,调试用
console.log('容器尺寸:', chartDom.offsetWidth, chartDom.offsetHeight);
myChart = echarts.init(chartDom);
} catch (e) {
alert('图表初始化失败:' + e.message);
}
// 基础配置(简化+确保必选属性)
const option = {
title: {
text: '股票实时行情(9:30-11:30/13:00-15:00)',
left: 'center',
textStyle: { fontSize: 16 }
},
tooltip: {
trigger: 'axis',
// 简化提示框格式化
formatter: (params) => {
const time = new Date(params[0].data[0]);
const timeStr = `${time.getHours().toString().padStart(2, '0')}:${time.getMinutes().toString().padStart(2, '0')}`;
return `${timeStr}<br/>价格:${params[0].data[1].toFixed(2)}元`;
}
},
grid: {
left: '5%',
right: '5%',
top: '15%',
bottom: '10%',
containLabel: true
},
xAxis: {
type: 'time',
name: '交易时间',
nameTextStyle: { fontSize: 12 },
axisLabel: {
fontSize: 11,
formatter: (val) => {
const t = new Date(val);
return `${t.getHours()}:${t.getMinutes().toString().padStart(2, '0')}`;
}
},
// 固定时间范围,避免动态时间问题
min: new Date(2026, 1, 27, 9, 30).getTime(), // 固定日期(2026-02-27)
max: new Date(2026, 1, 27, 15, 0).getTime()
},
yAxis: {
type: 'value',
name: '价格(元)',
nameTextStyle: { fontSize: 12 },
// 固定Y轴范围,避免初始无数据时轴消失
min: 95,
max: 105
},
series: [{
name: '股价',
type: 'line',
smooth: true,
connectNulls: false,
lineStyle: { width: 2 }, // 加粗折线,更易看到
data: []
}]
};
// 先渲染基础图表(无数据也显示框架)
myChart.setOption(option);
// ========== 数据生成与动态更新 ==========
class StockSimulator {
constructor() {
this.basePrice = 100;
this.currentPrice = this.basePrice;
// 固定起始时间(避免系统时间导致的问题)
this.currentTime = new Date(2026, 1, 27, 9, 30);
this.chartData = [];
this.timer = null;
}
// 判断是否为交易时间
isTradingTime(time) {
const hour = time.getHours();
const minute = time.getMinutes();
return (hour >= 9 && hour < 11) || (hour === 11 && minute <= 30) || (hour >= 13 && hour < 15);
}
// 生成下一个价格(简化波动逻辑)
generateNextPrice() {
const randomChange = (Math.random() - 0.5) * 0.8; // 小幅波动
this.currentPrice = Math.max(95, Math.min(105, this.currentPrice + randomChange)); // 限制在95-105之间
return this.currentPrice;
}
// 推进时间
advanceTime() {
this.currentTime.setMinutes(this.currentTime.getMinutes() + 1);
// 跳过休市时间
if (this.currentTime.getHours() === 11 && this.currentTime.getMinutes() > 30) {
this.currentTime.setHours(13, 0);
}
}
// 启动更新
startUpdate() {
// 先添加第一个数据点,确保初始有数据
const firstPrice = this.generateNextPrice();
this.chartData.push([this.currentTime.getTime(), firstPrice]);
myChart.setOption({ series: [{ data: this.chartData }] });
// 定时器:每300ms更新一次(更快看到效果)
this.timer = setInterval(() => {
if (this.currentTime.getHours() >= 15) {
clearInterval(this.timer);
alert('今日交易结束!');
return;
}
this.advanceTime();
if (this.isTradingTime(this.currentTime)) {
const price = this.generateNextPrice();
this.chartData.push([this.currentTime.getTime(), price]);
// 增量更新
myChart.setOption({ series: [{ data: this.chartData }] });
}
}, 300);
}
}
// 启动模拟(确保DOM加载完成后执行)
window.onload = function() {
const simulator = new StockSimulator();
simulator.startUpdate();
};
// 窗口自适应
window.addEventListener('resize', () => {
if (myChart) myChart.resize();
});
</script>
</body>
</html>
3、x轴固定,上午休市,下午开市显示一起的
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>固定X轴-动态生成股价数据(11:30/13:00显示)</title>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<style>
body { margin: 0; padding: 20px; }
#stock-chart {
width: 100%;
min-width: 800px;
height: 600px;
border: 1px solid #eee;
box-sizing: border-box;
}
</style>
</head>
<body>
<h2 style="text-align: center;">股票实时行情(固定X轴+动态数据)</h2>
<div id="stock-chart"></div>
<script>
// 检查ECharts加载
if (typeof echarts === 'undefined') {
alert('ECharts加载失败,请检查网络!');
}
// 初始化图表
const myChart = echarts.init(document.getElementById('stock-chart'));
// ========== 1. 预先生成完整的X轴标签(固定显示) ==========
function generateFullXAxisLabels() {
const labels = [];
// 上午:9:30-11:30
for (let h = 9; h <= 11; h++) {
const startMin = h === 9 ? 30 : 0;
const endMin = h === 11 ? 31 : 60; // 包含11:30
for (let m = startMin; m < endMin; m++) {
let timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
// 关键修改:将11:30的标签改为 "11:30/13:00"
if (h === 11 && m === 30) {
timeStr = '11:30/13:00';
}
labels.push(timeStr);
}
}
// 下午:13:00-15:00
for (let h = 13; h < 15; h++) {
for (let m = 0; m < 60; m++) {
const timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
labels.push(timeStr);
}
}
// 最后添加15:00
labels.push('15:00');
return labels;
}
// 生成完整的X轴标签(固定)
const fullXAxisLabels = generateFullXAxisLabels();
// 初始化数据数组:所有位置先填null(空数据)
let chartData = new Array(fullXAxisLabels.length).fill(null);
// ========== 2. 图表基础配置(X轴固定) ==========
const option = {
title: {
text: '股票实时行情(9:30–11:30/13:00–15:00)',
left: 'center'
},
tooltip: {
trigger: 'axis',
formatter: (params) => {
const time = params[0].axisValue;
const price = params[0].data === null ? '无数据' : params[0].data.toFixed(2);
return `${time}<br/>价格:${price}元`;
}
},
grid: {
left: '5%', right: '5%', top: '15%', bottom: '10%', containLabel: true
},
xAxis: {
type: 'category',
name: '交易时间',
axisLabel: {
fontSize: 11,
// 每10个标签显示一次,避免拥挤
interval: (index, value) => {
// 强制显示"11:30/13:00"这个关键标签
if (value === '11:30/13:00') return true;
return index % 10 === 0;
}
},
// 固定X轴标签,不随数据变化
data: fullXAxisLabels,
// 强制X轴显示完整,不自动缩放
boundaryGap: false
},
yAxis: {
type: 'value',
name: '价格(元)',
min: 95,
max: 105
},
series: [{
name: '股价',
type: 'line',
smooth: true,
lineStyle: { width: 2 },
// 空数据不连接
connectNulls: false,
// 初始数据全为null
data: chartData
}]
};
// 初始化图表(X轴已固定显示)
myChart.setOption(option);
// ========== 3. 动态生成股价数据 ==========
class StockSimulator {
constructor() {
this.basePrice = 100;
this.currentPrice = this.basePrice;
this.currentIndex = 0; // 当前更新到的X轴索引
this.timer = null;
}
// 生成下一个价格
generatePrice() {
const randomChange = (Math.random() - 0.5) * 0.8;
this.currentPrice = Math.max(95, Math.min(105, this.currentPrice + randomChange));
return this.currentPrice;
}
// 启动动态更新
startUpdate() {
this.timer = setInterval(() => {
// 停止条件:更新完所有数据点
if (this.currentIndex >= fullXAxisLabels.length) {
clearInterval(this.timer);
alert('今日交易结束!');
return;
}
// 生成当前索引的价格数据
const price = this.generatePrice();
// 填充到数据数组对应位置
chartData[this.currentIndex] = price;
// 只更新数据,X轴保持不变
myChart.setOption({
series: [{
data: chartData
}]
});
// 推进索引
this.currentIndex++;
}, 200); // 200ms更新一个数据点
}
}
// 启动模拟(DOM加载完成后执行)
window.onload = function() {
const simulator = new StockSimulator();
simulator.startUpdate();
};
// 窗口自适应
window.addEventListener('resize', () => myChart.resize());
</script>
</body>
</html>
建议第3种实现方式,也是一些股票交易平台使用的显示方式。