JavaScript实现Marimekko堆叠图表的矩形偏移计算问题
Marimekko堆叠图表JS绘制逻辑修复方案
核心修复逻辑
原有代码所有矩形的y坐标固定为0,导致同列块全部重叠,只需要为每一列维护一个累积y偏移量,每次绘制当前列块后更新偏移量即可实现堆叠效果:
- 遍历数据行前初始化偏移数组,存储每一列当前已堆叠的高度位置,初始值全为0
- 绘制单个矩形时,y属性直接取对应列的当前偏移值
- 矩形高度赋值完成后,将当前矩形高度累加到对应列的偏移量中,作为下一个同列块的起始位置
- 若需后续适配全局最大列总和做高度归一化,可将矩形高度计算的分母替换为
Math.max(...stackIndexTotal)
完整可运行代码
JavaScript
// 模拟数据 const json = `{ "data": [ { "value": [ 1, 2, 3, 4] }, { "value": [ 5, 6, 7, 8] }, { "value": [ 9, 10, 11, 12] }, { "value": [13, 14, 15, 16] } ] }`, dataJSON = JSON.parse(json).data; // 计算每列数值总和 const stackIndexTotal = ( dataJSON.slice(1).reduce(((sums, { value }) => sums.map((sum, i) => sum + value[i]) ), dataJSON[0].value) ); const dataContainer = document.getElementById('data-container'); const numberOfValues = dataJSON.length; const widthOfSections = 100 / numberOfValues; // 初始化每列y轴偏移量,初始为0 const yOffset = new Array(dataJSON[0].value.length).fill(0); // 遍历每行数据 dataJSON.forEach((data, index) => { const dataItem = document.createElementNS('http://www.w3.org/2000/svg', 'g'); // 遍历当前行的每个列数值 data.value.forEach((item, i) => { // 若要适配全局最大列总和的百分比,将stackIndexTotal[i]替换为Math.max(...stackIndexTotal)即可 const rectHeight = (item / stackIndexTotal[i]) * 100; dataItem.innerHTML += ` <rect fill="hsl(20, 30%, ${ ((100 / numberOfValues) * index) }%)" x="${ widthOfSections * i }" width="${ widthOfSections }" height="${ rectHeight }" y="${ yOffset[i] }" ></rect> `; // 更新当前列的y偏移量 yOffset[i] += rectHeight; }); dataContainer.appendChild(dataItem); });
CSS
svg { max-width: 25em; max-height: 25em; border: 2px solid; margin: 2em 5em; overflow: visible !important; }
HTML
<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"><g id="data-container"></g></svg>
内容的提问来源于stack exchange,提问作者markb
相关产品推荐
相关产品推荐

