如何使用单个script.js通过多ID调用不同CSS类实现多甜甜圈图表
解决单个JS文件渲染多个甜甜圈图表的问题
我明白你的痛点——重复写几乎一样的JS文件太冗余了!咱们可以把图表渲染逻辑封装成可复用的函数,只用一个script.js就能搞定所有4个甜甜圈图。核心思路是把固定的ID、数据等参数抽离出来,让代码能根据不同的配置生成对应的图表。
步骤1:重构JS代码(单文件版本)
我们保留原来的绘图工具函数和Piechart类,新增一个可复用的初始化函数,通过传入不同参数来渲染不同的图表:
// 工具函数(保留原有逻辑) function drawLine(ctx, startX, startY, endX, endY) { ctx.beginPath(); ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); ctx.stroke(); } function drawArc(ctx, centerX, centerY, radius, startAngle, endAngle) { ctx.beginPath(); ctx.arc(centerX, centerY, radius, startAngle, endAngle); ctx.stroke(); } function drawPieSlice(ctx, centerX, centerY, radius, startAngle, endAngle, color) { ctx.fillStyle = color; ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.arc(centerX, centerY, radius, startAngle, endAngle); ctx.closePath(); ctx.fill(); } // Piechart类(保留原有逻辑) var Piechart = function (options) { this.options = options; this.canvas = options.canvas; this.ctx = this.canvas.getContext("2d"); this.colors = options.colors; this.draw = function () { var total_value = 0; var color_index = 0; for (var categ in this.options.data) { var val = this.options.data[categ]; total_value += val; } var start_angle = 0; for (categ in this.options.data) { val = this.options.data[categ]; var slice_angle = 2 * Math.PI * val / total_value; drawPieSlice( this.ctx, this.canvas.width / 2, this.canvas.height / 2, Math.min(this.canvas.width / 2, this.canvas.height / 2), start_angle, start_angle + slice_angle, this.colors[color_index % this.colors.length] ); start_angle += slice_angle; color_index++; } // 绘制甜甜圈中心的自定义颜色圆 if (this.options.doughnutHoleSize) { drawPieSlice( this.ctx, this.canvas.width / 2, this.canvas.height / 2, this.options.doughnutHoleSize * Math.min(this.canvas.width / 2, this.canvas.height / 2), 0, 2 * Math.PI, "#206020" ); } } }; // 新增:可复用的图表初始化函数 function createDoughnutChart(canvasId, data, colors, doughnutHoleSize = 0.7) { var myCanvas = document.getElementById(canvasId); myCanvas.width = 50; myCanvas.height = 40; var myDougnutChart = new Piechart({ canvas: myCanvas, data: data, colors: colors, doughnutHoleSize: doughnutHoleSize }); myDougnutChart.draw(); } // 等待DOM加载完成后初始化所有图表,避免找不到元素的问题 document.addEventListener('DOMContentLoaded', function() { // 初始化第1个图表 createDoughnutChart("myCanvas1", { "Positive": 50, "Negative": 10, "N/A": 20 }, ["#32CD32", "#FF0000", "#FFFF00"]); // 初始化第2个图表(可自定义数据和颜色) createDoughnutChart("myCanvas2", { "Positive": 40, "Negative": 20, "N/A": 25 }, ["#32CD32", "#FF0000", "#FFFF00"]); // 初始化第3个图表 createDoughnutChart("myCanvas3", { "Positive": 60, "Negative": 5, "N/A": 15 }, ["#32CD32", "#FF0000", "#FFFF00"]); // 初始化第4个图表 createDoughnutChart("myCanvas4", { "Positive": 35, "Negative": 15, "N/A": 30 }, ["#32CD32", "#FF0000", "#FFFF00"]); });
步骤2:修改HTML结构
现在只需要引入一次script.js,并确保每个canvas有唯一的ID:
<!-- HTML部分 --> <div class="chart-container"> <div class="chart"> <canvas id="myCanvas1"></canvas> </div> <div class="chart"> <canvas id="myCanvas2"></canvas> </div> <div class="chart"> <canvas id="myCanvas3"></canvas> </div> <div class="chart"> <canvas id="myCanvas4"></canvas> </div> </div> <!-- 只引入一次JS文件,建议放在body末尾 --> <script type="text/javascript" src="script.js"></script>
步骤3:调整CSS布局(确保间隔≥20px)
修改CSS类,用更灵活的方式布局,保证每个图表之间的间隔至少20px:
/* CSS文件 */ .chart-container { position: absolute; bottom: 0; left: 122px; display: flex; gap: 20px; /* 直接设置间隔为20px,满足需求 */ } .chart { padding: 1em 3px 3px 5px; width: 66px; height: 63px; }
为什么原来的方式不行?
原来的代码是硬编码了固定的canvas ID(myCanvas1)和数据,每个JS文件只能处理一个特定的图表。通过封装成可复用函数,我们把canvas ID、数据、颜色等变成了参数,这样在同一个JS文件里就能多次调用函数,生成不同的图表了。
内容的提问来源于stack exchange,提问作者user9762426
相关产品推荐
相关产品推荐

