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

Chart.js:能否实现固定高度、宽度随图例项数量自适应的图表?

Chart.js 图例项目过多时自动扩展图表宽度的解决方案

问题场景

使用Chart.js v3.8.1开发环形图,当图例项目数量较多、超出图表初始宽度时,希望图表容器能自动适配图例总宽度,但直接修改容器样式属性无法实现需求。

原代码如下:

HTML

<div class="container">
    <div class="chart-container">
        <canvas style="height: 300px; width: 100%"></canvas>
    </div>
</div>

CSS

.container {
    width: 100%;
    height: 400px;
    border: 3px solid red;
    display: flex;
}

.chart-container {
    border: 2px solid blue;
    width: fit-content;
    margin: auto 0;
    width: fit-content;
}

canvas {
    border: 2px solid green;
}

JavaScript

$(document).ready(() => {
    let preparedData = prepareData(60);
    const config = {
        type: "doughnut",
        data: preparedData,
        options: {
            responsive: false,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: true,
                    position: "right"
                }
            }
        }
    };

    let chart = new Chart($("canvas"), config);
});

function prepareData(numData) {
    let labels = [];
    let localData = [];

    for (idx = 0; idx < numData; idx++) {
        labels.push("Data " + idx);
        let random = getRandomInt(100);
        localData.push(random);
    }

    let datasets = [
        {
            label: "Info",
            data: localData,
            borderWidth: 0
        }
    ];

    return { labels, datasets };
}

function getRandomInt(max) {
    return Math.floor(Math.random() * max);
}

解决方案

Chart.js默认不会自动根据图例尺寸调整容器宽度,需通过监听图例渲染事件,手动计算尺寸并动态调整容器宽度:

1. 修改核心配置与添加事件监听

调整Chart.js配置,开启响应式,并监听afterRender事件计算图例宽度:

$(document).ready(() => {
    let preparedData = prepareData(60);
    const chartCanvas = $("canvas")[0];
    const chartContainer = $(".chart-container")[0];
    
    const config = {
        type: "doughnut",
        data: preparedData,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: true,
                    position: "right"
                }
            },
            // 监听resize事件,确保窗口变化时重新计算
            onResize: function(chart) {
                adjustContainerWidth(chart);
            }
        }
    };

    let chart = new Chart(chartCanvas, config);
    
    // 图例渲染完成后调整容器宽度
    chart.on('afterRender', function() {
        adjustContainerWidth(this);
    });
    
    // 计算并设置容器宽度的核心函数
    function adjustContainerWidth(chart) {
        const legend = chart.legend;
        if (!legend) return;
        
        // 获取图例实际宽度与图表自身宽度
        const legendWidth = legend.width;
        const chartWidth = chart.width;
        
        // 总宽度 = 图表宽度 + 图例宽度 + 自定义间距
        const totalWidth = chartWidth + legendWidth + 20;
        
        // 设置容器宽度并触发图表resize
        chartContainer.style.width = `${totalWidth}px`;
        chart.resize();
    }
});

// 以下函数保持不变
function prepareData(numData) {
    let labels = [];
    let localData = [];

    for (idx = 0; idx < numData; idx++) {
        labels.push("Data " + idx);
        let random = getRandomInt(100);
        localData.push(random);
    }

    let datasets = [
        {
            label: "Info",
            data: localData,
            borderWidth: 0
        }
    ];

    return { labels, datasets };
}

function getRandomInt(max) {
    return Math.floor(Math.random() * max);
}

2. 优化CSS样式

调整容器样式,确保横向溢出时可滚动:

.container {
    width: 100%;
    height: 400px;
    border: 3px solid red;
    display: flex;
    overflow-x: auto; /* 超出父容器时显示横向滚动条 */
}

.chart-container {
    border: 2px solid blue;
    margin: auto 0;
    min-width: fit-content; /* 容器宽度适配内容 */
}

canvas {
    border: 2px solid green;
    height: 300px !important; /* 固定图表高度 */
}

关键说明

  • 开启responsive: true是让Chart.js能响应容器尺寸变化的前提
  • afterRender事件确保在图例完全渲染后获取准确尺寸
  • 自定义间距可根据实际布局需求调整,避免图表与图例紧贴
  • 父容器添加overflow-x: auto,防止总宽度超出时布局错乱

内容的提问来源于stack exchange,提问作者Ciappone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:25:04