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
相关产品推荐
相关产品推荐

