Growth charts: label each percentile curve (3rd, 50th, 97th, …)
Adds a Chart.js plugin that draws the percentile label at the right end of each reference line, matching the convention on printed WHO/CDC growth charts. Lets clinicians identify lines at a glance without using the legend. Canvas gets 30px right-padding so the labels don't get clipped.
This commit is contained in:
parent
e32e9977f5
commit
de0562060b
1 changed files with 33 additions and 0 deletions
|
|
@ -811,6 +811,34 @@
|
|||
|
||||
var _chartInstances = {};
|
||||
|
||||
// Chart.js plugin — draws the percentile label (e.g. "50th") at the
|
||||
// right end of each percentile curve so the lines are identifiable
|
||||
// without a legend. Standard on printed WHO/CDC growth charts.
|
||||
var percentileLabelPlugin = {
|
||||
id: 'percentileLabels',
|
||||
afterDatasetsDraw: function(chart) {
|
||||
var ctx = chart.ctx;
|
||||
chart.data.datasets.forEach(function(ds, i) {
|
||||
// Only the percentile line datasets (labels look like "50th")
|
||||
if (!ds.label || !/^\d+th$/.test(ds.label)) return;
|
||||
var meta = chart.getDatasetMeta(i);
|
||||
if (!meta || meta.hidden || !meta.data || !meta.data.length) return;
|
||||
var last = meta.data[meta.data.length - 1];
|
||||
if (!last) return;
|
||||
ctx.save();
|
||||
ctx.font = '600 10px -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif';
|
||||
ctx.fillStyle = typeof ds.borderColor === 'string' ? ds.borderColor : '#555';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'middle';
|
||||
// Solidify alpha so labels remain readable even when the line is faint
|
||||
var m = ctx.fillStyle.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
||||
if (m) ctx.fillStyle = 'rgb(' + m[1] + ',' + m[2] + ',' + m[3] + ')';
|
||||
ctx.fillText(ds.label, last.x + 4, last.y);
|
||||
ctx.restore();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function renderGrowthChart(canvasId, containerId, lmsTable, patientX, patientY, xLabel, yLabel, extraDatasets) {
|
||||
if (typeof Chart === 'undefined') return; // Chart.js not loaded yet
|
||||
|
||||
|
|
@ -841,11 +869,16 @@
|
|||
_chartInstances[canvasId] = new Chart(document.getElementById(canvasId), {
|
||||
type: 'line',
|
||||
data: { datasets: datasets },
|
||||
plugins: [percentileLabelPlugin],
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
aspectRatio: 1.6,
|
||||
animation: { duration: 300 },
|
||||
// Leave ~28px of padding on the right so the percentile labels
|
||||
// ("50th", "95th", ...) drawn past the last data point are not
|
||||
// clipped by the canvas edge.
|
||||
layout: { padding: { right: 30 } },
|
||||
scales: {
|
||||
x: {
|
||||
type: 'linear',
|
||||
|
|
|
|||
Loading…
Reference in a new issue