Chart.js绘制带垂直边缘的填充面积图的正确实现方式问询
Chart.js绘制带垂直边缘的填充面积图的正确实现方式问询
我在使用Chart.js绘制带垂直边缘的堆叠填充面积图时遇到了一个问题:当多个数据系列存在重复的x值(比如不同任务的起始或结束时间重合)时,图表无法正确渲染出垂直边缘。
目前我临时的解决办法是给重复的x值添加一个极小的偏移量(比如1e-6),让它们变成近似值(比如11.999999)来避开重复,这样图表就能正常显示了,但这种实现方式总感觉不够优雅,肯定有更规范的方法来处理这种垂直边缘的绘制。
我的当前代码
JavaScript
const TASKS = [ { start: 6.5, end: 23.5, value: 17 }, { start: 0, end: 12, value: 8 }, { start: 12, end: 23.5, value: 23 }, { start: 0, end: 6.5, value: 1 }, { start: 23.5, end: 24, value: 6 }, ]; const COLORS = ["#80dfff80", "#ff80df80", "#dfff8080", "#e5d29980", "#99e5d280"]; function formatTasks(tasks, epsilon) { const xValues = [...new Set(tasks.flatMap(task => [task.start, task.end, Math.max(0, task.start - epsilon), task.end - epsilon]))].sort((a, b) => a - b); const result = tasks.map(task => xValues.map(x => ({ x, y: x >= task.start && x < task.end ? task.value : 0 }))); console.log(result); return result; } ; [0, 1e-6].forEach((EPSILON, chartIndex) => { new Chart('chart' + (chartIndex + 1), { "type": "scatter", "data": { "labels": [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" ], "datasets": formatTasks(TASKS, EPSILON).map((data, index) => ({ "type": "scatter", "label": "Task " + (index + 1), "yAxisID": "y", "showLine": true, "pointRadius": 0, "pointHoverRadius": 0, "borderWidth": 0, "borderColor": "transparent", "pointStyle": "rect", "backgroundColor": COLORS[index], "stack": "tasks", "fill": index ? "-1" : "origin", "data": data, })), }, "options": { "responsive": true, "maintainAspectRatio": false, "animation": false, "plugins": { "legend": { "position": "bottom", "labels": { "usePointStyle": true } }, }, "scales": { "x": { "min": 0, "max": 24, "ticks": { "minRotation": 0, "maxRotation": 0, "stepSize": 1 } }, "y": { "type": "linear", "position": "left", "beginAtZero": true, "stacked": true, "ticks": { "format": { "maximumFractionDigits": 0 } } }, } } }) });
CSS
.chart-container { position: relative; margin: auto; height: 40vh; width: 80vw; min-height: 200px; }
HTML
Chart 1: (Epsilon = 0) 无法正常渲染 <div class="chart-container"><canvas id="chart1"></canvas></div> Chart 2: (Epsilon = 1e-6) 可以工作,但实现方式不够优雅 <div class="chart-container"><canvas id="chart2"></canvas></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
问题说明
- 当
epsilon=0时,由于存在重复的x值,Chart.js无法正确识别垂直边缘,导致填充区域渲染异常; - 当
epsilon=1e-6时,通过给x值添加微小偏移避开重复,图表能正常显示,但这种用近似值的方式显然不是最佳方案。
想请教各位,在Chart.js中绘制这种带垂直边缘的堆叠填充面积图,正确的实现方式应该是什么?有没有不需要手动调整x值的方法?
备注:内容来源于stack exchange,提问作者tsh




