下面我将为您介绍如何使用 KLineChart 库生成一个股票K线图 Demo,并提供完整的代码示例和关键步骤说明。
🧰 准备工作
首先需要引入必要的 JavaScript 库,并准备好 StockTV API 密钥。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>StockTV K线图实战Demo</title>
<!-- 引入KLineChart库 -->
<script src="https://cdn.dolphindb.cn/vendors/klinecharts/dist/umd/klinecharts.min.js"></script>
</head>
<body>
<div id="k-line-chart" style="height: 600px; width: 100%;"></div>
<script>
// 配置参数
const API_KEY = 'YOUR_API_KEY_HERE'; // 请替换为你的真实API密钥
const API_BASE = 'https://api.stocktv.top';
// 你的代码将在这里编写
</script>
</body>
</html>
📡 获取股票K线数据
通过 StockTV API 获取股票数据需要两个步骤:先获取股票唯一ID,再请求K线数据。
// 配置股票参数
const symbol = 'AAPL'; // 股票代码
const interval = 'P1D'; // K线周期:日线
async function fetchKLineData() {
try {
// 1. 根据股票代码查询其唯一产品ID (pid)
const listUrl = `${
API_BASE}/stock/stocks?countryId=1&symbol=${
symbol}&key=${
API_KEY}`;
const listResponse = await fetch(listUrl);
const listData = await listResponse.json();
if (listData.code !== 200 || listData.data.length === 0) {
console.error('未找到该股票:', listData.message);
return;
}
const stockPid = listData.data[0].id; // 获取股票的pid
// 2. 使用pid请求历史K线数据
const klineUrl = `${
API_BASE}/stock/kline?pid=${
stockPid}&interval=${
interval}&key=${
API_KEY}`;
const klineResponse = await fetch(klineUrl);
const klineData = await klineResponse.json();
if (klineData.code === 200) {
return klineData.data; // 返回数据用于绘图
} else {
console.error('获取K线数据失败:', klineData.message);
return null;
}
} catch (error) {
console.error('请求失败:', error);
return null;
}
}
⚙️ 初始化K线图表与数据转换
获取到数据后,需要将其转换为 KLineChart 可识别的格式并初始化图表。
// 初始化K线图容器
const chart = klinecharts.init('k-line-chart');
async function initChart() {
const apiData = await fetchKLineData();
if (!apiData) return;
// 数据格式转换:将API返回的字段名映射为KLineChart要求的字段名
const klineChartData = apiData.map(item => ({
timestamp: item.time, // 将 'time' 映射为 'timestamp'
open: Number(item.open),
high: Number(item.high),
low: Number(item.low),
close: Number(item.close),
volume: Number(item.volume)
}));
// 按时间排序(防止API返回乱序)
klineChartData.sort((a, b) => a.timestamp - b.timestamp);
// 使用转换后的数据渲染图表
chart.applyNewData(klineChartData);
console.log('K线图初始化完成!');
}
// 执行初始化
initChart();
🎨 自定义样式与技术指标
KLineChart 支持丰富的样式自定义和技术指标添加。
// 设置样式选项
chart.setStyleOptions({
candle: {
type: 'candle_solid', // 蜡烛图类型
bar: {
upColor: '#26A69A', // 上涨颜色
downColor: '#EF5350', // 下跌颜色
},
priceMark: {
// 价格标记
high: {
show: true },
low: {
show: true }
}
},
grid: {
// 网格线
show: true
}
});
// 添加技术指标(如移动平均线MA)
chart.createIndicator('MA', false, {
id: 'candle_pane' });
// 添加成交量指标
chart.createIndicator('VOL');
🔄 实现实时数据更新
对于金融应用,实时性很重要。以下是定时轮询的实现方式。
// 定时轮询更新函数
async function startPolling(pid) {
setInterval(async () => {
try {
const klineUrl = `${
API_BASE}/stock/kline?pid=${
pid}&interval=${
interval}&key=${
API_KEY}`;
const response = await fetch(klineUrl);
const result = await response.json();
if (result.code === 200 && result.data.length > 0) {
const latestData = result.data[result.data.length - 1];
const formattedData = {
timestamp: latestData.time,
open: Number(latestData.open),
high: Number(latestData.high),
low: Number(latestData.low),
close: Number(latestData.close),
volume: Number(latestData.volume)
};
// 增量更新图表
chart.updateData(formattedData);
}
} catch (error) {
console.error('实时更新失败:', error);
}
}, 5000); // 每5秒轮询一次
}
💡 完整示例代码
以下是整合所有功能的完整 HTML 示例。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>StockTV K线图Demo</title>
<script src="https://cdn.dolphindb.cn/vendors/klinecharts/dist/umd/klinecharts.min.js"></script>
<style>
body {
margin: 20px; font-family: Arial, sans-serif; }
.controls {
margin-bottom: 20px; }
button {
padding: 8px 15px; margin-right: 10px; cursor: pointer; }
</style>
</head>
<body>
<div class="controls">
<h3>股票K线图示例</h3>
<button onclick="loadData('AAPL')">苹果(AAPL)</button>
<button onclick="loadData('MSFT')">微软(MSFT)</button>
<select id="intervalSelect">
<option value="P1D">日线</option>
<option value="PT1H">1小时</option>
<option value="PT15M">15分钟</option>
</select>
</div>
<div id="k-line-chart" style="height: 600px; width: 100%;"></div>
<script>
const API_KEY = 'YOUR_API_KEY_HERE'; // 请替换为你的真实API密钥
const API_BASE = 'https://api.stocktv.top';
const chart = klinecharts.init('k-line-chart');
// 设置默认样式
chart.setStyleOptions({
candle: {
bar: {
upColor: '#26A69A',
downColor: '#EF5350',
}
}
});
async function loadData(symbol, interval = 'P1D') {
if (!interval) interval = document.getElementById('intervalSelect').value;
try {
// 获取股票PID
const listUrl = `${
API_BASE}/stock/stocks?countryId=1&symbol=${
symbol}&key=${
API_KEY}`;
const listResponse = await fetch(listUrl);
const listData = await listResponse.json();
if (listData.code !== 200 || listData.data.length === 0) {
alert('未找到该股票');
return;
}
const stockPid = listData.data[0].id;
// 获取K线数据
const klineUrl = `${
API_BASE}/stock/kline?pid=${
stockPid}&interval=${
interval}&key=${
API_KEY}`;
const klineResponse = await fetch(klineUrl);
const klineData = await klineResponse.json();
if (klineData.code !== 200) {
alert('获取数据失败: ' + klineData.message);
return;
}
// 数据转换
const chartData = klineData.data.map(item => ({
timestamp: item.time,
open: Number(item.open),
high: Number(item.high),
low: Number(item.low),
close: Number(item.close),
volume: Number(item.volume)
})).sort((a, b) => a.timestamp - b.timestamp);
// 渲染图表
chart.applyNewData(chartData);
chart.createIndicator('MA');
chart.createIndicator('VOL');
} catch (error) {
console.error('Error:', error);
alert('请求失败,请检查控制台日志');
}
}
// 页面加载默认数据
window.onload = () => loadData('AAPL');
// 响应式调整大小
window.addEventListener('resize', () => {
chart.resize();
});
</script>
</body>
</html>
📋 关键注意事项
API密钥安全:切勿将真实 API 密钥直接硬编码在前端代码中并上传到公开仓库。生产环境应通过后端服务器转发请求。
数据格式转换:StockTV API 返回的数据字段需要转换为 KLineChart 要求的格式,特别是时间戳字段的映射。
错误处理:完善的错误处理能提升应用健壮性,包括网络请求失败、API返回错误码等情况。
频率限制:遵守 StockTV API 的调用频率限制,避免过于频繁的请求。
这个Demo展示了如何使用 KLineChart 和 StockTV API 快速构建一个功能完整的股票K线图应用,您可以根据实际需求进一步扩展功能。