mirror of
https://github.com/temetro/temetro.git
synced 2026-08-11 11:09:04 +00:00
321a6298a4
- Pharmacy: the sidebar entry now expands into Pharmacy + a new Inventory page (searchable medication stock with derived in-stock/low/out availability, backed by /api/inventory). Fix the dispensing-queue "Expiring" badge so it only flags courses ending within the next 7 days, not ones already elapsed. - Lab "Add analysis result": the patient picker no longer lists patients until you type and supports arrow-key + Enter selection; the test field offers a catalog of common analyses with an Advanced option (custom analysis + ref range); submitted results now show immediately in a Recent results feed. - Analysis: add a Live panel (real-time line chart) and replace the flat trend sparklines with bklit-ui area + bar charts (installed from the @bklit shadcn registry; chart CSS variables wired into the theme for light and dark). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
export function computeSeriesBarWidth(input: {
|
|
innerWidth: number;
|
|
dataLength: number;
|
|
columnWidth: number;
|
|
seriesCount: number;
|
|
composedBarSize?: number;
|
|
composedMaxBarSize?: number;
|
|
composedBarGap?: number;
|
|
stacked?: boolean;
|
|
}): number {
|
|
const {
|
|
innerWidth,
|
|
dataLength,
|
|
columnWidth,
|
|
seriesCount,
|
|
composedBarSize,
|
|
composedMaxBarSize,
|
|
composedBarGap = 4,
|
|
stacked = false,
|
|
} = input;
|
|
|
|
const gap = composedBarGap;
|
|
const groupCount = stacked ? 1 : Math.max(1, seriesCount);
|
|
let slot = columnWidth;
|
|
if (slot <= 0) {
|
|
slot = dataLength < 2 ? innerWidth : innerWidth / (dataLength - 1);
|
|
}
|
|
|
|
let width =
|
|
composedBarSize ??
|
|
Math.min(slot * 0.88, composedMaxBarSize ?? Number.POSITIVE_INFINITY);
|
|
if (composedMaxBarSize != null) {
|
|
width = Math.min(width, composedMaxBarSize);
|
|
}
|
|
if (groupCount > 1) {
|
|
const maxGroup = slot * 0.92;
|
|
const needed = groupCount * width + (groupCount - 1) * gap;
|
|
if (needed > maxGroup && maxGroup > 0) {
|
|
width = Math.max(4, (maxGroup - (groupCount - 1) * gap) / groupCount);
|
|
}
|
|
}
|
|
|
|
return Math.max(2, width);
|
|
}
|
|
|
|
/** Half-width of the bar group at each x — used to pad reveal clips. */
|
|
export function computeSeriesBarRevealClipPadding(input: {
|
|
barWidth: number;
|
|
seriesCount: number;
|
|
gap?: number;
|
|
stacked?: boolean;
|
|
}): number {
|
|
const { barWidth, seriesCount, gap = 4, stacked = false } = input;
|
|
|
|
if (stacked || seriesCount <= 1) {
|
|
return Math.ceil(barWidth / 2);
|
|
}
|
|
|
|
const groupWidth = seriesCount * barWidth + (seriesCount - 1) * gap;
|
|
return Math.ceil(groupWidth / 2);
|
|
}
|