@eifi1/ui-kit 0.52.0 → 0.53.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 +47 -54
- package/dist/billing/cancel-subscription.d.ts +5 -14
- package/dist/billing/cancel-subscription.js +1 -3
- package/dist/billing/cancel-subscription.js.map +1 -1
- package/dist/billing/plan-card.d.ts +5 -13
- package/dist/billing/plan-card.js +3 -11
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-switch.d.ts +5 -14
- package/dist/billing/plan-switch.js +1 -3
- package/dist/billing/plan-switch.js.map +1 -1
- package/dist/chart.d.ts +3 -14
- package/dist/chart.js +64 -11
- package/dist/chart.js.map +1 -1
- package/dist/components/date-field.d.ts +1 -1
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.d.ts +1 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.d.ts +4 -17
- package/dist/components/date-range-picker.js +2 -2
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/nav-pills.d.ts +1 -1
- package/dist/components/nav-pills.js.map +1 -1
- package/dist/components/series-chart-axes.d.ts +1 -1
- package/dist/components/series-chart-axes.js.map +1 -1
- package/dist/components/series-chart.d.ts +64 -19
- package/dist/components/series-chart.js +2 -1
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/treemap-labels.d.ts +6 -1
- package/dist/components/treemap-labels.js +2 -2
- package/dist/components/treemap-labels.js.map +1 -1
- package/dist/components/treemap.d.ts +29 -4
- package/dist/components/treemap.js +22 -9
- package/dist/components/treemap.js.map +1 -1
- package/dist/data-table.d.ts +1 -6
- package/dist/data-table.js +1 -9
- package/dist/data-table.js.map +1 -1
- package/dist/demo/demo-countdown.d.ts +0 -5
- package/dist/demo/demo-countdown.js +0 -4
- package/dist/demo/demo-countdown.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/feedback/feedback-mutation.d.ts +11 -23
- package/dist/feedback/feedback-mutation.js +1 -9
- package/dist/feedback/feedback-mutation.js.map +1 -1
- package/dist/feedback/feedback-public-list.d.ts +1 -6
- package/dist/feedback/feedback-public-list.js +1 -2
- package/dist/feedback/feedback-public-list.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.js +0 -8
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +3 -50
- package/dist/feedback/feedback-row-detail.js +0 -8
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +3 -19
- package/dist/feedback/feedback-status-undo.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +0 -9
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +6 -40
- package/dist/feedback.js +88 -46
- package/dist/feedback.js.map +1 -1
- package/dist/i18n/defaults.js +0 -4
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +2 -19
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +5 -14
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +2 -30
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +2 -19
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +2 -19
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +2 -19
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +2 -20
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +2 -19
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +9 -4
- package/dist/i18n/review.js.map +1 -1
- package/dist/i18n/shared-labels.js +0 -1
- package/dist/i18n/shared-labels.js.map +1 -1
- package/dist/index.d.ts +15 -64
- package/dist/index.js +22 -102
- package/dist/index.js.map +1 -1
- package/dist/rhf/fields.d.ts +2 -2
- package/dist/rhf/fields.js.map +1 -1
- package/dist/search/search-index.d.ts +0 -6
- package/dist/search/search-index.js +0 -4
- package/dist/search/search-index.js.map +1 -1
- package/dist/search.d.ts +1 -8
- package/dist/search.js +2 -7
- package/dist/search.js.map +1 -1
- package/dist/shell/account-menu-language.d.ts +7 -21
- package/dist/shell/account-menu-language.js +1 -3
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/account-menu-text-size.d.ts +9 -23
- package/dist/shell/account-menu-text-size.js +2 -3
- package/dist/shell/account-menu-text-size.js.map +1 -1
- package/dist/shell/app-shell.d.ts +0 -10
- package/dist/shell/app-shell.js +1 -7
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/company-switcher.d.ts +1 -1
- package/dist/shell/company-switcher.js.map +1 -1
- package/dist/shell/dev-menu.d.ts +1 -1
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +1 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +7 -29
- package/dist/shell.js +12 -42
- package/dist/shell.js.map +1 -1
- package/dist/sync.d.ts +2 -6
- package/dist/sync.js +2 -15
- package/dist/sync.js.map +1 -1
- package/dist/theme/chart-palette.d.ts +0 -5
- package/dist/theme/chart-palette.js +0 -2
- package/dist/theme/chart-palette.js.map +1 -1
- package/package.json +1 -1
- package/src/billing/cancel-subscription.tsx +5 -16
- package/src/billing/plan-card.tsx +7 -24
- package/src/billing/plan-switch.tsx +5 -16
- package/src/chart.ts +62 -13
- package/src/components/date-field.tsx +1 -1
- package/src/components/date-picker.tsx +0 -1
- package/src/components/date-range-picker.tsx +6 -22
- package/src/components/nav-pills.tsx +1 -1
- package/src/components/series-chart-axes.ts +6 -1
- package/src/components/series-chart.tsx +78 -21
- package/src/components/treemap-labels.ts +11 -3
- package/src/components/treemap.tsx +65 -12
- package/src/data-table.ts +1 -11
- package/src/demo/demo-countdown.ts +3 -8
- package/src/feedback/feedback-mutation.ts +12 -33
- package/src/feedback/feedback-public-list.tsx +1 -7
- package/src/feedback/feedback-row-detail-labels.ts +0 -8
- package/src/feedback/feedback-row-detail.tsx +8 -58
- package/src/feedback/feedback-status-undo.ts +4 -18
- package/src/feedback/feedback-thread.tsx +0 -10
- package/src/feedback.ts +89 -48
- package/src/i18n/defaults.ts +0 -4
- package/src/i18n/german.ts +2 -19
- package/src/i18n/kit-labels.tsx +5 -14
- package/src/i18n/locales/es.ts +2 -19
- package/src/i18n/locales/fr.ts +2 -19
- package/src/i18n/locales/hu.ts +2 -19
- package/src/i18n/locales/it.ts +2 -20
- package/src/i18n/locales/zh.ts +2 -19
- package/src/i18n/review.ts +9 -4
- package/src/i18n/shared-labels.ts +0 -1
- package/src/index.ts +30 -112
- package/src/rhf/fields.tsx +2 -2
- package/src/search/search-index.ts +0 -15
- package/src/search.ts +8 -8
- package/src/shell/account-menu-language.tsx +7 -27
- package/src/shell/account-menu-text-size.tsx +13 -32
- package/src/shell/app-shell.tsx +0 -13
- package/src/shell/company-switcher.tsx +1 -1
- package/src/shell/dev-menu.tsx +1 -1
- package/src/shell/top-bar-parts-labels.ts +1 -1
- package/src/shell.ts +17 -44
- package/src/sync.ts +2 -15
- package/src/theme/chart-palette.ts +0 -2
- package/tokens.css +4 -4
- package/dist/billing/dialog-close.d.ts +0 -29
- package/dist/billing/dialog-close.js +0 -8
- package/dist/billing/dialog-close.js.map +0 -1
- package/dist/components/field-sync-labels.d.ts +0 -3
- package/dist/components/field-sync-labels.js +0 -12
- package/dist/components/field-sync-labels.js.map +0 -1
- package/dist/components/field-sync.d.ts +0 -186
- package/dist/components/field-sync.js +0 -269
- package/dist/components/field-sync.js.map +0 -1
- package/dist/components/section-nav.d.ts +0 -44
- package/dist/components/section-nav.js +0 -33
- package/dist/components/section-nav.js.map +0 -1
- package/dist/components/sign-chip-labels.d.ts +0 -3
- package/dist/components/sign-chip-labels.js +0 -11
- package/dist/components/sign-chip-labels.js.map +0 -1
- package/dist/components/sign-chip.d.ts +0 -77
- package/dist/components/sign-chip.js +0 -47
- package/dist/components/sign-chip.js.map +0 -1
- package/dist/lib/isin.d.ts +0 -38
- package/dist/lib/isin.js +0 -36
- package/dist/lib/isin.js.map +0 -1
- package/dist/shell/role-switcher.d.ts +0 -28
- package/dist/shell/role-switcher.js +0 -31
- package/dist/shell/role-switcher.js.map +0 -1
- package/src/billing/dialog-close.ts +0 -34
- package/src/components/field-sync-labels.ts +0 -14
- package/src/components/field-sync.tsx +0 -504
- package/src/components/section-nav.tsx +0 -72
- package/src/components/sign-chip-labels.ts +0 -13
- package/src/components/sign-chip.tsx +0 -133
- package/src/lib/isin.ts +0 -72
- package/src/shell/role-switcher.tsx +0 -53
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/series-chart-axes.ts"],"sourcesContent":["// The series chart's pure half: the axis bands, the padded and anchored domains, the\n// series keys and colours, and the abscissa reduced to a number line. No React, no\n// recharts and no JSX here (chart-zoom-core lends the one name `DEFAULT_Y_AXIS`) —\n// arithmetic over rows and axes, which is why apps import some of it in\n// files that draw no chart (Kurvenschmiede's curve-chart-model.ts builds its series\n// keys with `seriesKey`).\n//\n// Moved out of series-chart.tsx as it was (MOD-9, refactor audit 2026-10). The public\n// names are still exported from series-chart.tsx, so `/chart` and the barrel are\n// unchanged; this module is not an entry of its own. The names below that series-chart\n// does not re-export (the tick-band constants, `xModel`, `finite`, …) stay internal.\nimport { DEFAULT_Y_AXIS } from \"./chart-zoom-core\";\nimport type { TimeTickUnit } from \"./series-chart-ticks\";\nimport { paletteFor } from \"../theme/chart-palette\";\nimport type {\n SeriesChartAxis,\n SeriesChartRow,\n SeriesChartSeries,\n SeriesChartTickValues,\n SeriesChartX,\n SeriesChartXValue,\n} from \"./series-chart\";\n\n/** How much of an axis band the rotated title takes, in px at Normal — × the text size's\n * scale on the chart (§3.2), since the title is text. Reserved rather than shared with\n * the ticks: a title merely offset inside the band prints on top of a five-figure tick,\n * and which gives way depends on the data. */\nexport const AXIS_TITLE_STRIP = 16;\n\n/** Where inside its strip the rotated title sits. */\nexport const AXIS_TITLE_OFFSET = 10;\n\n/** The tallest band tilted x ticks reserve, in px at Normal (× the scale). A category\n * name longer than this at its angle is clipped rather than squeezing the plot down to\n * a strip. */\nconst MAX_TILTED_TICK_BAND = 120;\n\n/** What one character of a tick label is taken to be, in px at Normal, for the tilted\n * band — the shell's `text-xs`. An estimate: the SVG is not laid out yet when the band\n * is decided. Both grow with the text size, as `text-xs` does (§3.2). */\nconst TICK_CHAR_WIDTH = 7;\nconst TICK_LINE_HEIGHT = 12;\n/** recharts' gap between the axis line and a bottom tick's text — px, at every size:\n * recharts draws it, not the type. */\nconst TICK_GAP = 8;\n/** recharts' own band under level x ticks. */\nconst LEVEL_TICK_BAND = 30;\n/** The least room recharts' x ticks keep between labels, in px at Normal. */\nexport const MIN_TICK_GAP = 32;\n\n/**\n * The height the x axis reserves for its ticks at a text `scale`: tilted by `angle`\n * degrees, the rotated box of the longest label, from its length; level, recharts' own\n * 30 px grown with the labels. `undefined` for level ticks at Normal, where recharts'\n * default is exactly that.\n */\nexport function tiltedTickBand(labels: readonly string[], angle: number, scale = 1): number | undefined {\n if (!angle) return scale === 1 ? undefined : Math.ceil(LEVEL_TICK_BAND * scale);\n const rad = (Math.abs(angle) * Math.PI) / 180;\n const longest = Math.max(0, ...labels.map((label) => label.length)) * TICK_CHAR_WIDTH * scale;\n const band = Math.sin(rad) * longest + Math.cos(rad) * TICK_LINE_HEIGHT * scale + TICK_GAP;\n return Math.min(\n Math.round(MAX_TILTED_TICK_BAND * scale),\n Math.max(Math.ceil(LEVEL_TICK_BAND * scale), Math.ceil(band)),\n );\n}\n\n/** The width the ticks of a y axis get when a caller does not say, in px at Normal. */\nexport const AXIS_TICK_WIDTH = 48;\n\n/**\n * How much air a FITTED axis leaves between the data and its frame, as a fraction of\n * the range. Recharts fits `[dataMin, dataMax]`, which draws a peak half a stroke\n * outside the plot and a curve running to its limit indistinguishable from the frame.\n */\nconst AUTO_PAD = 0.04;\n\n/** The band a fitted axis draws, padded — and a real band for constant data, which is\n * a zero-height domain recharts cannot scale into. `undefined` when nothing finite. */\nexport function paddedDomain(values: Iterable<number>): [number, number] | undefined {\n let low = Infinity;\n let high = -Infinity;\n for (const value of values) {\n if (!Number.isFinite(value)) continue;\n if (value < low) low = value;\n if (value > high) high = value;\n }\n return padBand(low, high);\n}\n\n/**\n * {@link paddedDomain} for a caller that has already walked its own data — so a row\n * of charts can share one scale without building an array to find two numbers in, and\n * without a second padding rule. `low > high` means \"nothing was seen\": `undefined`.\n */\nexport function padBand(low: number, high: number): [number, number] | undefined {\n if (!(low <= high)) return undefined;\n const pad = (high - low) * AUTO_PAD || Math.abs(high) * AUTO_PAD || 1;\n return [low - pad, high + pad];\n}\n\n/**\n * The whole band a y axis occupies: its ticks, and its title when it draws one. For\n * lining a heading up over a PLOT rather than over its column.\n *\n * `scale` is the text size's (`useTextSize().scale`, §3.2, §10.10): the chart draws every\n * band — the default 48 px and a caller's own `width` alike (keksdose's\n * `MONEY_AXIS_WIDTH`) — this many times wider, because the ticks in it are `text-xs`\n * and grow with the text. A heading lined up over the plot has to pass the same scale.\n * One factor for both sides of a facing pair, so the mirrored bands stay equal.\n */\nexport function axisBandWidth(tickWidth: number | undefined, titled: boolean, scale = 1): number {\n const band = (tickWidth ?? AXIS_TICK_WIDTH) + (titled ? AXIS_TITLE_STRIP : 0);\n return scale === 1 ? band : Math.round(band * scale);\n}\n\n/**\n * The colour an axis TITLE takes, or `undefined` for the neutral one.\n *\n * An axis measuring exactly one line is that line's, and saying so in the title lets a\n * reader find a channel's scale without counting axes. An axis measuring several is\n * nobody's — a title in the first one's colour would be claiming it. Counted off the\n * series, so toggling a second line onto an axis gives the colour up in the same render.\n */\nexport function soleSeriesColor(\n axis: Pick<SeriesChartAxis, \"id\" | \"color\">,\n series: readonly Pick<SeriesChartSeries, \"axis\">[],\n): string | undefined {\n const mine = series.filter((entry) => (entry.axis ?? DEFAULT_Y_AXIS) === axis.id);\n return mine.length === 1 ? axis.color : undefined;\n}\n\n/** The single-axis case, which is most charts. `width` is what the TICKS need;\n * `orientation` is which side they stand on. */\nexport function oneAxis(\n format: ((value: number) => string) | undefined,\n title: string,\n width?: number,\n orientation?: \"left\" | \"right\",\n): SeriesChartAxis[] {\n return [{ id: DEFAULT_Y_AXIS, format, title, width, orientation }];\n}\n\n/** One source's samples: an abscissa and the channels measured against it. */\nexport interface SeriesSource {\n x: readonly number[];\n channels: Readonly<Record<string, readonly number[]>>;\n}\n\n/**\n * Merge sources sampled on different grids into rows the chart can draw.\n *\n * Merged ON THE ABSCISSA VALUE ITSELF, never interpolated onto a common grid: a line\n * through invented points looks exactly like one through measured ones. Where a source\n * has no sample the key is absent, and `connectNulls` bridges the hole with the same\n * straight segment an interpolation would have drawn — without claiming a measurement.\n */\nexport function mergeSeries(sources: readonly SeriesSource[]): Record<string, number>[] {\n const byAbscissa = new Map<number, Record<string, number>>();\n for (const source of sources) {\n source.x.forEach((value, index) => {\n const row = byAbscissa.get(value) ?? { x: value };\n for (const [key, channel] of Object.entries(source.channels)) row[key] = channel[index];\n byAbscissa.set(value, row);\n });\n }\n return [...byAbscissa.values()].sort((a, b) => a.x - b.x);\n}\n\n/**\n * A series key built out of parts — as a CSS identifier.\n *\n * The chart shell paints each series through `--color-<key>`, and skips (with a\n * console warning) any key that is not `[A-Za-z_][A-Za-z0-9_-]*`. A line whose colour\n * was skipped has no stroke at all: an axis, a grid and nothing between them. So a key\n * assembled out of DATA — an id, an enum, a side — goes through here: every other\n * character becomes `_`, the parts are joined with `_`, and a key that would start with\n * a digit or a hyphen gets a leading `_`.\n */\nexport function seriesKey(...parts: (string | number)[]): string {\n const key = parts.map((part) => String(part).replace(/[^A-Za-z0-9_-]/g, \"_\")).join(\"_\");\n return /^[A-Za-z_]/.test(key) ? key : `_${key}`;\n}\n\n/**\n * The band an axis carrying bars or areas draws: the data's extent with ZERO in it,\n * padded only on the sides that are not zero — bars standing on a frame's bottom edge,\n * not floating four per cent above it on a band of air nobody asked for.\n * `undefined` when there is nothing to fit.\n *\n * All-zero data (a quiet period, a zoom window over empty months) is `[0, 1]`: one unit\n * on the free side, the unit {@link padBand} pads a zero extent by. d3 maps every value\n * of a zero-height domain to the range's midpoint, so `[0, 0]` stood the bars on a\n * baseline in the middle of the plot, the \"0\" tick beside it (audit 2026-10-30 DSP-10;\n * keksdose's weekday pattern drew seven 4 px stubs mid-card for a period with no\n * spending).\n */\nexport function anchoredBand(extent: readonly [number, number] | undefined): [number, number] | undefined {\n if (!extent) return undefined;\n const low = Math.min(0, extent[0]);\n const high = Math.max(0, extent[1]);\n if (low === 0 && high === 0) return [0, 1];\n const pad = (high - low) * AUTO_PAD || 1;\n return [low < 0 ? low - pad : 0, high > 0 ? high + pad : 0];\n}\n\n/**\n * Series with their colours settled BEFORE any are switched off.\n *\n * A series with no `color` takes `paletteFor(its position)` — and a legend toggle that\n * hands the chart a shorter list moves every later series one position up, repainting\n * it in its neighbour's colour on each click. Resolving the colours on the full list\n * and filtering after keeps each series in the colour its legend entry shows.\n */\nexport function visibleSeries(series: readonly SeriesChartSeries[], hidden: ReadonlySet<string>): SeriesChartSeries[] {\n return series\n .map((entry, index) => ({ ...entry, color: entry.color ?? paletteFor(index) }))\n .filter((entry) => !hidden.has(entry.key));\n}\n\n/** Where a category or time chart keeps each row's plotted position. Not the caller's\n * key: that one still holds their own value, which `format` and a hit hand back. */\nconst PLOTTED_X = \"__seriesChartX\";\n\n/** A finite number, or `undefined` — the only thing a row cell counts as a sample. */\nexport const finite = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\n/** A time value as epoch ms. A date-only ISO string is LOCAL midnight (see\n * `SeriesChartX.type`); anything unreadable is `undefined`, i.e. not plotted. */\nfunction toTime(value: unknown): number | undefined {\n if (value instanceof Date) return finite(value.getTime());\n if (typeof value === \"number\") return finite(value);\n if (typeof value !== \"string\") return undefined;\n const day = /^(\\d{4})-(\\d{2})(?:-(\\d{2}))?$/.exec(value);\n if (day) return new Date(Number(day[1]), Number(day[2]) - 1, Number(day[3] ?? 1)).getTime();\n return finite(Date.parse(value));\n}\n\n/** A category's identity, so a Date matches another Date of the same instant. */\nconst categoryId = (value: unknown) =>\n value instanceof Date ? `d:${value.getTime()}` : `${typeof value}:${String(value)}`;\n\n/**\n * The abscissa, reduced to a number line — which is all the plot, the ticks and the\n * zoom ever deal in. A number stays itself; a category becomes its slot index; a time\n * its epoch ms. Everything the caller sees (ticks, tooltip, hits) is turned back.\n */\nexport interface XModel {\n kind: \"number\" | \"category\" | \"time\";\n /** The caller's key, still holding their value. */\n sourceKey: string;\n /** The key the plot reads. The same as `sourceKey` on a number line. */\n plotKey: string;\n /** The rows as plotted. The caller's own on a number line. */\n rows: readonly SeriesChartRow[];\n /** The caller's rows, which dots and hits hand back. */\n source: readonly SeriesChartRow[];\n position: (value: unknown) => number | undefined;\n valueAt: (position: number) => SeriesChartXValue;\n}\n\nexport function xModel(rows: readonly SeriesChartRow[], x: SeriesChartX): XModel {\n const sourceKey = x.key ?? \"x\";\n if (x.type === \"category\") {\n const slots = new Map<string, number>();\n rows.forEach((row, index) => {\n const id = categoryId(row[sourceKey]);\n if (!slots.has(id)) slots.set(id, index);\n });\n return {\n kind: \"category\",\n sourceKey,\n plotKey: PLOTTED_X,\n rows: rows.map((row, index) => ({ ...row, [PLOTTED_X]: index })),\n source: rows,\n position: (value) => slots.get(categoryId(value)),\n valueAt: (position) => rows[Math.round(position)]?.[sourceKey] as SeriesChartXValue,\n };\n }\n if (x.type === \"time\") {\n return {\n kind: \"time\",\n sourceKey,\n plotKey: PLOTTED_X,\n rows: rows.map((row) => ({ ...row, [PLOTTED_X]: toTime(row[sourceKey]) })),\n source: rows,\n position: toTime,\n valueAt: (position) => new Date(position),\n };\n }\n return {\n kind: \"number\",\n sourceKey,\n plotKey: sourceKey,\n rows,\n source: rows,\n position: finite,\n valueAt: (position) => position,\n };\n}\n\n/** Caller ticks, as positions inside the domain on show. */\nexport function resolveTicks<T>(\n values: SeriesChartTickValues<T> | undefined,\n domain: [number, number] | undefined,\n position: (value: T) => number | undefined,\n): number[] | undefined {\n if (!values || !domain) return undefined;\n const list = typeof values === \"function\" ? values(domain) : values;\n if (!list) return undefined;\n const slack = (domain[1] - domain[0]) * 1e-9;\n return list\n .map(position)\n .filter((at): at is number => at !== undefined && at >= domain[0] - slack && at <= domain[1] + slack);\n}\n\n/** A low/high pair widened by some values, or `undefined` if there is still none. */\nexport function extend(\n span: readonly [number, number] | undefined,\n values: readonly (number | undefined)[],\n): [number, number] | undefined {\n let out: [number, number] | undefined = span ? [span[0], span[1]] : undefined;\n for (const value of values) {\n if (value === undefined || !Number.isFinite(value)) continue;\n out = out ? [Math.min(out[0], value), Math.max(out[1], value)] : [value, value];\n }\n return out;\n}\n\n/** How a time tick is written, by what one step of the ticks is. */\nexport const TIME_TICK_FORMAT: Record<TimeTickUnit, Intl.DateTimeFormatOptions> = {\n hour: { hour: \"2-digit\", minute: \"2-digit\" },\n day: { day: \"numeric\", month: \"short\" },\n month: { month: \"short\", year: \"2-digit\" },\n year: { year: \"numeric\" },\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/series-chart-axes.ts"],"sourcesContent":["// The series chart's pure half: the axis bands, the padded and anchored domains, the\n// series keys and colours, and the abscissa reduced to a number line. No React, no\n// recharts and no JSX here (chart-zoom-core lends the one name `DEFAULT_Y_AXIS`) —\n// arithmetic over rows and axes, which is why apps import some of it in\n// files that draw no chart (Kurvenschmiede's curve-chart-model.ts builds its series\n// keys with `seriesKey`).\n//\n// Moved out of series-chart.tsx as it was (MOD-9, refactor audit 2026-10). The public\n// names are still exported from series-chart.tsx, so `/chart` and the barrel are\n// unchanged; this module is not an entry of its own. The names below that series-chart\n// does not re-export (the tick-band constants, `xModel`, `finite`, …) stay internal.\nimport { DEFAULT_Y_AXIS } from \"./chart-zoom-core\";\nimport type { TimeTickUnit } from \"./series-chart-ticks\";\nimport { paletteFor } from \"../theme/chart-palette\";\nimport type {\n SeriesChartAxis,\n SeriesChartRow,\n SeriesChartSeries,\n SeriesChartTickValues,\n SeriesChartX,\n SeriesChartXValue,\n} from \"./series-chart\";\n\n/** How much of an axis band the rotated title takes, in px at Normal — × the text size's\n * scale on the chart (§3.2), since the title is text. Reserved rather than shared with\n * the ticks: a title merely offset inside the band prints on top of a five-figure tick,\n * and which gives way depends on the data. */\nexport const AXIS_TITLE_STRIP = 16;\n\n/** Where inside its strip the rotated title sits. */\nexport const AXIS_TITLE_OFFSET = 10;\n\n/** The tallest band tilted x ticks reserve, in px at Normal (× the scale). A category\n * name longer than this at its angle is clipped rather than squeezing the plot down to\n * a strip. */\nconst MAX_TILTED_TICK_BAND = 120;\n\n/** What one character of a tick label is taken to be, in px at Normal, for the tilted\n * band — the shell's `text-xs`. An estimate: the SVG is not laid out yet when the band\n * is decided. Both grow with the text size, as `text-xs` does (§3.2). */\nconst TICK_CHAR_WIDTH = 7;\nconst TICK_LINE_HEIGHT = 12;\n/** recharts' gap between the axis line and a bottom tick's text — px, at every size:\n * recharts draws it, not the type. */\nconst TICK_GAP = 8;\n/** recharts' own band under level x ticks. */\nconst LEVEL_TICK_BAND = 30;\n/** The least room recharts' x ticks keep between labels, in px at Normal. */\nexport const MIN_TICK_GAP = 32;\n\n/**\n * The height the x axis reserves for its ticks at a text `scale`: tilted by `angle`\n * degrees, the rotated box of the longest label, from its length; level, recharts' own\n * 30 px grown with the labels. `undefined` for level ticks at Normal, where recharts'\n * default is exactly that.\n */\nexport function tiltedTickBand(labels: readonly string[], angle: number, scale = 1): number | undefined {\n if (!angle) return scale === 1 ? undefined : Math.ceil(LEVEL_TICK_BAND * scale);\n const rad = (Math.abs(angle) * Math.PI) / 180;\n const longest = Math.max(0, ...labels.map((label) => label.length)) * TICK_CHAR_WIDTH * scale;\n const band = Math.sin(rad) * longest + Math.cos(rad) * TICK_LINE_HEIGHT * scale + TICK_GAP;\n return Math.min(\n Math.round(MAX_TILTED_TICK_BAND * scale),\n Math.max(Math.ceil(LEVEL_TICK_BAND * scale), Math.ceil(band)),\n );\n}\n\n/** The width the ticks of a y axis get when a caller does not say, in px at Normal. */\nexport const AXIS_TICK_WIDTH = 48;\n\n/**\n * How much air a FITTED axis leaves between the data and its frame, as a fraction of\n * the range. Recharts fits `[dataMin, dataMax]`, which draws a peak half a stroke\n * outside the plot and a curve running to its limit indistinguishable from the frame.\n */\nconst AUTO_PAD = 0.04;\n\n/** The band a fitted axis draws, padded — and a real band for constant data, which is\n * a zero-height domain recharts cannot scale into. `undefined` when nothing finite. */\nexport function paddedDomain(values: Iterable<number>): [number, number] | undefined {\n let low = Infinity;\n let high = -Infinity;\n for (const value of values) {\n if (!Number.isFinite(value)) continue;\n if (value < low) low = value;\n if (value > high) high = value;\n }\n return padBand(low, high);\n}\n\n/**\n * {@link paddedDomain} for a caller that has already walked its own data — so a row\n * of charts can share one scale without building an array to find two numbers in, and\n * without a second padding rule. `low > high` means \"nothing was seen\": `undefined`.\n */\nexport function padBand(low: number, high: number): [number, number] | undefined {\n if (!(low <= high)) return undefined;\n const pad = (high - low) * AUTO_PAD || Math.abs(high) * AUTO_PAD || 1;\n return [low - pad, high + pad];\n}\n\n/**\n * The whole band a y axis occupies: its ticks, and its title when it draws one. For\n * lining a heading up over a PLOT rather than over its column.\n *\n * `scale` is the text size's (`useTextSize().scale`, §3.2, §10.10): the chart draws every\n * band — the default 48 px and a caller's own `width` alike (keksdose's\n * `MONEY_AXIS_WIDTH`) — this many times wider, because the ticks in it are `text-xs`\n * and grow with the text. A heading lined up over the plot has to pass the same scale.\n * One factor for both sides of a facing pair, so the mirrored bands stay equal.\n */\nexport function axisBandWidth(tickWidth: number | undefined, titled: boolean, scale = 1): number {\n const band = (tickWidth ?? AXIS_TICK_WIDTH) + (titled ? AXIS_TITLE_STRIP : 0);\n return scale === 1 ? band : Math.round(band * scale);\n}\n\n/**\n * The colour an axis TITLE takes, or `undefined` for the neutral one.\n *\n * An axis measuring exactly one line is that line's, and saying so in the title lets a\n * reader find a channel's scale without counting axes. An axis measuring several is\n * nobody's — a title in the first one's colour would be claiming it. Counted off the\n * series, so toggling a second line onto an axis gives the colour up in the same render.\n */\nexport function soleSeriesColor(\n axis: Pick<SeriesChartAxis, \"id\" | \"color\">,\n series: readonly Pick<SeriesChartSeries, \"axis\">[],\n): string | undefined {\n const mine = series.filter((entry) => (entry.axis ?? DEFAULT_Y_AXIS) === axis.id);\n return mine.length === 1 ? axis.color : undefined;\n}\n\n/** The single-axis case, which is most charts. `width` is what the TICKS need;\n * `orientation` is which side they stand on. */\nexport function oneAxis(\n format: ((value: number) => string) | undefined,\n title: string,\n width?: number,\n orientation?: \"left\" | \"right\",\n): SeriesChartAxis[] {\n return [{ id: DEFAULT_Y_AXIS, format, title, width, orientation }];\n}\n\n/** One source's samples: an abscissa and the channels measured against it. */\nexport interface SeriesSource {\n x: readonly number[];\n channels: Readonly<Record<string, readonly number[]>>;\n}\n\n/**\n * Merge sources sampled on different grids into rows the chart can draw.\n *\n * Merged ON THE ABSCISSA VALUE ITSELF, never interpolated onto a common grid: a line\n * through invented points looks exactly like one through measured ones. Where a source\n * has no sample the key is absent, and `connectNulls` bridges the hole with the same\n * straight segment an interpolation would have drawn — without claiming a measurement.\n */\nexport function mergeSeries(sources: readonly SeriesSource[]): Record<string, number>[] {\n const byAbscissa = new Map<number, Record<string, number>>();\n for (const source of sources) {\n source.x.forEach((value, index) => {\n const row = byAbscissa.get(value) ?? { x: value };\n for (const [key, channel] of Object.entries(source.channels)) row[key] = channel[index];\n byAbscissa.set(value, row);\n });\n }\n return [...byAbscissa.values()].sort((a, b) => a.x - b.x);\n}\n\n/**\n * A series key built out of parts — as a CSS identifier.\n *\n * The chart shell paints each series through `--color-<key>`, and skips (with a\n * console warning) any key that is not `[A-Za-z_][A-Za-z0-9_-]*`. A line whose colour\n * was skipped has no stroke at all: an axis, a grid and nothing between them. So a key\n * assembled out of DATA — an id, an enum, a side — goes through here: every other\n * character becomes `_`, the parts are joined with `_`, and a key that would start with\n * a digit or a hyphen gets a leading `_`.\n */\nexport function seriesKey(...parts: (string | number)[]): string {\n const key = parts.map((part) => String(part).replace(/[^A-Za-z0-9_-]/g, \"_\")).join(\"_\");\n return /^[A-Za-z_]/.test(key) ? key : `_${key}`;\n}\n\n/**\n * The band an axis carrying bars or areas draws: the data's extent with ZERO in it,\n * padded only on the sides that are not zero — bars standing on a frame's bottom edge,\n * not floating four per cent above it on a band of air nobody asked for.\n * `undefined` when there is nothing to fit.\n *\n * All-zero data (a quiet period, a zoom window over empty months) is `[0, 1]`: one unit\n * on the free side, the unit {@link padBand} pads a zero extent by. d3 maps every value\n * of a zero-height domain to the range's midpoint, so `[0, 0]` stood the bars on a\n * baseline in the middle of the plot, the \"0\" tick beside it (audit 2026-10-30 DSP-10;\n * keksdose's weekday pattern drew seven 4 px stubs mid-card for a period with no\n * spending).\n */\nexport function anchoredBand(extent: readonly [number, number] | undefined): [number, number] | undefined {\n if (!extent) return undefined;\n const low = Math.min(0, extent[0]);\n const high = Math.max(0, extent[1]);\n if (low === 0 && high === 0) return [0, 1];\n const pad = (high - low) * AUTO_PAD || 1;\n return [low < 0 ? low - pad : 0, high > 0 ? high + pad : 0];\n}\n\n/**\n * Series with their colours settled BEFORE any are switched off.\n *\n * A series with no `color` takes `paletteFor(its position)` — and a legend toggle that\n * hands the chart a shorter list moves every later series one position up, repainting\n * it in its neighbour's colour on each click. Resolving the colours on the full list\n * and filtering after keeps each series in the colour its legend entry shows.\n */\n// Generic so a typed list comes back typed (0.53): a chart of `Month` rows takes it, and\n// its `dot`s still read `point.row` as a `Month`.\nexport function visibleSeries<TRow extends object>(\n series: readonly SeriesChartSeries<TRow>[],\n hidden: ReadonlySet<string>,\n): SeriesChartSeries<TRow>[] {\n return series\n .map((entry, index) => ({ ...entry, color: entry.color ?? paletteFor(index) }))\n .filter((entry) => !hidden.has(entry.key));\n}\n\n/** Where a category or time chart keeps each row's plotted position. Not the caller's\n * key: that one still holds their own value, which `format` and a hit hand back. */\nconst PLOTTED_X = \"__seriesChartX\";\n\n/** A finite number, or `undefined` — the only thing a row cell counts as a sample. */\nexport const finite = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\n/** A time value as epoch ms. A date-only ISO string is LOCAL midnight (see\n * `SeriesChartX.type`); anything unreadable is `undefined`, i.e. not plotted. */\nfunction toTime(value: unknown): number | undefined {\n if (value instanceof Date) return finite(value.getTime());\n if (typeof value === \"number\") return finite(value);\n if (typeof value !== \"string\") return undefined;\n const day = /^(\\d{4})-(\\d{2})(?:-(\\d{2}))?$/.exec(value);\n if (day) return new Date(Number(day[1]), Number(day[2]) - 1, Number(day[3] ?? 1)).getTime();\n return finite(Date.parse(value));\n}\n\n/** A category's identity, so a Date matches another Date of the same instant. */\nconst categoryId = (value: unknown) =>\n value instanceof Date ? `d:${value.getTime()}` : `${typeof value}:${String(value)}`;\n\n/**\n * The abscissa, reduced to a number line — which is all the plot, the ticks and the\n * zoom ever deal in. A number stays itself; a category becomes its slot index; a time\n * its epoch ms. Everything the caller sees (ticks, tooltip, hits) is turned back.\n */\nexport interface XModel {\n kind: \"number\" | \"category\" | \"time\";\n /** The caller's key, still holding their value. */\n sourceKey: string;\n /** The key the plot reads. The same as `sourceKey` on a number line. */\n plotKey: string;\n /** The rows as plotted. The caller's own on a number line. */\n rows: readonly SeriesChartRow[];\n /** The caller's rows, which dots and hits hand back. */\n source: readonly SeriesChartRow[];\n position: (value: unknown) => number | undefined;\n valueAt: (position: number) => SeriesChartXValue;\n}\n\nexport function xModel(rows: readonly SeriesChartRow[], x: SeriesChartX): XModel {\n const sourceKey = x.key ?? \"x\";\n if (x.type === \"category\") {\n const slots = new Map<string, number>();\n rows.forEach((row, index) => {\n const id = categoryId(row[sourceKey]);\n if (!slots.has(id)) slots.set(id, index);\n });\n return {\n kind: \"category\",\n sourceKey,\n plotKey: PLOTTED_X,\n rows: rows.map((row, index) => ({ ...row, [PLOTTED_X]: index })),\n source: rows,\n position: (value) => slots.get(categoryId(value)),\n valueAt: (position) => rows[Math.round(position)]?.[sourceKey] as SeriesChartXValue,\n };\n }\n if (x.type === \"time\") {\n return {\n kind: \"time\",\n sourceKey,\n plotKey: PLOTTED_X,\n rows: rows.map((row) => ({ ...row, [PLOTTED_X]: toTime(row[sourceKey]) })),\n source: rows,\n position: toTime,\n valueAt: (position) => new Date(position),\n };\n }\n return {\n kind: \"number\",\n sourceKey,\n plotKey: sourceKey,\n rows,\n source: rows,\n position: finite,\n valueAt: (position) => position,\n };\n}\n\n/** Caller ticks, as positions inside the domain on show. */\nexport function resolveTicks<T>(\n values: SeriesChartTickValues<T> | undefined,\n domain: [number, number] | undefined,\n position: (value: T) => number | undefined,\n): number[] | undefined {\n if (!values || !domain) return undefined;\n const list = typeof values === \"function\" ? values(domain) : values;\n if (!list) return undefined;\n const slack = (domain[1] - domain[0]) * 1e-9;\n return list\n .map(position)\n .filter((at): at is number => at !== undefined && at >= domain[0] - slack && at <= domain[1] + slack);\n}\n\n/** A low/high pair widened by some values, or `undefined` if there is still none. */\nexport function extend(\n span: readonly [number, number] | undefined,\n values: readonly (number | undefined)[],\n): [number, number] | undefined {\n let out: [number, number] | undefined = span ? [span[0], span[1]] : undefined;\n for (const value of values) {\n if (value === undefined || !Number.isFinite(value)) continue;\n out = out ? [Math.min(out[0], value), Math.max(out[1], value)] : [value, value];\n }\n return out;\n}\n\n/** How a time tick is written, by what one step of the ticks is. */\nexport const TIME_TICK_FORMAT: Record<TimeTickUnit, Intl.DateTimeFormatOptions> = {\n hour: { hour: \"2-digit\", minute: \"2-digit\" },\n day: { day: \"numeric\", month: \"short\" },\n month: { month: \"short\", year: \"2-digit\" },\n year: { year: \"numeric\" },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -10,7 +10,14 @@ export { AXIS_TICK_WIDTH, AXIS_TITLE_STRIP, anchoredBand, axisBandWidth, mergeSe
|
|
|
10
10
|
export type { SeriesSource } from "./series-chart-axes.js";
|
|
11
11
|
import { type ChartTooltipPlacement, type LabelOverride } from "../i18n/kit-labels.js";
|
|
12
12
|
import { type ChartHeight } from "./chart-height.js";
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* One line, area or bar run of a {@link SeriesChart}.
|
|
15
|
+
*
|
|
16
|
+
* `TRow` is the chart's row type (0.53, keksdose after 0.52), and only `dot` reads it: its
|
|
17
|
+
* `point.row` is that type. Without a type argument a series is what it was, and a chart
|
|
18
|
+
* of typed rows still takes it — see {@link SeriesChartProps}.
|
|
19
|
+
*/
|
|
20
|
+
export interface SeriesChartSeries<TRow extends object = object> {
|
|
14
21
|
/** The row key this line reads — and the `--color-<key>` it is painted with, so it
|
|
15
22
|
* must be a CSS identifier. Build keys out of data with {@link seriesKey}. */
|
|
16
23
|
key: string;
|
|
@@ -58,8 +65,9 @@ export interface SeriesChartSeries {
|
|
|
58
65
|
* point: `true` for the default dot, `false`/`null` for none, or any SVG node drawn
|
|
59
66
|
* as-is at `point.cx`/`point.cy` — a buy/sell marker on keksdose's paper price.
|
|
60
67
|
* Never called for a point with no value. Bars have no points, and ignore it.
|
|
68
|
+
* `point.row` is the caller's own row, typed as the chart's rows are (0.53).
|
|
61
69
|
*/
|
|
62
|
-
dot?: boolean | ((point: SeriesChartPoint) => ReactNode);
|
|
70
|
+
dot?: boolean | ((point: SeriesChartPoint<TRow>) => ReactNode);
|
|
63
71
|
/** Line (or area outline) weight in px. Default 2, or 1.5 for a `step`. keksdose
|
|
64
72
|
* draws the subject of a chart at 2.5 and the reference it is read against at 1.5. */
|
|
65
73
|
strokeWidth?: number;
|
|
@@ -94,14 +102,16 @@ export interface SeriesChartSeries {
|
|
|
94
102
|
}
|
|
95
103
|
/** What a series draws. See {@link SeriesChartSeries.type}. */
|
|
96
104
|
export type SeriesChartType = "line" | "bar" | "area";
|
|
97
|
-
/** One point of a series, as a `dot` function is handed it.
|
|
98
|
-
|
|
105
|
+
/** One point of a series, as a `dot` function is handed it. `TRow` is the chart's row
|
|
106
|
+
* type (0.53); without one, `row` is a {@link SeriesChartRow}, as before. */
|
|
107
|
+
export interface SeriesChartPoint<TRow extends object = object> {
|
|
99
108
|
/** The series' key. */
|
|
100
109
|
key: string;
|
|
101
110
|
/** The row's position in `rows`. */
|
|
102
111
|
index: number;
|
|
103
|
-
/** The caller's own row, with everything the chart did not plot still in it
|
|
104
|
-
|
|
112
|
+
/** The caller's own row, with everything the chart did not plot still in it: the very
|
|
113
|
+
* object in `rows`, typed as `rows` is. */
|
|
114
|
+
row: SeriesChartRowOf<TRow>;
|
|
105
115
|
/** The abscissa in the caller's terms: the number, the category, or (time) a Date. */
|
|
106
116
|
x: SeriesChartXValue;
|
|
107
117
|
value: number;
|
|
@@ -113,8 +123,26 @@ export interface SeriesChartPoint {
|
|
|
113
123
|
}
|
|
114
124
|
/** A row of a series chart: one abscissa value and the series' values at it. Anything
|
|
115
125
|
* else in it (a raw ISO period for a drilldown) rides along untouched and is handed
|
|
116
|
-
* back in {@link SeriesChartPoint.row} and {@link SeriesChartHit.row}
|
|
126
|
+
* back in {@link SeriesChartPoint.row} and {@link SeriesChartHit.row} — typed as the
|
|
127
|
+
* caller's rows are since 0.53, and as this where their type names no keys. */
|
|
117
128
|
export type SeriesChartRow = Readonly<Record<string, unknown>>;
|
|
129
|
+
/**
|
|
130
|
+
* The row a hit or a point hands back, for a chart whose rows are `TRow[]` (0.53, keksdose
|
|
131
|
+
* after 0.52): `TRow` itself, so a drilldown reads `hit.row.rawPeriod` as the string it
|
|
132
|
+
* is. A {@link SeriesChartRow} where `TRow` names no keys — `object`, the default, which
|
|
133
|
+
* keeps `SeriesChartHit` and `SeriesChartPoint` without a type argument what they were, and
|
|
134
|
+
* the `object[]` rows an app passes today; `{}`; and `any` or `never` (`rows={[]}`), which
|
|
135
|
+
* are both assignable to `null` while no object type is.
|
|
136
|
+
*
|
|
137
|
+
* Both tests take `TRow` in the CHECKED position, never in the `extends` one, so TypeScript
|
|
138
|
+
* measures every type below as covariant in it (`SeriesChartSeries`, through `dot`'s
|
|
139
|
+
* parameter, contravariant) and relates two of them by their type arguments alone: a
|
|
140
|
+
* `SeriesChartHit<Month>` is a `SeriesChartHit`, and a handler or a series typed without an
|
|
141
|
+
* argument fits a chart of `Month` rows, though an interface has no index signature and is
|
|
142
|
+
* not, field by field, a `SeriesChartRow`. Written `object extends TRow ?`, the type is
|
|
143
|
+
* invariant and both of those stop type-checking.
|
|
144
|
+
*/
|
|
145
|
+
type SeriesChartRowOf<TRow> = [TRow] extends [null] ? SeriesChartRow : [keyof TRow] extends [never] ? SeriesChartRow : TRow;
|
|
118
146
|
/** An abscissa value: a number (`x.type: "number"`), a category (a string, a number or
|
|
119
147
|
* a Date standing for a period), or a time (a Date, epoch ms or an ISO string). */
|
|
120
148
|
export type SeriesChartXValue = number | string | Date;
|
|
@@ -406,28 +434,41 @@ export interface SeriesChartMarker {
|
|
|
406
434
|
/** Radius in px. Default 4.5. */
|
|
407
435
|
r?: number;
|
|
408
436
|
}
|
|
409
|
-
/** What a click on the plot picked.
|
|
410
|
-
|
|
437
|
+
/** What a click on the plot picked. `TRow` is the chart's row type (0.53); without one,
|
|
438
|
+
* `row` is a {@link SeriesChartRow}, as before. */
|
|
439
|
+
export interface SeriesChartHit<TRow extends object = object> {
|
|
411
440
|
/** The row's position in `rows`. */
|
|
412
441
|
index: number;
|
|
413
|
-
/** The caller's own row — with its `rawPeriod`, id or whatever the drilldown needs
|
|
414
|
-
|
|
442
|
+
/** The caller's own row — with its `rawPeriod`, id or whatever the drilldown needs: the
|
|
443
|
+
* very object in `rows`, typed as `rows` is, so it is read without a cast. */
|
|
444
|
+
row: SeriesChartRowOf<TRow>;
|
|
415
445
|
x: SeriesChartXValue;
|
|
416
446
|
/** The series, when the click landed ON a bar. A click anywhere else picks the slot
|
|
417
447
|
* (the period), not a series. */
|
|
418
448
|
key?: string;
|
|
419
449
|
}
|
|
420
|
-
|
|
450
|
+
/**
|
|
451
|
+
* The props of {@link SeriesChart} and {@link StaticSeriesChart}, for rows of type `TRow`.
|
|
452
|
+
*
|
|
453
|
+
* `TRow` is inferred from `rows` (0.53, keksdose after 0.52), and what the chart hands back
|
|
454
|
+
* — `hit.row` in `onPointClick`, `point.row` in a series' `dot` — is that type, so a
|
|
455
|
+
* drilldown reads its own fields without narrowing an `unknown`. Without a type argument,
|
|
456
|
+
* `SeriesChartProps` is what it was: any object is a row, and a row comes back as a
|
|
457
|
+
* {@link SeriesChartRow}. So is `ComponentProps<typeof SeriesChart>`, which reads the
|
|
458
|
+
* constraint, `object`. A series, a handler or a `dot` typed without an argument fits a
|
|
459
|
+
* chart of typed rows too.
|
|
460
|
+
*/
|
|
461
|
+
export interface SeriesChartProps<TRow extends object = object> {
|
|
421
462
|
/**
|
|
422
463
|
* One row per abscissa value. A missing key is a hole (see `connectNulls`).
|
|
423
464
|
*
|
|
424
465
|
* Any object (0.52, refactor audit 2026-10-30, API-2): an `interface` has no index
|
|
425
466
|
* signature, so a typed sweep did not fit `SeriesChartRow` and Kurvenschmiede cast its
|
|
426
467
|
* Ackermann rows `as unknown as Record<string, number>[]`. The chart reads the keys
|
|
427
|
-
* `series` and `x` name, and hands the row back as
|
|
468
|
+
* `series` and `x` name, and hands the row back typed as these are (0.53).
|
|
428
469
|
*/
|
|
429
|
-
rows: readonly
|
|
430
|
-
series: readonly SeriesChartSeries[];
|
|
470
|
+
rows: readonly TRow[];
|
|
471
|
+
series: readonly SeriesChartSeries<TRow>[];
|
|
431
472
|
/** Default: one untitled axis, `"y"`. */
|
|
432
473
|
axes?: readonly SeriesChartAxis[];
|
|
433
474
|
x?: SeriesChartX;
|
|
@@ -482,7 +523,7 @@ export interface SeriesChartProps {
|
|
|
482
523
|
* a chart without bars, named "period — series: value", behind ONE tab stop. With this
|
|
483
524
|
* they are buttons that Enter and Space activate; without, images to read.
|
|
484
525
|
*/
|
|
485
|
-
onPointClick?: (hit: SeriesChartHit) => void;
|
|
526
|
+
onPointClick?: (hit: SeriesChartHit<TRow>) => void;
|
|
486
527
|
/** Where the tooltip may go: for a chart inside a scroll wrapper. See
|
|
487
528
|
* {@link SeriesChartTooltip}. */
|
|
488
529
|
tooltip?: SeriesChartTooltip;
|
|
@@ -595,17 +636,21 @@ export interface SeriesLegendAxes {
|
|
|
595
636
|
* series whose axis is not drawn says the unit that axis would have: "Velocity (mm/s)"
|
|
596
637
|
* — see {@link SeriesChartAxis.unit}. Without them, the labels are as given.
|
|
597
638
|
*/
|
|
598
|
-
export declare function seriesLegendEntries(series: readonly SeriesChartSeries[], { axes, budgeted }?: SeriesLegendAxes): LegendEntry[];
|
|
639
|
+
export declare function seriesLegendEntries<TRow extends object>(series: readonly SeriesChartSeries<TRow>[], { axes, budgeted }?: SeriesLegendAxes): LegendEntry[];
|
|
599
640
|
/**
|
|
600
641
|
* {@link SeriesChart} without the zoom: the same picture, no drag layer, no reset
|
|
601
642
|
* button. For a thumbnail, a print view, or a chart the consumer wraps in its own
|
|
602
643
|
* interaction.
|
|
603
644
|
*/
|
|
604
|
-
export declare function StaticSeriesChart(props: SeriesChartProps): import("react").JSX.Element;
|
|
645
|
+
export declare function StaticSeriesChart<TRow extends object = object>(props: SeriesChartProps<TRow>): import("react").JSX.Element;
|
|
605
646
|
/**
|
|
606
647
|
* The series chart, zoomable. Drag across the plot to zoom (the drag's shape picks the
|
|
607
648
|
* axes), double-click or press the reset button to go back; wrap several in
|
|
608
649
|
* `SharedXZoom` to move their x windows together. Which axes zoom depends on the marks
|
|
609
650
|
* — see {@link SeriesChartProps.zoomAxes}.
|
|
651
|
+
*
|
|
652
|
+
* Generic in its rows (0.53): `hit.row` and a `dot`'s `point.row` are typed as `rows` is —
|
|
653
|
+
* see {@link SeriesChartProps}. A plain function, so the generic survives: a `memo` or a
|
|
654
|
+
* `forwardRef` around it would read `TRow` as its constraint.
|
|
610
655
|
*/
|
|
611
|
-
export declare function SeriesChart(props: SeriesChartProps): import("react").JSX.Element;
|
|
656
|
+
export declare function SeriesChart<TRow extends object = object>(props: SeriesChartProps<TRow>): import("react").JSX.Element;
|
|
@@ -822,7 +822,8 @@ function SeriesPlot({
|
|
|
822
822
|
] });
|
|
823
823
|
}
|
|
824
824
|
const ZoomablePlot = withChartZoom(SeriesPlot);
|
|
825
|
-
function usePlotProps(
|
|
825
|
+
function usePlotProps(typed) {
|
|
826
|
+
const props = typed;
|
|
826
827
|
const x = props.x ?? {};
|
|
827
828
|
const { rows } = props;
|
|
828
829
|
const { type, key } = x;
|