js实现k线图
使用Canvas绘制K线图
Canvas是HTML5提供的绘图API,适合高性能的图形渲染。通过计算坐标和绘制路径,可以高效地实现K线图。
const canvas = document.getElementById('kLineChart');
const ctx = canvas.getContext('2d');
function drawKLine(data) {
const padding = 20;
const candleWidth = 10;
const maxPrice = Math.max(...data.map(item => item.high));
const minPrice = Math.min(...data.map(item => item.low));
const priceRange = maxPrice - minPrice;
const heightRatio = (canvas.height - 2 * padding) / priceRange;
data.forEach((item, index) => {
const x = padding + index * (candleWidth + 5);
const highY = padding + (maxPrice - item.high) * heightRatio;
const lowY = padding + (maxPrice - item.low) * heightRatio;
const openY = padding + (maxPrice - item.open) * heightRatio;
const closeY = padding + (maxPrice - item.close) * heightRatio;
// 绘制上下影线
ctx.beginPath();
ctx.moveTo(x + candleWidth / 2, highY);
ctx.lineTo(x + candleWidth / 2, lowY);
ctx.stroke();
// 绘制K线实体
ctx.fillStyle = item.close > item.open ? 'green' : 'red';
ctx.fillRect(x, Math.min(openY, closeY), candleWidth, Math.abs(closeY - openY));
});
}
使用第三方库ECharts
ECharts是百度开源的强大可视化库,内置丰富的图表类型,包括K线图。只需简单配置即可生成专业级的K线图。
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<div id="kLineContainer" style="width: 800px;height:400px;"></div>
<script>
const chart = echarts.init(document.getElementById('kLineContainer'));
const option = {
xAxis: { type: 'category', data: ['2023-01', '2023-02', '2023-03'] },
yAxis: { scale: true },
series: [{
type: 'candlestick',
data: [
[20, 30, 10, 25],
[25, 35, 20, 30],
[30, 40, 25, 35]
]
}]
};
chart.setOption(option);
</script>
使用D3.js实现动态K线图
D3.js是数据驱动的文档操作库,适合需要高度自定义的动态可视化需求。
import * as d3 from 'd3';
function renderKLine(data, containerId) {
const margin = { top: 20, right: 20, bottom: 30, left: 50 };
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
const svg = d3.select(`#${containerId}`)
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const x = d3.scaleBand().range([0, width]).padding(0.2);
const y = d3.scaleLinear().range([height, 0]);
x.domain(data.map(d => d.date));
y.domain([d3.min(data, d => d.low) * 0.9, d3.max(data, d => d.high) * 1.1]);
svg.selectAll('.candle')
.data(data)
.enter()
.append('rect')
.attr('class', 'candle')
.attr('x', d => x(d.date))
.attr('y', d => y(Math.max(d.open, d.close)))
.attr('width', x.bandwidth())
.attr('height', d => Math.abs(y(d.open) - y(d.close)))
.attr('fill', d => d.close > d.open ? 'green' : 'red');
}
响应式设计注意事项
确保K线图在不同设备上正常显示需要处理响应式布局。监听窗口resize事件并重新计算尺寸。
window.addEventListener('resize', function() {
chart && chart.resize();
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
drawKLine(data);
});
数据格式规范
标准K线数据应包含时间、开盘价、收盘价、最高价和最低价。建议使用如下格式:
const kData = [
{ date: '2023-01', open: 20, close: 25, high: 30, low: 10 },
{ date: '2023-02', open: 25, close: 30, high: 35, low: 20 },
{ date: '2023-03', open: 30, close: 35, high: 40, low: 25 }
];






