@silverpoint/core 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/catalog.d.ts +2 -2
- package/dist/catalog.js +4 -2
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-OLYKR5PS.js → chunk-46QELMCG.js} +8 -213
- package/dist/chunk-46QELMCG.js.map +1 -0
- package/dist/chunk-5MP3BLZK.js +48 -0
- package/dist/chunk-5MP3BLZK.js.map +1 -0
- package/dist/chunk-6YFO7OP3.js +84 -0
- package/dist/chunk-6YFO7OP3.js.map +1 -0
- package/dist/chunk-ANJSW5JX.js +93 -0
- package/dist/chunk-ANJSW5JX.js.map +1 -0
- package/dist/{chunk-PD4MD7JU.js → chunk-E5CC2NNQ.js} +5 -3
- package/dist/chunk-E5CC2NNQ.js.map +1 -0
- package/dist/chunk-G7N4X5XD.js +12 -0
- package/dist/chunk-G7N4X5XD.js.map +1 -0
- package/dist/chunk-NI7B6UEO.js +24 -0
- package/dist/chunk-NI7B6UEO.js.map +1 -0
- package/dist/chunk-WYFRHI4S.js +179 -0
- package/dist/chunk-WYFRHI4S.js.map +1 -0
- package/dist/contrast-siWF_R5o.d.ts +30 -0
- package/dist/dashboard-demos.d.ts +2 -2
- package/dist/index.d.ts +13 -10
- package/dist/index.js +20 -9
- package/dist/index.js.map +1 -1
- package/dist/{model-CLhtoG75.d.ts → model-DVVt59AB.d.ts} +1 -1
- package/dist/palettes.d.ts +29 -0
- package/dist/palettes.js +79 -0
- package/dist/palettes.js.map +1 -0
- package/dist/{props-Dq8FC8GG.d.ts → props-BZ9CcrGv.d.ts} +53 -1
- package/dist/timeline.d.ts +90 -0
- package/dist/timeline.js +125 -0
- package/dist/timeline.js.map +1 -0
- package/dist/{types-B81k-s9_.d.ts → types-BT3Xm7fP.d.ts} +3 -1
- package/dist/types-D5ys35fF.d.ts +576 -0
- package/dist/types-DHBJ0PzV.d.ts +57 -0
- package/dist/ui-demos.d.ts +14 -3
- package/dist/ui-demos.js +163 -1
- package/dist/ui-demos.js.map +1 -1
- package/dist/ui.d.ts +346 -325
- package/dist/ui.js +932 -118
- package/dist/ui.js.map +1 -1
- package/dist/view-DteS9glE.d.ts +82 -0
- package/package.json +13 -1
- package/dist/chunk-OLYKR5PS.js.map +0 -1
- package/dist/chunk-PD4MD7JU.js.map +0 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { u as SubstrateName, q as InkMode, v as ProviderConfig } from './props-BZ9CcrGv.js';
|
|
2
|
+
import { a0 as UiSize, C as CommonUiProps, Q as SpButtonProps, R as SpCardProps, T as SpCheckboxProps, V as SpDividerProps, W as SpInputProps, X as SpSwitchProps } from './types-D5ys35fF.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The markup contract of the UI components (API delta §4), as data: every adapter writes this tree
|
|
6
|
+
* and nothing else, and the parity gate compares each adapter's server render with it (REQ-327).
|
|
7
|
+
* An adapter binds behaviour —value, events, forms— to the elements marked `bind`, and puts the
|
|
8
|
+
* consumer's content where a `slot` stands. It computes nothing (Art. 2).
|
|
9
|
+
*/
|
|
10
|
+
type UiAttrValue = string | true;
|
|
11
|
+
interface UiElement {
|
|
12
|
+
readonly tag: string;
|
|
13
|
+
/** HTML attribute names; `true` is a boolean attribute. */
|
|
14
|
+
readonly attrs: Readonly<Record<string, UiAttrValue>>;
|
|
15
|
+
readonly children: readonly UiNode[];
|
|
16
|
+
/** What an adapter binds to the element: see `UiBind`. */
|
|
17
|
+
readonly bind?: UiBind;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* `native`: a control an adapter binds value, events and forms to —one, or one per item of a
|
|
21
|
+
* composite, told apart by its `value` or `data-key`. `close`: the button that emits `close`.
|
|
22
|
+
* `sort`, `page`, `stepper`: a Table header (`data-key`), a Pagination button (`data-page`), an
|
|
23
|
+
* InputNumber stepper (`data-step`); `summary`: a CollapseItem's toggle; `trigger`, `dialog`,
|
|
24
|
+
* `popover`, `option`, `menuitem`: the parts of an overlay (TD §2).
|
|
25
|
+
*/
|
|
26
|
+
type UiBind = 'native' | 'close' | 'trigger' | 'dialog' | 'popover' | 'option' | 'menuitem' | 'sort' | 'page' | 'stepper' | 'summary' | 'probe' | 'mount';
|
|
27
|
+
type UiSlot = 'content' | 'prefix' | 'suffix' | 'extra' | 'footer' | 'trigger' | 'action' | 'fallback';
|
|
28
|
+
type UiNode = UiElement | {
|
|
29
|
+
readonly text: string;
|
|
30
|
+
} | {
|
|
31
|
+
readonly slot: UiSlot;
|
|
32
|
+
};
|
|
33
|
+
/** What a component inherits around it: the provider, the dashboard cell, the environment. */
|
|
34
|
+
interface UiEnvironment {
|
|
35
|
+
readonly provider?: ProviderConfig;
|
|
36
|
+
/** The configuration of the dashboard whose cell holds the component (REQ-311). */
|
|
37
|
+
readonly cell?: ProviderConfig;
|
|
38
|
+
/** `prefers-contrast: more` or `forced-colors: active` holds (REQ-123). */
|
|
39
|
+
readonly forcedPrecision?: boolean;
|
|
40
|
+
}
|
|
41
|
+
interface UiResolved {
|
|
42
|
+
readonly ground: string;
|
|
43
|
+
readonly substrate: SubstrateName;
|
|
44
|
+
readonly mode: InkMode;
|
|
45
|
+
readonly size: UiSize;
|
|
46
|
+
/** 0..5: `ui.css` folds it onto the variants the ground draws. */
|
|
47
|
+
readonly frame: number;
|
|
48
|
+
/** The resolved palette's declarations, first in the root's `style`; '' for none (REQ-461). */
|
|
49
|
+
readonly palette?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Ground, substrate, mode and palette with the charts' precedence: prop, then dashboard, then provider,
|
|
53
|
+
* then the library default; a forced `precision` applies after, and nothing overrides it (REQ-311).
|
|
54
|
+
*/
|
|
55
|
+
declare function resolveUi(props: CommonUiProps, env: UiEnvironment): UiResolved;
|
|
56
|
+
/** `SpButton`: a native `<button>`, or `<a>` with `href` (REQ-314, REQ-310). */
|
|
57
|
+
declare function uiButtonView(props: SpButtonProps, r: UiResolved, content: {
|
|
58
|
+
readonly text?: string;
|
|
59
|
+
}): UiElement;
|
|
60
|
+
/** `SpInput`: a native `<input>` in a framed box, its message after it (REQ-314, REQ-334). */
|
|
61
|
+
declare function uiInputView(props: SpInputProps, r: UiResolved, state: {
|
|
62
|
+
readonly value: string;
|
|
63
|
+
readonly prefix?: boolean;
|
|
64
|
+
readonly suffix?: boolean;
|
|
65
|
+
}): UiElement;
|
|
66
|
+
/** `SpCheckbox`: native state; the tick and dash are drawn and shown by it (REQ-310). */
|
|
67
|
+
declare function uiCheckboxView(props: SpCheckboxProps, r: UiResolved, state: {
|
|
68
|
+
readonly checked: boolean;
|
|
69
|
+
}): UiElement;
|
|
70
|
+
/** `SpSwitch`: a native checkbox with `role="switch"`, a pill track and an exact knob (REQ-314). */
|
|
71
|
+
declare function uiSwitchView(props: SpSwitchProps, r: UiResolved, state: {
|
|
72
|
+
readonly checked: boolean;
|
|
73
|
+
}): UiElement;
|
|
74
|
+
/** `SpCard`: an `<article>` named by its heading, or a `<section>` without a title (REQ-318). */
|
|
75
|
+
declare function uiCardView(props: SpCardProps, r: UiResolved, slots: {
|
|
76
|
+
readonly extra?: boolean;
|
|
77
|
+
readonly footer?: boolean;
|
|
78
|
+
}): UiElement;
|
|
79
|
+
/** `SpDivider`: a `separator`; with text, the text between two rules (REQ-318). */
|
|
80
|
+
declare function uiDividerView(props: SpDividerProps, r: UiResolved): UiElement;
|
|
81
|
+
|
|
82
|
+
export { type UiResolved as U, type UiElement as a, type UiAttrValue as b, type UiBind as c, type UiEnvironment as d, type UiNode as e, type UiSlot as f, uiCardView as g, uiCheckboxView as h, uiDividerView as i, uiInputView as j, uiSwitchView as k, resolveUi as r, uiButtonView as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silverpoint/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Geometry, scales, interaction and the Inker interface of silverpoint. No DOM, no framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,6 +39,18 @@
|
|
|
39
39
|
"import": "./dist/catalog.js",
|
|
40
40
|
"default": "./dist/catalog.js"
|
|
41
41
|
},
|
|
42
|
+
"./palettes": {
|
|
43
|
+
"@silverpoint/source": "./src/palettes.ts",
|
|
44
|
+
"types": "./dist/palettes.d.ts",
|
|
45
|
+
"import": "./dist/palettes.js",
|
|
46
|
+
"default": "./dist/palettes.js"
|
|
47
|
+
},
|
|
48
|
+
"./timeline": {
|
|
49
|
+
"@silverpoint/source": "./src/timeline/index.ts",
|
|
50
|
+
"types": "./dist/timeline.d.ts",
|
|
51
|
+
"import": "./dist/timeline.js",
|
|
52
|
+
"default": "./dist/timeline.js"
|
|
53
|
+
},
|
|
42
54
|
"./package.json": "./package.json"
|
|
43
55
|
},
|
|
44
56
|
"files": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/round.ts","../src/render/seed.ts","../src/diagnostics/diagnose.ts","../src/scales/util.ts","../src/scales/scales.ts","../src/charts/shared/format.ts","../src/charts/shared/cells.ts","../src/charts/shared/cartesian.ts","../src/charts/shared/polar.ts"],"names":["read","format","at"],"mappings":"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","file":"chunk-OLYKR5PS.js","sourcesContent":["import type { Geometry, Rect, Stroke, Tile } from '../types';\n\n/** Rounds to 2 decimals, the precision of every emitted coordinate (REQ-002). */\nexport function round2(value: number): number {\n const rounded = Math.round(value * 100) / 100;\n return Object.is(rounded, -0) ? 0 : rounded;\n}\n\nconst NUMBER = /-?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][-+]?\\d+)?/g;\n\n/** Rounds every number inside SVG path data to 2 decimals. */\nexport function roundPathData(d: string): string {\n return d.replace(NUMBER, (token) => String(round2(Number(token))));\n}\n\nfunction roundRect(rect: Rect): Rect {\n return {\n x: round2(rect.x),\n y: round2(rect.y),\n width: round2(rect.width),\n height: round2(rect.height),\n };\n}\n\nfunction roundStroke(stroke: Stroke): Stroke {\n return { ...stroke, d: roundPathData(stroke.d) };\n}\n\nfunction roundTile(tile: Tile): Tile {\n return {\n ...tile,\n width: round2(tile.width),\n height: round2(tile.height),\n angle: round2(tile.angle),\n strokes: tile.strokes.map(roundStroke),\n };\n}\n\n/** Rounds all coordinates of a geometry to 2 decimals, returning a new object (REQ-002). */\nexport function roundGeometry(geometry: Geometry): Geometry {\n return {\n viewBox: roundRect(geometry.viewBox),\n plot: roundRect(geometry.plot),\n strokes: geometry.strokes.map(roundStroke),\n labels: geometry.labels.map((label) => ({ ...label, x: round2(label.x), y: round2(label.y) })),\n hitAreas: geometry.hitAreas.map((hit) => ({\n ...hit,\n x: round2(hit.x),\n y: round2(hit.y),\n ...(hit.box ? { box: roundRect(hit.box) } : {}),\n })),\n defs: geometry.defs.map(roundTile),\n };\n}\n","import type { Seed } from '../types';\n\nconst FNV_OFFSET_BASIS = 0x811c9dc5;\nconst FNV_PRIME = 0x01000193;\n\nfunction utf8Bytes(input: string): number[] {\n const bytes: number[] = [];\n for (const char of input) {\n const code = char.codePointAt(0) ?? 0;\n if (code < 0x80) {\n bytes.push(code);\n } else if (code < 0x800) {\n bytes.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));\n } else if (code < 0x10000) {\n bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));\n } else {\n bytes.push(\n 0xf0 | (code >> 18),\n 0x80 | ((code >> 12) & 0x3f),\n 0x80 | ((code >> 6) & 0x3f),\n 0x80 | (code & 0x3f),\n );\n }\n }\n return bytes;\n}\n\n/**\n * 32-bit FNV-1a over the UTF-8 bytes of the input (DD-006).\n *\n * Frozen by SemVer: changing it changes every derived seed, and with it every golden image.\n */\nexport function fnv1a32(input: string): number {\n let hash = FNV_OFFSET_BASIS;\n for (const byte of utf8Bytes(input)) {\n hash ^= byte;\n hash = Math.imul(hash, FNV_PRIME);\n }\n return hash >>> 0;\n}\n\n/** Derives the seed of a chart from its identifier (REQ-003). */\nexport function deriveSeed(id: string): number {\n return fnv1a32(id);\n}\n\n/** `seed ?? derive(id)`, with string seeds hashed and numbers taken as unsigned 32-bit. */\nexport function resolveSeed(seed: Seed | undefined, id: string): number {\n if (seed === undefined) return deriveSeed(id);\n if (typeof seed === 'string') return fnv1a32(seed);\n return Number.isFinite(seed) ? Math.trunc(seed) >>> 0 : 0;\n}\n","/** Stable diagnostic codes, part of the public surface (API Spec §11). */\nexport type SpCode =\n | 'SP001'\n | 'SP002'\n | 'SP003'\n | 'SP004'\n | 'SP005'\n | 'SP006'\n | 'SP007'\n | 'SP008'\n | 'SP009'\n | 'SP010'\n | 'SP011'\n | 'SP012'\n | 'SP013'\n | 'SP014'\n | 'SP015'\n | 'SP016'\n | 'SP017'\n | 'SP018'\n | 'SP019'\n | 'SP020'\n | 'SP021'\n | 'SP022';\n\nexport interface Detail {\n /** The property involved. */\n readonly property: string;\n /** Specifics of this occurrence, appended to what happened. */\n readonly message?: string;\n}\n\ninterface Template {\n readonly req: string;\n readonly what: string;\n readonly todo: string;\n}\n\n/** Thrown by diagnostics of `error` severity. */\nexport class SilverpointError extends Error {\n readonly code: SpCode;\n\n constructor(code: SpCode, message: string) {\n super(message);\n this.name = 'SilverpointError';\n this.code = code;\n }\n}\n\n/** Receives every warning; replaceable so tests and tools can observe diagnostics. */\nexport type DiagnosticSink = (code: SpCode, message: string) => void;\n\nconst consoleSink: DiagnosticSink = (_code, message) => {\n console.warn(message);\n};\n\nlet sink: DiagnosticSink = consoleSink;\nconst reported = new Set<string>();\n\n/**\n * Replaces the warning sink and forgets already reported warnings. Returns a function that\n * restores the console sink.\n * @internal\n */\nexport function __setDiagnosticSink(next: DiagnosticSink | null): () => void {\n sink = next ?? consoleSink;\n reported.clear();\n return () => {\n sink = consoleSink;\n reported.clear();\n };\n}\n\nfunction format(code: SpCode, chart: string, detail: Detail, template: Template): string {\n const specifics = detail.message ? ` ${detail.message}` : '';\n return `[${code}] ${chart}: ${template.what} (\\`${detail.property}\\`).${specifics} ${template.todo}. (${template.req})`;\n}\n\n/** Always shipped: these diagnostics throw in every build (TD §5.4). */\nconst ERRORS: Partial<Record<SpCode, Template>> = {\n SP009: {\n req: 'REQ-097',\n what: 'a scale bound cannot be derived from the data and was not supplied',\n todo: 'Pass the named property explicitly',\n },\n SP012: {\n req: 'REQ-127',\n what: 'the ground does not reach the minimum contrast',\n todo: 'Recompute the palette; colours are not chosen by eye',\n },\n};\n\n/**\n * The single diagnostic channel (TD §5.4). `error` codes always throw; `warn` codes reach\n * the sink only outside production and are stripped from production bundles.\n */\nexport function diagnose(code: SpCode, chart: string, detail: Detail): void {\n const error = ERRORS[code];\n if (error) {\n throw new SilverpointError(code, format(code, chart, detail, error));\n }\n if (process.env.NODE_ENV !== 'production') {\n developmentDiagnose(code, chart, detail);\n }\n}\n\nfunction developmentDiagnose(code: SpCode, chart: string, detail: Detail): void {\n const template = WARNINGS[code];\n if (!template) return;\n const message = format(code, chart, detail, template);\n // SP005 is an error in development and a stripped warning in production (REQ-025).\n if (code === 'SP005') {\n throw new SilverpointError(code, message);\n }\n if (reported.has(message)) return;\n reported.add(message);\n sink(code, message);\n}\n\nconst WARNINGS: Partial<Record<SpCode, Template>> = {\n SP001: {\n req: 'REQ-007',\n what: 'the dataset is empty; the ground\\'s empty state is drawn',\n todo: 'Pass at least one row, or omit `data` to see the demo dataset',\n },\n SP002: {\n req: 'REQ-008',\n what: 'a value cannot be drawn as given (null, not finite, or outside the data contract); it is corrected or omitted',\n todo: 'Check the value against the chart\\'s data contract (Data Model §2)',\n },\n SP003: {\n req: 'REQ-009',\n what: 'the container measures 0 px; the render is deferred',\n todo: 'Give the container a size, or pin `width` and `height`',\n },\n SP004: {\n req: 'REQ-010',\n what: 'the scale domain has zero length; it is expanded with the ground\\'s domainPadding',\n todo: 'Nothing to do if the data is constant; otherwise check the accessor',\n },\n SP005: {\n req: 'REQ-025',\n what: 'more than one element is marked with white heightening; only the first is applied',\n todo: 'Heighten a single element per chart',\n },\n SP006: {\n req: 'REQ-026',\n what: 'the inker is not registered; falling back to NullInker',\n todo: 'Register the inker or fix the ground\\'s `inker` token',\n },\n SP007: {\n req: 'REQ-045',\n what: 'the ground is not registered; falling back to silverpoint',\n todo: 'Call registerGround() before rendering, or fix the name',\n },\n SP008: {\n req: 'REQ-096',\n what: 'the data volume is above the family\\'s threshold',\n todo: 'Aggregate the data before charting it',\n },\n SP010: {\n req: 'REQ-091',\n what: 'the chord ring has more than 12 categories',\n todo: 'Group the smaller categories',\n },\n SP011: {\n req: 'NFR §7',\n what: 'the path byte budget of 40 KB is exceeded',\n todo: \"Use `hatchFill: 'tile'` or a larger hatch gap\",\n },\n SP014: {\n req: 'REQ-204',\n what: 'a dashboard cell spans more columns than the breakpoint has; it is clamped',\n todo: 'Lower the span, or give that breakpoint more columns',\n },\n SP015: {\n req: 'REQ-205',\n what: 'the dashboard layout and its children disagree; unmatched children are placed in source order, span 1',\n todo: 'Give every child a `cell` the layout declares, once',\n },\n SP016: {\n req: 'REQ-217',\n what: 'a chart in a linked dashboard has no field named by `link.key`; it shows no linked mark',\n todo: 'Link on a field every linked chart carries, or leave this chart out of the link',\n },\n SP017: {\n req: 'REQ-324',\n what: 'a value or a range cannot be drawn as given; it is clamped, rounded to its step or defaulted',\n todo: 'Keep the value within `min`..`max` and on `step`, with `min < max` and `step > 0`',\n },\n SP018: {\n req: 'REQ-319',\n what: 'the component has no accessible name: no text content and no `label`',\n todo: 'Give it visible text, or a `label` for an icon-only control',\n },\n SP019: {\n req: 'REQ-325',\n what: 'items share a key, or have none; the first is kept and the later ones are skipped',\n todo: 'Give every item a unique, non-empty `key`',\n },\n SP020: {\n req: 'REQ-437',\n what: 'the hierarchy is invalid (a duplicate or empty `id`, a missing `parent`, a cycle, or several roots); the offending rows are dropped',\n todo: 'Give every row a unique `id` and an existing `parent`, under a single root',\n },\n SP021: {\n req: 'REQ-433',\n what: 'a statistic parameter is invalid; its default is used',\n todo: 'Keep the parameter in its documented range',\n },\n SP022: {\n req: 'REQ-434',\n what: 'a group has too few observations for its statistic; they are drawn as points',\n todo: 'Give the group more observations, or expect it drawn as points',\n },\n SP013: {\n req: 'REQ-032',\n what: 'the @silverpoint/fonts face failed to load; rendering fell back to the system stack',\n todo: 'Install @silverpoint/fonts and import its stylesheet; golden images will not match until then',\n },\n};\n","/**\n * `extent`, `min` and `max` are owned here instead of imported from `d3-array`, which is\n * not in the allowlist (TD §5.3).\n */\n\nexport function min(values: readonly number[]): number | undefined {\n let result: number | undefined;\n for (const value of values) {\n if (Number.isFinite(value) && (result === undefined || value < result)) result = value;\n }\n return result;\n}\n\nexport function max(values: readonly number[]): number | undefined {\n let result: number | undefined;\n for (const value of values) {\n if (Number.isFinite(value) && (result === undefined || value > result)) result = value;\n }\n return result;\n}\n\nexport function extent(values: readonly number[]): [number, number] | undefined {\n const low = min(values);\n const high = max(values);\n return low === undefined || high === undefined ? undefined : [low, high];\n}\n","import { scaleBand, scaleLinear } from 'd3-scale';\nimport { diagnose } from '../diagnostics/diagnose';\n\nexport interface ScaleSite {\n /** Chart name, for diagnostics. */\n readonly chart: string;\n /** Property the domain comes from, for diagnostics. */\n readonly property: string;\n}\n\n/**\n * Expands a zero-length domain by the ground's `domainPadding` instead of dividing by zero\n * (REQ-010). A constant `v` becomes `[v - |v|·p, v + |v|·p]`, or `[-p, p]` around zero — `[0, 2p]`\n * on a zero-based axis, which never shows a value below zero that no datum has.\n */\nexport function expandDomain(\n domain: readonly [number, number],\n padding: number,\n site: ScaleSite,\n /** A zero-based axis (bars, areas): a flat zero domain grows upward only, never below zero. */\n fromZero = false,\n): [number, number] {\n const [low, high] = domain;\n if (low !== high) return [low, high];\n const spread = low === 0 ? padding : Math.abs(low) * padding;\n if (fromZero && low === 0) {\n if (process.env.NODE_ENV !== 'production') {\n diagnose('SP004', site.chart, { property: site.property, message: `Domain [0, 0] became [0, ${2 * spread}].` });\n }\n return [0, 2 * spread];\n }\n if (process.env.NODE_ENV !== 'production') {\n diagnose('SP004', site.chart, {\n property: site.property,\n message: `Domain [${low}, ${high}] became [${low - spread}, ${high + spread}].`,\n });\n }\n return [low - spread, high + spread];\n}\n\nexport interface LinearScale {\n (value: number): number;\n readonly domain: readonly [number, number];\n ticks(count: number): number[];\n}\n\n/** Linear scale over `d3-scale`, with degenerate-domain expansion. */\nexport function linearScale(\n domain: readonly [number, number],\n range: readonly [number, number],\n options: ScaleSite & { readonly padding: number; readonly nice?: boolean; readonly fromZero?: boolean },\n): LinearScale {\n const expanded = expandDomain(domain, options.padding, options, options.fromZero);\n const scale = scaleLinear().domain(expanded).range(range);\n if (options.nice) scale.nice(4);\n const [low, high] = scale.domain() as [number, number];\n const result = ((value: number) => scale(value)) as LinearScale;\n Object.defineProperty(result, 'domain', { value: [low, high] as const });\n (result as { ticks: LinearScale['ticks'] }).ticks = (count) => scale.ticks(count);\n return result;\n}\n\nexport interface BandScale {\n /** Start of the band, or `undefined` for a value outside the domain. */\n (value: string): number | undefined;\n readonly bandwidth: number;\n /** Centre of the band. */\n center(value: string): number | undefined;\n}\n\n/** Band scale over `d3-scale`. */\nexport function bandScale(\n domain: readonly string[],\n range: readonly [number, number],\n options: { readonly paddingInner?: number; readonly paddingOuter?: number } = {},\n): BandScale {\n const scale = scaleBand<string>()\n .domain(domain)\n .range(range)\n .paddingInner(options.paddingInner ?? 0)\n .paddingOuter(options.paddingOuter ?? 0);\n const bandwidth = scale.bandwidth();\n const result = ((value: string) => scale(value)) as BandScale;\n Object.defineProperty(result, 'bandwidth', { value: bandwidth });\n (result as { center: BandScale['center'] }).center = (value) => {\n const start = scale(value);\n return start === undefined ? undefined : start + bandwidth / 2;\n };\n return result;\n}\n","import type { Accessor, Datum } from '../../types';\n\n/** Reads a field through an accessor. */\nexport function read<T>(accessor: Accessor<T>, datum: Datum, index: number): T {\n return typeof accessor === 'function' ? accessor(datum, index) : (datum[accessor] as T);\n}\n\n/** Human name of an accessor, for tables and descriptions. */\nexport function accessorName(accessor: Accessor<unknown>, fallback: string): string {\n return typeof accessor === 'string' ? accessor : fallback;\n}\n\n/** Formatters already built, by locale and options: building one costs more than a label (TD §2). */\nconst FORMATTERS = /* @__PURE__ */ new Map<string, Intl.NumberFormat>();\n/** Distinct locale-and-options pairs kept; past it the cache starts over, so it stays bounded. */\nconst MAX_FORMATTERS = 64;\n\n/** Formats a number with the resolved locale. Formatting lives in the core so both adapters agree. */\nexport function formatNumber(\n value: number,\n locale: string,\n options: Intl.NumberFormatOptions | undefined,\n): string {\n const resolved = options ?? { maximumFractionDigits: 2 };\n // Every option Intl reads, inherited ones included: JSON.stringify sees own properties only.\n const read: string[] = [];\n for (const name in resolved) read.push(`${name}=${JSON.stringify(resolved[name as keyof Intl.NumberFormatOptions])}`);\n const key = `${locale}|${read.sort().join('&')}`;\n let formatter = FORMATTERS.get(key);\n if (!formatter) {\n if (FORMATTERS.size >= MAX_FORMATTERS) FORMATTERS.clear();\n formatter = new Intl.NumberFormat(locale, resolved);\n FORMATTERS.set(key, formatter);\n }\n return formatter.format(value);\n}\n\n/**\n * `formatNumber` with its formatter resolved once, for a column of many values — a table with a\n * row per observation (REQ-445): the same constructor and arguments, so the same text, without\n * rebuilding the cache key for every cell.\n */\nexport function numberFormatter(locale: string, options: Intl.NumberFormatOptions | undefined): (value: number) => string {\n const formatter = new Intl.NumberFormat(locale, options ?? { maximumFractionDigits: 2 });\n return (value) => formatter.format(value);\n}\n\n/** Formats a label that may be a number or free text. */\nexport function formatValue(\n value: unknown,\n locale: string,\n options: Intl.NumberFormatOptions | undefined,\n): string {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? formatNumber(value, locale, options) : '—';\n }\n return value === null || value === undefined ? '—' : String(value);\n}\n\n/**\n * Formats a category — an x value, a time, a stage, a name. A number here is an identifier such as\n * a year, so it is printed without grouping: 2020, never 2,020.\n */\nexport function formatCategory(value: unknown, locale: string): string {\n return formatValue(value, locale, typeof value === 'number' ? { useGrouping: false, maximumFractionDigits: 2 } : undefined);\n}\n\n/** SVG path of a circle, drawn as two arcs so it survives inking as a closed path. */\nexport function circlePath(cx: number, cy: number, r: number): string {\n return `M${cx - r},${cy}A${r},${r},0,1,0,${cx + r},${cy}A${r},${r},0,1,0,${cx - r},${cy}Z`;\n}\n\n/** A change with its sign written out — `+4`, `−8` (U+2212), `0` — so direction never rests on shape alone (REQ-440). */\nexport function signedChange(change: number, format: (value: number) => string): string {\n if (change > 0) return `+${format(change)}`;\n if (change < 0) return `−${format(-change)}`;\n return format(0);\n}\n\n/** Advance of one character at the tick size, as `TICK_CHAR` in cartesian.ts measures it. */\nconst CHAR = 5.2;\n\n/**\n * Text cut with an ellipsis to fit `width` px at the tick size. A name cut on the drawing is still\n * whole in the table and the readout (REQ-121), so nothing is lost to the reader.\n */\nexport function fitText(text: string, width: number): string {\n const fits = Math.max(Math.floor(width / CHAR), 2);\n return text.length > fits ? `${text.slice(0, fits - 1)}…` : text;\n}\n","import { diagnose } from '../../diagnostics/diagnose';\nimport type { Rect, ToneLevel } from '../../types';\n\n/** Closed path of a rectangle, clockwise from its top-left corner. */\nexport function rectPath(rect: Rect): string {\n const { x, y, width, height } = rect;\n return `M${x},${y}H${x + width}V${y + height}H${x}Z`;\n}\n\n/** A rectangle shrunk by `by` on every side, never below zero size. */\nexport function inset(rect: Rect, by: number): Rect {\n return {\n x: rect.x + by,\n y: rect.y + by,\n width: Math.max(rect.width - 2 * by, 0),\n height: Math.max(rect.height - 2 * by, 0),\n };\n}\n\n/** A finite number, or `undefined`. */\nexport function finite(raw: unknown): number | undefined {\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\n/**\n * Tonal level of a value normalised to 0-1: none at or below 0, then quarters (Data Model §3.4).\n * The tone always repeats a value the chart also prints or draws by length or size (REQ-124).\n */\nexport function toneOf(ratio: number): ToneLevel {\n if (!(ratio > 0)) return 0;\n if (ratio <= 0.25) return 1;\n if (ratio <= 0.5) return 2;\n if (ratio <= 0.75) return 3;\n return 4;\n}\n\n/**\n * Side of a mark, as a share of its slot, per tone: where a value cannot be printed, its size\n * carries the level the tone shows, so it survives `precision` mode (REQ-124). The heatmap's cells\n * when their values do not fit, the density bins always.\n */\nexport const TONE_SCALE: Readonly<Record<ToneLevel, number>> = { 0: 0.4, 1: 0.55, 2: 0.7, 3: 0.85, 4: 1 };\n\n/** A consumer-supplied tone, rounded and held to 0-4. */\nexport function toneLevel(raw: number): ToneLevel {\n return Math.min(Math.max(Math.round(raw), 0), 4) as ToneLevel;\n}\n\n/** A value outside what the chart can draw: it is corrected or dropped, and warned (SP002). */\nexport function warnValue(chart: string, property: string, message: string): void {\n if (process.env.NODE_ENV !== 'production') diagnose('SP002', chart, { property, message });\n}\n\nconst RING_TONES: readonly ToneLevel[] = [1, 2, 3, 4];\n\n/**\n * The tone of sector `index` of `count` around a closed ring: the ramp in turn, and the last sector\n * never repeats the first, its neighbour across 12 o'clock. Tone only repeats what the legend and\n * the printed shares say (REQ-124). Every chart with categories tones them this way — a ring, a\n * waffle, a mosaic, a hierarchy's first level, a network's groups (DD-032, REQ-440).\n */\nexport function ringTone(index: number, count: number): ToneLevel {\n const tone = RING_TONES[index % RING_TONES.length] as ToneLevel;\n if (count > 1 && index === count - 1 && tone === RING_TONES[0]) return RING_TONES[2] as ToneLevel;\n return tone;\n}\n\n/**\n * The tones of a ring's sectors, counted over the drawn ones only: a zero sector is not drawn, so it\n * must not hold a place in the ramp, or two drawn neighbours could share a tone. A zero sector takes\n * the tone its place would have, for its legend swatch.\n */\nexport function ringTones(values: readonly number[]): ToneLevel[] {\n const drawn = values.filter((v) => v > 0).length;\n let k = 0;\n return values.map((v) => (v > 0 ? ringTone(k++, drawn) : ringTone(Math.min(k, Math.max(drawn - 1, 0)), drawn)));\n}\n","import { bandScale, linearScale, type LinearScale } from '../../scales/scales';\nimport { extent } from '../../scales/util';\nimport type { Accessor, Datum, Rect, Stroke, TextLabel, ToneLevel } from '../../types';\nimport { rectPath } from './cells';\nimport { diagnose } from '../../diagnostics/diagnose';\nimport { accessorName, formatNumber, read } from './format';\n\n/** Room under the plot for the category labels. */\nexport const AXIS_BAND = 20;\n/** Room around the plot so a heightened point or a pill end is never clipped. */\nexport const PLOT_INSET = 6;\n/** Minimum horizontal room per category label. */\nconst LABEL_SPACING = 48;\n\n/** The plot of a cartesian chart inside its drawing area: inset, with the axis band below. */\nexport function cartesianPlot(area: Rect): Rect {\n return {\n x: area.x + PLOT_INSET,\n y: area.y + PLOT_INSET,\n width: Math.max(area.width - 2 * PLOT_INSET, 1),\n height: Math.max(area.height - AXIS_BAND - PLOT_INSET, 1),\n };\n}\n\nexport interface SeriesPoint {\n readonly index: number;\n readonly datum: Datum;\n readonly value: number | undefined;\n}\n\nexport interface Series {\n readonly key: string;\n readonly points: readonly SeriesPoint[];\n /** Points whose value is not a finite number. */\n readonly missing: number;\n}\n\n/** Reads one numeric series through an accessor; non-finite values become gaps. */\nexport function readSeries(data: readonly Datum[], accessor: Accessor<number | null | undefined>, fallbackName: string): Series {\n let missing = 0;\n const points = data.map((datum, index) => {\n const raw = read(accessor, datum, index);\n const value = typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n if (value === undefined) missing += 1;\n return { index, datum, value };\n });\n return { key: accessorName(accessor, fallbackName), points, missing };\n}\n\n/** Points per series a cartesian chart draws before it recommends aggregation (API Spec §12). */\nexport const POINTS_PER_SERIES = 500;\n\n/**\n * Warns SP008 when a series runs past the family's ceiling. The series is still drawn in full:\n * the warning recommends aggregation, it never degrades silently (REQ-096).\n */\nexport function checkVolume(chart: string, series: readonly Series[]): void {\n for (const s of series) checkCount(chart, s.key, s.points.length);\n}\n\n/** The same ceiling, for a chart whose points are not read as a `Series`. */\nexport function checkCount(chart: string, property: string, count: number): void {\n if (process.env.NODE_ENV === 'production' || count <= POINTS_PER_SERIES) return;\n diagnose('SP008', chart, { property, message: `${count} points; the ceiling is ${POINTS_PER_SERIES} per series.` });\n}\n\n/** The finite values of a set of series. */\nexport function seriesValues(series: readonly Series[]): number[] {\n return series.flatMap((s) => s.points.flatMap((p) => (p.value === undefined ? [] : [p.value])));\n}\n\nexport interface ValueAxis {\n readonly scale: LinearScale;\n readonly strokes: readonly Stroke[];\n readonly labels: readonly TextLabel[];\n}\n\n/**\n * The vertical value scale of a cartesian chart, niced, with its grid lines and tick labels and\n * the base rule. The domain always reaches zero when `zero` is set, as bars and areas need.\n */\nexport function valueAxis(\n plot: Rect,\n domain: readonly [number, number],\n options: {\n readonly chart: string;\n readonly property: string;\n readonly padding: number;\n readonly locale: string;\n readonly numberFormat: Intl.NumberFormatOptions | undefined;\n readonly zero?: boolean;\n /** Round the domain out to tick values; `true` by default. Pinned bounds pass `false`. */\n readonly nice?: boolean;\n },\n): ValueAxis {\n const bottom = plot.y + plot.height;\n const low = options.zero === false ? domain[0] : Math.min(0, domain[0]);\n const high = options.zero === false ? domain[1] : Math.max(0, domain[1]);\n const scale = linearScale([low, high], [bottom, plot.y], {\n chart: options.chart,\n property: options.property,\n padding: options.padding,\n nice: options.nice !== false,\n fromZero: options.zero !== false,\n });\n const strokes: Stroke[] = [];\n const labels: TextLabel[] = [];\n for (const tick of scale.ticks(4)) {\n const ty = scale(tick);\n if (tick === scale.domain[0]) continue;\n strokes.push({ d: `M${plot.x},${ty}H${plot.x + plot.width}`, role: 'ornament', part: 'grid' });\n labels.push({ x: plot.x, y: ty - 3, text: formatNumber(tick, options.locale, options.numberFormat), kind: 'tick', part: 'axis', anchor: 'start' });\n }\n strokes.push({ d: `M${plot.x},${bottom}H${plot.x + plot.width}`, role: 'ornament', part: 'rule' });\n return { scale, strokes, labels };\n}\n\nexport interface CategoryAxis {\n /** Centre of item `index` along x. */\n at(index: number): number;\n /** Width of one category's band; 0 on a numeric axis. */\n readonly bandwidth: number;\n}\n\n/**\n * Positions along x: a linear scale when every x value is a finite number, otherwise one band per\n * row, whose centre is the item's position.\n */\nexport function categoryAxis(\n xValues: readonly unknown[],\n plot: Rect,\n options: { readonly chart: string; readonly property: string; readonly padding: number; readonly paddingInner?: number; readonly paddingOuter?: number; readonly numeric?: boolean },\n): CategoryAxis {\n const numeric = options.numeric !== false && xValues.length > 0 && xValues.every((v) => typeof v === 'number' && Number.isFinite(v));\n if (numeric) {\n const numbers = xValues as number[];\n const x = linearScale(extent(numbers) ?? [0, 0], [plot.x, plot.x + plot.width], {\n chart: options.chart,\n property: options.property,\n padding: options.padding,\n });\n return { at: (index) => x(numbers[index] ?? 0), bandwidth: 0 };\n }\n const keys = xValues.map((_, index) => String(index));\n const band = bandScale(keys, [plot.x, plot.x + plot.width], { paddingInner: options.paddingInner, paddingOuter: options.paddingOuter });\n return { at: (index) => band.center(String(index)) ?? plot.x, bandwidth: band.bandwidth };\n}\n\n/** Category labels under the plot, thinned so they never crowd: one every `step` items. */\nexport function categoryLabels(texts: readonly string[], at: (index: number) => number, area: Rect, plot: Rect): TextLabel[] {\n const count = texts.length;\n const step = Math.max(1, Math.ceil(count / Math.max(2, Math.floor(plot.width / LABEL_SPACING))));\n const labels: TextLabel[] = [];\n for (let index = 0; index < count; index += step) {\n labels.push({\n x: at(index),\n y: area.y + area.height - 5,\n text: texts[index] ?? '',\n kind: 'tick',\n part: 'axis',\n anchor: index === 0 ? 'start' : 'middle',\n });\n }\n return labels;\n}\n\n/** Height of the legend row at the top of the drawing area: a full line above the top value tick. */\nexport const LEGEND_BAND = 22;\n/** Advance of one character of tick or legend text at the 9.5 px tick size. */\nexport const TICK_CHAR = 5.2;\nconst LEGEND_CHAR = TICK_CHAR;\n\nexport interface LegendEntry {\n readonly name: string;\n readonly part: 'ink' | 'ink-secondary';\n readonly tone?: ToneLevel;\n readonly dash?: 'dotted';\n}\n\n/**\n * A legend row at the top of the area: a swatch drawn like its series — outline, dash and tone —\n * and the series' name. The swatch carries no data, so it is an ornament; the name is what tells\n * the series apart, never the tone alone (REQ-124). Returns the area left below it.\n */\nexport function legend(area: Rect, entries: readonly LegendEntry[]): { area: Rect; strokes: Stroke[]; labels: TextLabel[] } {\n const strokes: Stroke[] = [];\n const labels: TextLabel[] = [];\n let x = area.x + PLOT_INSET;\n for (const entry of entries) {\n const swatch = { x, y: area.y + 4, width: 12, height: 7 };\n strokes.push({ d: rectPath(swatch), role: 'ornament', part: entry.part, ...(entry.tone ? { tone: entry.tone } : {}), ...(entry.dash ? { dash: entry.dash } : {}) });\n labels.push({ x: x + 16, y: area.y + 11, text: entry.name, kind: 'tick', part: 'axis', anchor: 'start' });\n x += 16 + entry.name.length * LEGEND_CHAR + 12;\n }\n return { area: { x: area.x, y: area.y + LEGEND_BAND, width: area.width, height: Math.max(area.height - LEGEND_BAND, 1) }, strokes, labels };\n}\n\n/** A rectangle with fully rounded ends — a pill — as a closed path of lines and arcs. */\nexport function pillPath(rect: Rect): string {\n const { x, y, width, height } = rect;\n const r = Math.min(width, height) / 2;\n if (r <= 0) return `M${x},${y}H${x + width}V${y + height}H${x}Z`;\n return (\n `M${x},${y + r}A${r},${r},0,0,1,${x + r},${y}H${x + width - r}A${r},${r},0,0,1,${x + width},${y + r}` +\n `V${y + height - r}A${r},${r},0,0,1,${x + width - r},${y + height}H${x + r}A${r},${r},0,0,1,${x},${y + height - r}Z`\n );\n}\n\n/**\n * The horizontal value scale of a chart laid out in rows: niced, zero in the domain, with vertical\n * grid lines and tick labels under the plot, and the base rule at zero.\n */\nexport function horizontalValueAxis(\n plot: Rect,\n area: Rect,\n domain: readonly [number, number],\n options: { readonly chart: string; readonly property: string; readonly padding: number; readonly locale: string; readonly numberFormat: Intl.NumberFormatOptions | undefined },\n): ValueAxis {\n const scale = linearScale([Math.min(0, domain[0]), Math.max(0, domain[1])], [plot.x, plot.x + plot.width], {\n chart: options.chart,\n property: options.property,\n padding: options.padding,\n nice: true,\n fromZero: true,\n });\n const strokes: Stroke[] = [];\n const labels: TextLabel[] = [];\n for (const tick of scale.ticks(4)) {\n const tx = scale(tick);\n if (tick !== 0) strokes.push({ d: `M${tx},${plot.y}V${plot.y + plot.height}`, role: 'ornament', part: 'grid' });\n labels.push({ x: tx, y: area.y + area.height - 5, text: formatNumber(tick, options.locale, options.numberFormat), kind: 'tick', part: 'axis', anchor: 'middle' });\n }\n strokes.push({ d: `M${scale(0)},${plot.y}V${plot.y + plot.height}`, role: 'ornament', part: 'rule' });\n return { scale, strokes, labels };\n}\n\n/**\n * Label baselines for points at `ys`, moved apart to at least `gap` and kept within\n * `[top, bottom]`: the labels move, the segments never do (Art. 1).\n */\nexport function spreadLabels(ys: readonly number[], gap: number, top: number, bottom: number): number[] {\n const order = ys.map((y, i) => [y, i] as const).sort((a, b) => a[0] - b[0] || a[1] - b[1]);\n const placed = order.map(([y]) => y);\n for (let k = 0; k < placed.length; k += 1) placed[k] = Math.max(placed[k] as number, k === 0 ? top : (placed[k - 1] as number) + gap);\n for (let k = placed.length - 1; k >= 0; k -= 1) placed[k] = Math.min(placed[k] as number, k === placed.length - 1 ? bottom : (placed[k + 1] as number) - gap);\n const result = new Array<number>(ys.length);\n order.forEach(([, i], k) => {\n result[i] = placed[k] as number;\n });\n return result;\n}\n","import type { Accessor, Datum, Rect, Stroke, TextLabel, ToneLevel } from '../../types';\nimport { diagnose } from '../../diagnostics/diagnose';\nimport { PLOT_INSET } from './cartesian';\nimport { finite, rectPath, warnValue } from './cells';\nimport { accessorName, formatCategory, read } from './format';\n\n/**\n * The polar frame (T-071): a circle centred in the drawing area. Angles are radians measured\n * clockwise from 12 o'clock — d3-shape's convention — so a sweep reads like a clock face.\n */\nexport interface PolarFrame {\n readonly cx: number;\n readonly cy: number;\n /** Largest radius that fits the area's shorter side, inset so no stroke is clipped. */\n readonly radius: number;\n}\n\n/** `labelRoom` keeps a margin around the circle for names printed outside it. */\nexport function polarFrame(area: Rect, labelRoom = 0): PolarFrame {\n return {\n cx: area.x + area.width / 2,\n cy: area.y + area.height / 2,\n radius: Math.max(Math.min(area.width, area.height) / 2 - PLOT_INSET - labelRoom, 1),\n };\n}\n\n/** Room outside a circle for the names printed around it. */\nexport const RIM_LABELS = 14;\n\n/**\n * Names around the rim, one per slot at its middle angle, thinned so no more than `most` are\n * printed; the table and the readout name every slot.\n */\nexport function rimLabels(frame: PolarFrame, entries: readonly { readonly angle: number; readonly text: string }[], most = 24): TextLabel[] {\n const step = Math.max(1, Math.ceil(entries.length / most));\n return entries.filter((_, i) => i % step === 0).map((e) => polarLabel(frame, e.angle, frame.radius + 8, e.text));\n}\n\n/** The point at `angle` on the circle of radius `r`. */\nexport function pointAt(frame: PolarFrame, angle: number, r: number): { x: number; y: number } {\n return { x: frame.cx + r * Math.sin(angle), y: frame.cy - r * Math.cos(angle) };\n}\n\n/** Below this sweep an arc has no extent to draw. */\nconst EPSILON = 1e-9;\n\nconst at = (frame: PolarFrame, angle: number, r: number) => {\n const p = pointAt(frame, angle, r);\n return `${p.x},${p.y}`;\n};\n\n/** An arc command of at most half a turn from the current point to `end` along radius `r`. */\nfunction arcTo(frame: PolarFrame, r: number, end: number, clockwise: boolean): string {\n return `A${r},${r},0,0,${clockwise ? 1 : 0},${at(frame, end, r)}`;\n}\n\n/**\n * An arc along radius `r` from `start` to `end` that never degenerates: past half a turn it is drawn\n * as two halves, so a sweep near a full turn never rounds to an arc that ends where it starts.\n */\nfunction sweep(frame: PolarFrame, r: number, start: number, end: number, clockwise: boolean): string {\n if (Math.abs(end - start) <= Math.PI) return arcTo(frame, r, end, clockwise);\n const middle = (start + end) / 2;\n return arcTo(frame, r, middle, clockwise) + arcTo(frame, r, end, clockwise);\n}\n\n/** An open arc along one radius, from `start` to `end` (clockwise when `end > start`). */\nexport function arcPath(frame: PolarFrame, r: number, start: number, end: number): string {\n if (Math.abs(end - start) < EPSILON || r <= 0) return '';\n return `M${at(frame, start, r)}${sweep(frame, r, start, end, end > start)}`;\n}\n\nexport interface SectorShape {\n readonly inner: number;\n readonly outer: number;\n readonly start: number;\n readonly end: number;\n}\n\n/**\n * A closed ring slice: out along the outer arc, across, and back along the inner arc. With no\n * inner radius it is a wedge from the centre. The arcs are exact SVG arcs, never polylines.\n */\nexport function sectorPath(frame: PolarFrame, shape: SectorShape): string {\n const { inner, outer, start, end } = shape;\n if (Math.abs(end - start) < EPSILON || outer <= 0) return '';\n const clockwise = end > start;\n const outerArc = `M${at(frame, start, outer)}${sweep(frame, outer, start, end, clockwise)}`;\n if (inner <= 0) return `${outerArc}L${frame.cx},${frame.cy}Z`;\n return `${outerArc}L${at(frame, end, inner)}${sweep(frame, inner, end, start, !clockwise)}Z`;\n}\n\n/** Half-width of the band around the poles where a label is centred rather than side-anchored. */\nconst POLE = 0.1;\n\n/** A label on the circle of radius `r` at `angle`, anchored so it reads away from the circle. */\nexport function polarLabel(frame: PolarFrame, angle: number, r: number, text: string, kind: TextLabel['kind'] = 'tick'): TextLabel {\n const p = pointAt(frame, angle, r);\n const side = Math.sin(angle);\n const anchor = side > POLE ? 'start' : side < -POLE ? 'end' : 'middle';\n // Baseline a third of the cap height below the point, so the text sits centred on it.\n return { x: p.x, y: p.y + 3, text, kind, part: 'axis', anchor };\n}\n\nexport interface Sector {\n readonly index: number;\n readonly datum: Datum;\n readonly name: string;\n readonly value: number;\n}\n\n/**\n * Reads a sector series (Data Model §2.2): a value must be finite and `≥ 0` — a negative angle does\n * not exist — or the row is warned `SP002` and dropped; a repeated name is made unique.\n */\nexport function readSectors(\n data: readonly Datum[],\n nameKey: Accessor<string | number>,\n valueKey: Accessor<number | null | undefined>,\n chart: string,\n locale: string,\n): Sector[] {\n const valueName = accessorName(valueKey, 'value');\n const seen = new Map<string, number>();\n const sectors: Sector[] = [];\n data.forEach((datum, index) => {\n const value = finite(read(valueKey, datum, index));\n if (value === undefined || value < 0) {\n warnValue(chart, valueName, `Row ${index} has a ${valueName} of ${String(read(valueKey, datum, index))}; a sector needs a finite value ≥ 0, so it is omitted.`);\n return;\n }\n const given = read(nameKey, datum, index);\n if (given === undefined || given === null || given === '') warnValue(chart, accessorName(nameKey, 'name'), `Row ${index} has no name; it is shown as \"—\".`);\n const raw = formatCategory(given, locale);\n const count = (seen.get(raw) ?? 0) + 1;\n seen.set(raw, count);\n if (count > 1) warnValue(chart, accessorName(nameKey, 'name'), `The name \"${raw}\" repeats; row ${index} is shown as \"${raw} (${count})\".`);\n sectors.push({ index, datum, name: count > 1 ? `${raw} (${count})` : raw, value });\n });\n return sectors;\n}\n\n/** Sectors a polar chart draws before it recommends aggregation (API Spec §12). */\nexport const SECTORS_PER_CHART = 60;\n\n/** Warns SP008 above the polar ceiling; the chart is still drawn in full (REQ-096). */\nexport function checkSectors(chart: string, property: string, count: number): void {\n if (process.env.NODE_ENV === 'production' || count <= SECTORS_PER_CHART) return;\n diagnose('SP008', chart, { property, message: `${count} sectors; the ceiling is ${SECTORS_PER_CHART}.` });\n}\n\n// The ring's tones serve every family with categories (DD-032); they live in cells.ts.\nexport { ringTone, ringTones } from './cells';\n\n/** Height of one legend row. */\nconst LEGEND_ROW = 14;\n\nexport interface SectorLegendEntry {\n readonly name: string;\n readonly share: string;\n readonly tone: ToneLevel;\n}\n\n/**\n * A legend column: a toned swatch (ornament: it carries no data), the sector's name and its share,\n * in the ring's clockwise order. Rows that do not fit end in \"+N more\"; the table lists them all.\n */\nexport function sectorLegend(area: Rect, entries: readonly SectorLegendEntry[]): { strokes: Stroke[]; labels: TextLabel[] } {\n const strokes: Stroke[] = [];\n const labels: TextLabel[] = [];\n const fits = Math.max(Math.floor(area.height / LEGEND_ROW), 1);\n const shown = entries.length > fits ? fits - 1 : entries.length;\n const top = area.y + (area.height - Math.min(entries.length, fits) * LEGEND_ROW) / 2;\n entries.slice(0, shown).forEach((entry, row) => {\n const y = top + row * LEGEND_ROW;\n strokes.push({ d: rectPath({ x: area.x, y: y + 3, width: 9, height: 7 }), role: 'ornament', part: 'ink', tone: entry.tone });\n labels.push({ x: area.x + 14, y: y + 10, text: entry.name, kind: 'tick', part: 'text', anchor: 'start' });\n labels.push({ x: area.x + area.width, y: y + 10, text: entry.share, kind: 'tick', part: 'axis', anchor: 'end' });\n });\n if (shown < entries.length) {\n labels.push({ x: area.x + 14, y: top + shown * LEGEND_ROW + 10, text: `+${entries.length - shown} more`, kind: 'tick', part: 'axis', anchor: 'start' });\n }\n return { strokes, labels };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/prng.ts","../src/charts/shared/dates.ts","../src/charts/shared/card.ts","../src/charts/shared/shell.ts"],"names":["areaHeight"],"mappings":"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","file":"chunk-PD4MD7JU.js","sourcesContent":["/**\n * A seeded 32-bit PRNG (mulberry32), for generated demo data (Data Model §4). Owned here rather\n * than imported, so its sequence is frozen by SemVer like the seed derivation (DD-006): changing\n * it changes demo output, which is never a patch.\n */\nexport function createPrng(seed: number): () => number {\n let state = seed >>> 0;\n return () => {\n state = (state + 0x6d2b79f5) >>> 0;\n let t = state;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4_294_967_296;\n };\n}\n","/**\n * ISO dates as whole days since 1970-01-01, in UTC. Day arithmetic never touches the host's\n * time zone or clock, so server and client agree (REQ-005, REQ-103).\n */\nconst DAY_MS = 86_400_000;\nconst ISO_DATE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\n/** Days since the epoch of an ISO `YYYY-MM-DD` date; `NaN` when it is not one. */\nexport function parseIsoDate(iso: string): number {\n const match = ISO_DATE.exec(iso);\n if (!match) return Number.NaN;\n return Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])) / DAY_MS;\n}\n\n/** The ISO `YYYY-MM-DD` form of a day number. */\nexport function isoDate(day: number): string {\n return new Date(day * DAY_MS).toISOString().slice(0, 10);\n}\n\nexport function addDays(day: number, days: number): number {\n return day + days;\n}\n\n/** Day of the week in UTC, 0 = Sunday. */\nexport function weekday(day: number): number {\n return (((day + 4) % 7) + 7) % 7;\n}\n","import type { CommonChartProps, Rect, Stroke, TextLabel } from '../../types';\nimport { formatValue } from './format';\n\n/** Inner padding of the card frame. */\nexport const CARD_PADDING = 16;\nconst TITLE_ROW = 20;\nconst VALUE_ROW = 52;\nconst HEADER_GAP = 8;\nconst FOOTER_ROW = 30;\n\nexport interface CardLayout {\n readonly viewBox: Rect;\n /** Where the chart draws; the whole viewBox under `chrome: 'bare'`. */\n readonly area: Rect;\n readonly strokes: readonly Stroke[];\n readonly labels: readonly TextLabel[];\n}\n\n/**\n * Lays out the card frame shared by every chart: title and badge, metric and unit, the drawing\n * area and the footer. Under `chrome: 'bare'` it emits the drawing area and nothing else\n * (REQ-095).\n */\nexport function cardLayout(\n props: CommonChartProps,\n options: {\n readonly width: number;\n readonly areaHeight: number;\n readonly chrome: 'card' | 'bare';\n readonly locale: string;\n },\n): CardLayout {\n const { width, areaHeight, chrome, locale } = options;\n if (chrome === 'bare') {\n const box = { x: 0, y: 0, width, height: areaHeight };\n return { viewBox: box, area: box, strokes: [], labels: [] };\n }\n\n const labels: TextLabel[] = [];\n const strokes: Stroke[] = [];\n const left = CARD_PADDING;\n const right = width - CARD_PADDING;\n let cursor = CARD_PADDING;\n\n if (props.title !== undefined || props.badge !== undefined) {\n const baseline = cursor + 11;\n if (props.title !== undefined) {\n labels.push({ x: left, y: baseline, text: props.title, kind: 'title', part: 'text', anchor: 'start' });\n }\n if (props.badge !== undefined) {\n labels.push({ x: right, y: baseline, text: props.badge, kind: 'badge', part: 'axis', anchor: 'end' });\n }\n cursor += TITLE_ROW;\n }\n\n if (props.value !== undefined || props.unit !== undefined) {\n if (props.value !== undefined) {\n labels.push({\n x: left,\n y: cursor + 30,\n text: formatValue(props.value, locale, props.numberFormat),\n kind: 'value',\n part: 'text',\n anchor: 'start',\n });\n }\n if (props.unit !== undefined) {\n labels.push({ x: left, y: cursor + 46, text: props.unit, kind: 'unit', part: 'axis', anchor: 'start' });\n }\n cursor += VALUE_ROW;\n }\n\n if (cursor > CARD_PADDING) cursor += HEADER_GAP;\n const area = { x: left, y: cursor, width: right - left, height: areaHeight };\n cursor += areaHeight;\n\n if (props.footerLeft !== undefined || props.footerRight !== undefined) {\n const ruleY = cursor + 8;\n strokes.push({ d: `M${left},${ruleY}H${right}`, role: 'ornament', part: 'rule' });\n if (props.footerLeft !== undefined) {\n labels.push({ x: left, y: ruleY + 18, text: props.footerLeft, kind: 'footer', part: 'axis', anchor: 'start' });\n }\n if (props.footerRight !== undefined) {\n labels.push({ x: right, y: ruleY + 18, text: props.footerRight, kind: 'footer', part: 'axis', anchor: 'end' });\n }\n cursor += FOOTER_ROW;\n }\n\n const height = cursor + CARD_PADDING;\n const inset = 0.5;\n strokes.unshift({\n d: `M${inset},${inset}H${width - inset}V${height - inset}H${inset}Z`,\n role: 'ornament',\n part: 'rule',\n });\n\n return { viewBox: { x: 0, y: 0, width, height }, area, strokes, labels };\n}\n","import { diagnose } from '../../diagnostics/diagnose';\nimport { roundGeometry } from '../../render/round';\nimport type {\n ChartModel,\n CommonChartProps,\n DataTable,\n Geometry,\n HitArea,\n RecipeContext,\n Rect,\n Stroke,\n TextLabel,\n} from '../../types';\n\n/** What every chart model shares, before any geometry: identity and the accessible layer. */\nexport type ModelBase = Pick<ChartModel, 'chart' | 'id' | 'chrome' | 'name' | 'ids' | 'table' | 'dataTable'>;\n\n/** The accessible name, ids and table of a chart (REQ-120, REQ-121). */\nexport function modelBase(\n chart: string,\n props: CommonChartProps,\n context: RecipeContext,\n fallbackName: string,\n table: Omit<DataTable, 'caption'>,\n): ModelBase {\n const { id } = context;\n const name = props.label ?? props.title ?? fallbackName;\n return {\n chart,\n id,\n chrome: props.chrome ?? 'card',\n name,\n ids: { title: `${id}-title`, desc: `${id}-desc`, table: `${id}-table` },\n table: { caption: name, ...table },\n dataTable: props.dataTable ?? 'hidden',\n };\n}\n\n/** The drawing-area height a chart asks for: the `height` prop or the default of API Spec §5.1. */\nexport function areaHeight(props: CommonChartProps): number {\n return props.height ?? 160;\n}\n\n/**\n * The width the chart draws at, or a deferred model when the container has no usable size yet:\n * the render waits, and no attribute ever carries `NaN` (REQ-009, SP003).\n */\nexport function measure(\n base: ModelBase,\n props: CommonChartProps,\n context: RecipeContext,\n): { readonly width: number; readonly height: number } | { readonly deferred: ChartModel } {\n const width = props.width ?? context.width;\n const height = areaHeight(props);\n if (width !== undefined && width > 0 && height > 0) return { width, height };\n if (width !== undefined && process.env.NODE_ENV !== 'production') {\n diagnose('SP003', base.chart, {\n property: width <= 0 ? 'width' : 'height',\n message: `Measured ${width} × ${height} px.`,\n });\n }\n const box = { x: 0, y: 0, width: 0, height: 0 };\n return {\n deferred: {\n ...base,\n status: 'deferred',\n geometry: { viewBox: box, plot: box, strokes: [], labels: [], hitAreas: [], defs: [] },\n description: props.description ?? base.name,\n },\n };\n}\n\n/**\n * The ground's empty state inside the drawing area, with no spurious axes and no exception\n * (REQ-007). SP001 is reported only when the dataset itself is empty.\n */\nexport function emptyModel(\n base: ModelBase,\n props: CommonChartProps,\n context: RecipeContext,\n frame: { readonly viewBox: Rect; readonly plot: Rect; readonly strokes: readonly Stroke[]; readonly labels: readonly TextLabel[] },\n datasetEmpty: boolean,\n): ChartModel {\n if (datasetEmpty && process.env.NODE_ENV !== 'production') {\n diagnose('SP001', base.chart, { property: 'data' });\n }\n const { plot } = frame;\n const strokes: Stroke[] = [...frame.strokes];\n if (context.emptyState.rule) {\n strokes.push({ d: `M${plot.x},${plot.y + plot.height}H${plot.x + plot.width}`, role: 'ornament', part: 'rule' });\n }\n const labels: TextLabel[] = [\n ...frame.labels,\n {\n x: plot.x + plot.width / 2,\n y: plot.y + plot.height / 2,\n text: context.emptyState.text,\n kind: 'empty',\n part: 'axis',\n anchor: 'middle',\n },\n ];\n return {\n ...base,\n status: 'ready',\n description: props.description ?? `${base.name}. ${context.emptyState.text}.`,\n geometry: roundGeometry({ viewBox: frame.viewBox, plot, strokes, labels, hitAreas: [], defs: [] }),\n };\n}\n\n/** A drawn chart: its geometry rounded to 2 decimals (REQ-002). */\nexport function readyModel(\n base: ModelBase,\n description: string,\n geometry: Omit<Geometry, 'defs' | 'hitAreas'> & { readonly hitAreas: readonly HitArea[] },\n): ChartModel {\n return { ...base, status: 'ready', description, geometry: roundGeometry({ ...geometry, defs: [] }) };\n}\n"]}
|