mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 11:58:14 +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>
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
export const BAR_DEPTH_MAX_PX = 7;
|
|
/** The side parallelogram's back edge lifts by `depth * this ratio`, giving a
|
|
* subtle head-on perspective slope. */
|
|
export const BAR_DEPTH_PERSPECTIVE_RATIO = 0.45;
|
|
|
|
/**
|
|
* Maximum side-face depth in px for a chart, clamped so depth never spills past
|
|
* the gap between bars. `stepWidth` is d3-scaleBand's `step()` (bandwidth +
|
|
* gap); `bandWidth` is a single bar's width. Returns 0 for gapless/dense charts.
|
|
*/
|
|
export function barDepthMaxDepth(stepWidth: number, bandWidth: number): number {
|
|
const gap = Math.max(0, stepWidth - bandWidth);
|
|
return Math.min(bandWidth * 0.22, Math.max(0, gap - 1), BAR_DEPTH_MAX_PX);
|
|
}
|
|
|
|
/**
|
|
* Per-bar side-face depth + perspective rise.
|
|
*
|
|
* - `absOffset` ∈ [0, 1]: the bar's normalized distance from the chart's
|
|
* horizontal center. 0 = dead center (no depth); 1 = chart edge (full depth).
|
|
* - `naturalHeight`: the bar's pixel height. Depth is capped by it so a short
|
|
* bar's side never reads wider than the bar is tall.
|
|
* - `maxDepth`: from `barDepthMaxDepth`.
|
|
*/
|
|
export function barDepthAndRise(
|
|
absOffset: number,
|
|
naturalHeight: number,
|
|
maxDepth: number
|
|
): { depth: number; perspectiveRise: number } {
|
|
const offset = Math.min(1, Math.max(0, absOffset));
|
|
const cappedMaxDepth = Math.min(maxDepth, Math.max(0, naturalHeight));
|
|
const depth = offset * cappedMaxDepth;
|
|
return { depth, perspectiveRise: depth * BAR_DEPTH_PERSPECTIVE_RATIO };
|
|
}
|