JavaScript 结合 Canvas 或 SVG 绘制图表的方法如下:
Canvas 绘制图表
创建画布:在 HTML 中创建 <canvas> 元素,并设置宽高。
获取上下文:用 JavaScript 获取 canvas 上下文(2d context)。
绘制图形:使用 context 的绘图方法绘制图形。
示例:绘制简单柱状图。
<canvas id="myChart" width="400" height="300"></canvas><script> const canvas = document.getElementById('myChart'); const ctx = canvas.getContext('2d'); const data = [30, 50, 80, 60, 90]; // 示例数据 const barWidth = 50; const barSpacing = 20; const maxHeight = canvas.height - 20; const maxValue = Math.max(...data); data.forEach((value, index) => { const x = index * (barWidth + barSpacing) + 30; const y = maxHeight - (value / maxValue) * (maxHeight - 40); const height = (value / maxValue) * (maxHeight - 40); // 绘制矩形柱子 ctx.fillStyle = '#4CAF50'; ctx.fillRect(x, y, barWidth, height); // 添加数值标签 ctx.fillStyle = '#000'; ctx.font = '12px Arial'; ctx.fillText(value, x + barWidth / 2 - 8, y - 5); });</script>SVG 绘制图表
插入 SVG 标签:在 HTML 中插入 <svg> 标签,定义宽度和高度。
创建图形元素:使用 JavaScript 动态创建图形元素(如 <rect>, <line>, <text>)并添加到 SVG 中。
示例:用 SVG 绘制折线图。
<svg id="lineChart" width="400" height="300"></svg><script> const svg = document.getElementById('lineChart'); const data = [20, 40, 25, 70, 60]; const padding = 40; const width = 400 - 2 * padding; const height = 300 - 2 * padding; const xStep = width / (data.length - 1); const maxValue = Math.max(...data); // 绘制坐标轴线 const xAxis = document.createElementNS("http://www.w3.org/2000/svg"
, "line"); xAxis.setAttribute("x1", padding); xAxis.setAttribute("y1", height + padding); xAxis.setAttribute("x2", width + padding); xAxis.setAttribute("y2", height + padding); xAxis.setAttribute("stroke", "black"); svg.appendChild(xAxis); // 绘制折线路径 let pathData = `M ${padding} ${height + padding - (data[0] / maxValue) * height}`; for (let i = 1; i < data.length; i++) { const x = padding + i * xStep; const y = height + padding - (data[i] / maxValue) * height; pathData += ` L ${x} ${y}`; } const line = document.createElementNS("http://www.w3.org/2000/svg"
, "path"); line.setAttribute("d", pathData); line.setAttribute("fill", "none"); line.setAttribute("stroke", "#1E90FF"); line.setAttribute("stroke-width", 2); svg.appendChild(line); // 添加数据点圆圈 data.forEach((value, index) => { const x = padding + index * xStep; const y = height + padding - (value / maxValue) * height; const circle = document.createElementNS("http://www.w3.org/2000/svg"
, "circle"); circle.setAttribute("cx", x); circle.setAttribute("cy", y); circle.setAttribute("r", 4); circle.setAttribute("fill", "#FF4500"); // 添加鼠标悬停提示 circle.addEventListener('mouseover', () => { tooltip.style.display = 'block'; tooltip.style.left = x + 10 + 'px'; tooltip.style.top = y - 20 + 'px'; tooltip.textContent = value; }); svg.appendChild(circle); }); // 提示框 const tooltip = document.createElement('div'); tooltip.style.position = 'absolute'; tooltip.style.background = '#333'; tooltip.style.color = '#fff'; tooltip.style.padding = '4px 8px'; tooltip.style.borderRadius = '4px'; tooltip.style.fontSize = '12px'; tooltip.style.display = 'none'; document.body.appendChild(tooltip); document.addEventListener('mousemove', () => { if (tooltip.style.display === 'block') { tooltip.style.display = 'none'; } });</script>选择 Canvas 还是 SVG
Canvas:数据量大、频繁重绘(如实时监控)→ 推荐 Canvas。
SVG:需要交互、可访问性、响应式设计 → 推荐 SVG。
开发效率:追求开发效率 → 可考虑 D3.js、Chart.js 等库。
原生 JavaScript 配合 Canvas 或 SVG 能完全控制图表细节,适合定制化需求强的项目。掌握这两种方式,就能灵活应对大多数前端图表开发任务。