如何通过for循环利用JS数组在Canvas中绘制纳税表单柱状图?
Canvas柱状图绘制问题
已完成Canvas网格与标签设计,需调用taxForms.js数组数据绘制柱状图,尝试用for循环实现但无法运行。
现有代码
HTML与Canvas代码
<!DOCTYPE html> <html> <head> <title>Tax forms: Bar chart with lines</title> <meta charset="UTF-8"> <script src="taxForms.js"></script> </head> <body> <style> #chart { margin: 1rem auto; display: block; } </style> <canvas id="chart" width="700" height="550"></canvas> <script> const canvas = document.getElementById('chart'); const context = canvas.getContext('2d'); /* Draw a line from (fromX, fromY) to (toX, toY) */ function drawLine(fromX, fromY, toX, toY) { context.strokeStyle = 'black'; context.beginPath(); context.moveTo(toX, toY); context.lineTo(fromX, fromY); context.stroke(); } /* Draw a text (string) on (x, y) */ function drawText(text, x, y) { context.fillStyle = 'black'; context.fillText(text, x, y); } /* Draw a text and with a line to its right */ function drawLineWithText(text, fromX, fromY, toX, toY) { drawText(text, fromX - 50, fromY + 5); drawLine(fromX, fromY, toX, toY); } /* Insert your code here. */ for (var i = 10; i > 0; i--){ drawLineWithText(i*100000,50,550-i*50,600,550-i*50); } /*Code for the small labels*/ context.beginPath(); context.fillStyle = 'red'; context.rect(600,50,50,20); context.fill(); drawText('Income',655,64); context.beginPath(); context.fillStyle = 'blue'; context.rect(600,75,50,20); context.fill(); drawText('Wealth',655,89); /*Code for the bars*/ /*relevant code for the bars starts under here*/ function rect(fX, fY, tX, tY) { context.beginPath(); context.fillStyle = 'red'; context.fill(); } for (var i = 1; i < taxForms.lenght; i++){ rect(10, 10, 10, i*2); } </script> </body> </html>
JavaScript代码(taxForms.js)
const taxForms = [ { realName: "Bruce Wayne", income: 750000, wealth: 300000 }, { realName: "John Blake", income: 440000, wealth: 832000 }, { realName: "Selina Kyle", income: 640000, wealth: 432000 } ];
效果对比
当前效果:
预期效果:
问题分析与修复
核心错误点
- 拼写错误:
taxForms.lenght应为taxForms.length,导致循环无法触发 - rect函数无效:未调用Canvas原生
rect()方法,无法生成矩形路径 - 未匹配网格比例:网格每100000单位对应50像素高度,未按此比例计算柱子尺寸
- 未处理双数据系列:未区分income(红色)和wealth(蓝色)的柱子,也未添加姓名标签
修正后的柱状图代码
替换原有「Code for the bars」部分的代码:
/*Code for the bars*/ // 设置字体(可选,优化文字显示) context.font = "14px Arial"; // 计算比例:每100000单位对应50像素高度 const scale = 50 / 100000; // 每个条目柱子的宽度和间距 const barWidth = 80; const gap = 40; const startX = 80; // 遍历taxForms数组绘制每个条目的柱子和标签 taxForms.forEach((form, index) => { const x = startX + index * (barWidth + gap); const baseY = 550; // 绘制Income柱子(红色) const incomeHeight = form.income * scale; context.fillStyle = 'red'; context.fillRect(x, baseY - incomeHeight, barWidth/2, incomeHeight); // 绘制Wealth柱子(蓝色) const wealthHeight = form.wealth * scale; context.fillStyle = 'blue'; context.fillRect(x + barWidth/2, baseY - wealthHeight, barWidth/2, wealthHeight); // 绘制姓名标签 drawText(form.realName, x, baseY + 15); });
替换后即可正确渲染出匹配预期的双系列柱状图。
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

