实验目的:1. 熟悉使用canvas绘制图形
2. 熟悉表单组件及按钮相应事件
实验要求:在网页中添加表单组件,要求用户输入统计数据,根据用户数据绘制相应的饼状图和柱状图。
- 要求对用户输入进行有效性验证;
- 通过点击按钮绘制饼状图或柱状图;
- 饼状图和柱状图要有数据标注。
代码展示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Canvas绘图</title> </head> <body> <form id="dataForm" οnsubmit="event.preventDefault(); validateInput();"> <label for="data">输入数据:</label> <!-- <input type="text" id="data" name="data" >--> <textarea id="data" name="data" rows="5" cols="33" required> {"条目1": 1, "条目2": 2, "条目3": 3, "条目4": 5} </textarea> <button type="button" οnclick="drawPieChart()">绘制饼状图</button> <button type="button" οnclick="drawBarChart()">绘制柱状图</button> </form> <div> <canvas id="myCanvas" width="500" height="400" style="border:1px solid #000000;"></canvas> </div> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); function drawPieChart() { // 清除画布 ctx.clearRect(0, 0, canvas.width, canvas.height); let inputData = document.getElementById('data').value; let data = stringToJson(inputData); if (!data) { alert('请输入有效数据'); return; } let total = Object.values(data).reduce((acc, val) => acc + val, 0); let startAngle = 0; let legendX = 370; let legendY = 20; for (let key in data) { const value = data[key]; const percentage = ((value / total) * 100).toFixed(2); const sliceAngle = (2 * Math.PI * value) / total; const color = getRandomColor(); // 计算文本位置 const textX = 200 + Math.cos(startAngle + sliceAngle / 2) * 150; const textY = 200 + Math.sin(startAngle + sliceAngle / 2) * 150; ctx.fillStyle = color; ctx.beginPath(); ctx.moveTo(200, 200); ctx.arc(200, 200, 150, startAngle, startAngle + sliceAngle); ctx.closePath(); ctx.fill(); // 绘制图例 ctx.fillRect(legendX, legendY, 20, 20); ctx.fillStyle = "black"; ctx.fillText(`${key} (${percentage}%)`, legendX + 30, legendY + 15); legendY += 30; // 绘制百分比 ctx.fillStyle = "black"; ctx.fillText(`${percentage}%`, textX, textY); startAngle += sliceAngle; } } function drawBarChart() { // 清除画布 ctx.clearRect(0, 0, canvas.width, canvas.height); let inputData = document.getElementById('data').value; let data = stringToJson(inputData); let startX = 50; for (let key in data) { const value = data[key]; const barHeight = value * 50; ctx.fillStyle = getRandomColor(); ctx.fillRect(startX, 300 - barHeight, 50, barHeight); ctx.fillStyle = "black"; ctx.fillText(key, startX, 320); startX += 70; } } function validateInput() { const dataInput = document.getElementById('data').value.trim(); // 在这里编写对用户输入进行有效性验证的代码 // 例如,确保输入为逗号分隔的数字等 // 这里只是一个简单的示例 if (dataInput === '') { alert('请输入有效数据'); return false; } return true; } function getRandomColor() { const letters = '0123456789ABCDEF'; let color = '#'; for (let i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; } function stringToJson(str) { try { return JSON.parse(str); } catch (error) { console.error("Invalid JSON string:", error); return null; } } </script> </body> </html>
效果展示: