Files
brk/website_next/chart/bar/index.js
T
2026-07-04 13:27:57 +02:00

79 lines
1.8 KiB
JavaScript

import { createLinePathData, formatCoordinate } from "../path.js";
import { createStackedSeries } from "../stacked/series.js";
import { clamp } from "../math.js";
import { appendSeriesPath } from "../series-path.js";
/** @param {StackedPoint[]} points */
function getBarWidth(points) {
return points.length > 1
? Math.abs(points[1].plotX - points[0].plotX) * 0.8
: 1;
}
/**
* @param {ChartFrame} frame
* @param {StackedPoint[]} points
* @param {number} width
*/
function createBarPathData(frame, points, width) {
return points
.map(({ plotX, plotY0, plotY1 }) => {
const left = clamp(plotX - width / 2, frame.left, frame.right - width);
const right = left + width;
const top = Math.min(plotY0, plotY1);
const bottom = Math.max(plotY0, plotY1);
return (
`M${formatCoordinate(left)} ${formatCoordinate(top)}` +
`H${formatCoordinate(right)}V${formatCoordinate(bottom)}` +
`H${formatCoordinate(left)}Z`
);
})
.join(" ");
}
/**
* @param {PlotContext} context
*/
export function renderBarPlot({
group,
loadedSeries,
frame,
highlight,
scale,
order,
}) {
const { lineIndexes, plottedSeries, stackIndexes } = createStackedSeries(
loadedSeries,
frame,
order,
scale,
);
for (const index of stackIndexes) {
const { color, points } = plottedSeries[index];
appendSeriesPath({
group,
highlight,
index,
chart: "bar",
color,
d: createBarPathData(frame, points, getBarWidth(points)),
});
}
for (const index of lineIndexes) {
const { color, points } = plottedSeries[index];
appendSeriesPath({
group,
highlight,
index,
chart: "line",
color,
d: createLinePathData(points),
});
}
return plottedSeries;
}