You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用单个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:57:06