@silverpoint/core 0.2.0 → 0.6.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/dist/index.js CHANGED
@@ -1,52 +1,12 @@
1
- import { scaleLinear, scaleBand } from 'd3-scale';
1
+ import { DEFAULTS } from './chunk-KFBSQH5G.js';
2
+ export { DEFAULTS, FORCED_PRECISION_QUERY, instanceId, resolveConfig } from './chunk-KFBSQH5G.js';
3
+ import { cardLayout, modelBase, measure, emptyModel, readyModel, parseIsoDate, isoDate, createPrng, weekday } from './chunk-PD4MD7JU.js';
4
+ export { addDays, createPrng, isoDate, parseIsoDate, weekday } from './chunk-PD4MD7JU.js';
5
+ import { diagnose, circlePath, round2, readSeries, checkVolume, accessorName, read, formatCategory, formatValue, cartesianPlot, extent, seriesValues, valueAxis, categoryAxis, categoryLabels, formatNumber, finite, inset, rectPath, warnValue, toneOf, toneLevel, TONE_SCALE, checkCount, linearScale, legend, AXIS_BAND, PLOT_INSET, horizontalValueAxis, pillPath, checkSectors, readSectors, polarFrame, ringTones, sectorPath, pointAt, sectorLegend, RIM_LABELS, rimLabels, arcPath, ringTone, polarLabel, TICK_CHAR } from './chunk-OLYKR5PS.js';
6
+ export { SilverpointError, __setDiagnosticSink, bandScale, circlePath, deriveSeed, diagnose, expandDomain, extent, fnv1a32, linearScale, max, min, resolveSeed, round2, roundGeometry, roundPathData } from './chunk-OLYKR5PS.js';
2
7
  import { curveStepAfter, curveNatural, curveLinear, curveMonotoneX, line, curveStep, curveStepBefore, area } from 'd3-shape';
3
8
  import { chordDirected } from 'd3-chord';
4
9
 
5
- // src/render/round.ts
6
- function round2(value) {
7
- const rounded = Math.round(value * 100) / 100;
8
- return Object.is(rounded, -0) ? 0 : rounded;
9
- }
10
- var NUMBER = /-?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?/g;
11
- function roundPathData(d) {
12
- return d.replace(NUMBER, (token) => String(round2(Number(token))));
13
- }
14
- function roundRect(rect) {
15
- return {
16
- x: round2(rect.x),
17
- y: round2(rect.y),
18
- width: round2(rect.width),
19
- height: round2(rect.height)
20
- };
21
- }
22
- function roundStroke(stroke) {
23
- return { ...stroke, d: roundPathData(stroke.d) };
24
- }
25
- function roundTile(tile) {
26
- return {
27
- ...tile,
28
- width: round2(tile.width),
29
- height: round2(tile.height),
30
- angle: round2(tile.angle),
31
- strokes: tile.strokes.map(roundStroke)
32
- };
33
- }
34
- function roundGeometry(geometry) {
35
- return {
36
- viewBox: roundRect(geometry.viewBox),
37
- plot: roundRect(geometry.plot),
38
- strokes: geometry.strokes.map(roundStroke),
39
- labels: geometry.labels.map((label) => ({ ...label, x: round2(label.x), y: round2(label.y) })),
40
- hitAreas: geometry.hitAreas.map((hit) => ({
41
- ...hit,
42
- x: round2(hit.x),
43
- y: round2(hit.y),
44
- ...hit.box ? { box: roundRect(hit.box) } : {}
45
- })),
46
- defs: geometry.defs.map(roundTile)
47
- };
48
- }
49
-
50
10
  // src/render/serialize.ts
51
11
  function serializeGeometry(geometry) {
52
12
  return JSON.stringify(geometry);
@@ -64,208 +24,6 @@ function pathBytes(geometry) {
64
24
  }
65
25
  var PATH_BYTE_BUDGET = 4e4;
66
26
 
67
- // src/render/seed.ts
68
- var FNV_OFFSET_BASIS = 2166136261;
69
- var FNV_PRIME = 16777619;
70
- function utf8Bytes(input) {
71
- const bytes = [];
72
- for (const char of input) {
73
- const code = char.codePointAt(0) ?? 0;
74
- if (code < 128) {
75
- bytes.push(code);
76
- } else if (code < 2048) {
77
- bytes.push(192 | code >> 6, 128 | code & 63);
78
- } else if (code < 65536) {
79
- bytes.push(224 | code >> 12, 128 | code >> 6 & 63, 128 | code & 63);
80
- } else {
81
- bytes.push(
82
- 240 | code >> 18,
83
- 128 | code >> 12 & 63,
84
- 128 | code >> 6 & 63,
85
- 128 | code & 63
86
- );
87
- }
88
- }
89
- return bytes;
90
- }
91
- function fnv1a32(input) {
92
- let hash = FNV_OFFSET_BASIS;
93
- for (const byte of utf8Bytes(input)) {
94
- hash ^= byte;
95
- hash = Math.imul(hash, FNV_PRIME);
96
- }
97
- return hash >>> 0;
98
- }
99
- function deriveSeed(id) {
100
- return fnv1a32(id);
101
- }
102
- function resolveSeed(seed, id) {
103
- if (seed === void 0) return deriveSeed(id);
104
- if (typeof seed === "string") return fnv1a32(seed);
105
- return Number.isFinite(seed) ? Math.trunc(seed) >>> 0 : 0;
106
- }
107
-
108
- // src/render/prng.ts
109
- function createPrng(seed) {
110
- let state = seed >>> 0;
111
- return () => {
112
- state = state + 1831565813 >>> 0;
113
- let t = state;
114
- t = Math.imul(t ^ t >>> 15, t | 1);
115
- t ^= t + Math.imul(t ^ t >>> 7, t | 61);
116
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
117
- };
118
- }
119
-
120
- // src/charts/shared/dates.ts
121
- var DAY_MS = 864e5;
122
- var ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
123
- function parseIsoDate(iso) {
124
- const match = ISO_DATE.exec(iso);
125
- if (!match) return Number.NaN;
126
- return Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])) / DAY_MS;
127
- }
128
- function isoDate(day) {
129
- return new Date(day * DAY_MS).toISOString().slice(0, 10);
130
- }
131
- function addDays(day, days) {
132
- return day + days;
133
- }
134
- function weekday(day) {
135
- return ((day + 4) % 7 + 7) % 7;
136
- }
137
-
138
- // src/diagnostics/diagnose.ts
139
- var SilverpointError = class extends Error {
140
- code;
141
- constructor(code, message) {
142
- super(message);
143
- this.name = "SilverpointError";
144
- this.code = code;
145
- }
146
- };
147
- var consoleSink = (_code, message) => {
148
- console.warn(message);
149
- };
150
- var sink = consoleSink;
151
- var reported = /* @__PURE__ */ new Set();
152
- function __setDiagnosticSink(next) {
153
- sink = next ?? consoleSink;
154
- reported.clear();
155
- return () => {
156
- sink = consoleSink;
157
- reported.clear();
158
- };
159
- }
160
- function format(code, chart, detail, template) {
161
- const specifics = detail.message ? ` ${detail.message}` : "";
162
- return `[${code}] ${chart}: ${template.what} (\`${detail.property}\`).${specifics} ${template.todo}. (${template.req})`;
163
- }
164
- var ERRORS = {
165
- SP009: {
166
- req: "REQ-097",
167
- what: "a scale bound cannot be derived from the data and was not supplied",
168
- todo: "Pass the named property explicitly"
169
- },
170
- SP012: {
171
- req: "REQ-127",
172
- what: "the ground does not reach the minimum contrast",
173
- todo: "Recompute the palette; colours are not chosen by eye"
174
- }
175
- };
176
- function diagnose(code, chart, detail) {
177
- const error = ERRORS[code];
178
- if (error) {
179
- throw new SilverpointError(code, format(code, chart, detail, error));
180
- }
181
- if (process.env.NODE_ENV !== "production") {
182
- developmentDiagnose(code, chart, detail);
183
- }
184
- }
185
- function developmentDiagnose(code, chart, detail) {
186
- const template = WARNINGS[code];
187
- if (!template) return;
188
- const message = format(code, chart, detail, template);
189
- if (code === "SP005") {
190
- throw new SilverpointError(code, message);
191
- }
192
- if (reported.has(message)) return;
193
- reported.add(message);
194
- sink(code, message);
195
- }
196
- var WARNINGS = {
197
- SP001: {
198
- req: "REQ-007",
199
- what: "the dataset is empty; the ground's empty state is drawn",
200
- todo: "Pass at least one row, or omit `data` to see the demo dataset"
201
- },
202
- SP002: {
203
- req: "REQ-008",
204
- what: "a value cannot be drawn as given (null, not finite, or outside the data contract); it is corrected or omitted",
205
- todo: "Check the value against the chart's data contract (Data Model \xA72)"
206
- },
207
- SP003: {
208
- req: "REQ-009",
209
- what: "the container measures 0 px; the render is deferred",
210
- todo: "Give the container a size, or pin `width` and `height`"
211
- },
212
- SP004: {
213
- req: "REQ-010",
214
- what: "the scale domain has zero length; it is expanded with the ground's domainPadding",
215
- todo: "Nothing to do if the data is constant; otherwise check the accessor"
216
- },
217
- SP005: {
218
- req: "REQ-025",
219
- what: "more than one element is marked with white heightening; only the first is applied",
220
- todo: "Heighten a single element per chart"
221
- },
222
- SP006: {
223
- req: "REQ-026",
224
- what: "the inker is not registered; falling back to NullInker",
225
- todo: "Register the inker or fix the ground's `inker` token"
226
- },
227
- SP007: {
228
- req: "REQ-045",
229
- what: "the ground is not registered; falling back to silverpoint",
230
- todo: "Call registerGround() before rendering, or fix the name"
231
- },
232
- SP008: {
233
- req: "REQ-096",
234
- what: "the data volume is above the family's threshold",
235
- todo: "Aggregate the data before charting it"
236
- },
237
- SP010: {
238
- req: "REQ-091",
239
- what: "the chord ring has more than 12 categories",
240
- todo: "Group the smaller categories"
241
- },
242
- SP011: {
243
- req: "NFR \xA77",
244
- what: "the path byte budget of 40 KB is exceeded",
245
- todo: "Use `hatchFill: 'tile'` or a larger hatch gap"
246
- },
247
- SP014: {
248
- req: "REQ-204",
249
- what: "a dashboard cell spans more columns than the breakpoint has; it is clamped",
250
- todo: "Lower the span, or give that breakpoint more columns"
251
- },
252
- SP015: {
253
- req: "REQ-205",
254
- what: "the dashboard layout and its children disagree; unmatched children are placed in source order, span 1",
255
- todo: "Give every child a `cell` the layout declares, once"
256
- },
257
- SP016: {
258
- req: "REQ-217",
259
- what: "a chart in a linked dashboard has no field named by `link.key`; it shows no linked mark",
260
- todo: "Link on a field every linked chart carries, or leave this chart out of the link"
261
- },
262
- SP013: {
263
- req: "REQ-032",
264
- what: "the @silverpoint/fonts face failed to load; rendering fell back to the system stack",
265
- todo: "Install @silverpoint/fonts and import its stylesheet; golden images will not match until then"
266
- }
267
- };
268
-
269
27
  // src/render/heighten.ts
270
28
  function isOutlineOf(candidate, heightened) {
271
29
  return candidate.part === "ink" && (candidate.paint ?? "stroke") === "stroke" && candidate.d === heightened.d;
@@ -409,66 +167,6 @@ async function checkTypeface(fonts, chart, face = DISPLAY_FACE_PROBE) {
409
167
  return loaded;
410
168
  }
411
169
 
412
- // src/scales/util.ts
413
- function min(values) {
414
- let result;
415
- for (const value of values) {
416
- if (Number.isFinite(value) && (result === void 0 || value < result)) result = value;
417
- }
418
- return result;
419
- }
420
- function max(values) {
421
- let result;
422
- for (const value of values) {
423
- if (Number.isFinite(value) && (result === void 0 || value > result)) result = value;
424
- }
425
- return result;
426
- }
427
- function extent(values) {
428
- const low = min(values);
429
- const high = max(values);
430
- return low === void 0 || high === void 0 ? void 0 : [low, high];
431
- }
432
- function expandDomain(domain, padding, site, fromZero = false) {
433
- const [low, high] = domain;
434
- if (low !== high) return [low, high];
435
- const spread = low === 0 ? padding : Math.abs(low) * padding;
436
- if (fromZero && low === 0) {
437
- if (process.env.NODE_ENV !== "production") {
438
- diagnose("SP004", site.chart, { property: site.property, message: `Domain [0, 0] became [0, ${2 * spread}].` });
439
- }
440
- return [0, 2 * spread];
441
- }
442
- if (process.env.NODE_ENV !== "production") {
443
- diagnose("SP004", site.chart, {
444
- property: site.property,
445
- message: `Domain [${low}, ${high}] became [${low - spread}, ${high + spread}].`
446
- });
447
- }
448
- return [low - spread, high + spread];
449
- }
450
- function linearScale(domain, range, options) {
451
- const expanded = expandDomain(domain, options.padding, options, options.fromZero);
452
- const scale = scaleLinear().domain(expanded).range(range);
453
- if (options.nice) scale.nice(4);
454
- const [low, high] = scale.domain();
455
- const result = ((value) => scale(value));
456
- Object.defineProperty(result, "domain", { value: [low, high] });
457
- result.ticks = (count) => scale.ticks(count);
458
- return result;
459
- }
460
- function bandScale(domain, range, options = {}) {
461
- const scale = scaleBand().domain(domain).range(range).paddingInner(options.paddingInner ?? 0).paddingOuter(options.paddingOuter ?? 0);
462
- const bandwidth = scale.bandwidth();
463
- const result = ((value) => scale(value));
464
- Object.defineProperty(result, "bandwidth", { value: bandwidth });
465
- result.center = (value) => {
466
- const start = scale(value);
467
- return start === void 0 ? void 0 : start + bandwidth / 2;
468
- };
469
- return result;
470
- }
471
-
472
170
  // src/ink/null-inker.ts
473
171
  var NullInker = Object.freeze({
474
172
  name: "null",
@@ -491,363 +189,6 @@ function resolveInker(name, chart, builtins = []) {
491
189
  return NullInker;
492
190
  }
493
191
 
494
- // src/config/resolve.ts
495
- var DEFAULTS = Object.freeze({
496
- ground: "silverpoint",
497
- substrate: "cream",
498
- mode: "ink",
499
- chrome: "card",
500
- hatchFill: "tile",
501
- height: 160,
502
- dataTable: "hidden",
503
- locale: "en"
504
- });
505
- function resolveConfig(props, provider = {}, environment = {}) {
506
- const mode = environment.forcedPrecision ? "precision" : props.mode ?? provider.mode ?? DEFAULTS.mode;
507
- return {
508
- ground: props.ground ?? provider.ground ?? DEFAULTS.ground,
509
- substrate: props.substrate ?? provider.substrate ?? DEFAULTS.substrate,
510
- mode,
511
- chrome: props.chrome ?? DEFAULTS.chrome,
512
- hatchFill: props.hatchFill ?? DEFAULTS.hatchFill,
513
- height: props.height ?? DEFAULTS.height,
514
- dataTable: props.dataTable ?? DEFAULTS.dataTable,
515
- locale: props.locale ?? provider.locale ?? environment.locale ?? DEFAULTS.locale
516
- };
517
- }
518
- var FORCED_PRECISION_QUERY = "(prefers-contrast: more), (forced-colors: active)";
519
- function instanceId(chart, token) {
520
- const slug = chart.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
521
- const safe = String(token).replace(/[^A-Za-z0-9_-]/g, "");
522
- return `sp-${slug}-${safe}`;
523
- }
524
-
525
- // src/charts/shared/format.ts
526
- function read(accessor, datum, index) {
527
- return typeof accessor === "function" ? accessor(datum, index) : datum[accessor];
528
- }
529
- function accessorName(accessor, fallback) {
530
- return typeof accessor === "string" ? accessor : fallback;
531
- }
532
- var FORMATTERS = /* @__PURE__ */ new Map();
533
- var MAX_FORMATTERS = 64;
534
- function formatNumber(value, locale, options) {
535
- const resolved = options ?? { maximumFractionDigits: 2 };
536
- const read2 = [];
537
- for (const name in resolved) read2.push(`${name}=${JSON.stringify(resolved[name])}`);
538
- const key = `${locale}|${read2.sort().join("&")}`;
539
- let formatter = FORMATTERS.get(key);
540
- if (!formatter) {
541
- if (FORMATTERS.size >= MAX_FORMATTERS) FORMATTERS.clear();
542
- formatter = new Intl.NumberFormat(locale, resolved);
543
- FORMATTERS.set(key, formatter);
544
- }
545
- return formatter.format(value);
546
- }
547
- function formatValue(value, locale, options) {
548
- if (typeof value === "number") {
549
- return Number.isFinite(value) ? formatNumber(value, locale, options) : "\u2014";
550
- }
551
- return value === null || value === void 0 ? "\u2014" : String(value);
552
- }
553
- function formatCategory(value, locale) {
554
- return formatValue(value, locale, typeof value === "number" ? { useGrouping: false, maximumFractionDigits: 2 } : void 0);
555
- }
556
- function circlePath(cx, cy, r) {
557
- return `M${cx - r},${cy}A${r},${r},0,1,0,${cx + r},${cy}A${r},${r},0,1,0,${cx - r},${cy}Z`;
558
- }
559
-
560
- // src/charts/shared/card.ts
561
- var CARD_PADDING = 16;
562
- var TITLE_ROW = 20;
563
- var VALUE_ROW = 52;
564
- var HEADER_GAP = 8;
565
- var FOOTER_ROW = 30;
566
- function cardLayout(props, options) {
567
- const { width, areaHeight: areaHeight2, chrome, locale } = options;
568
- if (chrome === "bare") {
569
- const box = { x: 0, y: 0, width, height: areaHeight2 };
570
- return { viewBox: box, area: box, strokes: [], labels: [] };
571
- }
572
- const labels = [];
573
- const strokes = [];
574
- const left = CARD_PADDING;
575
- const right = width - CARD_PADDING;
576
- let cursor = CARD_PADDING;
577
- if (props.title !== void 0 || props.badge !== void 0) {
578
- const baseline = cursor + 11;
579
- if (props.title !== void 0) {
580
- labels.push({ x: left, y: baseline, text: props.title, kind: "title", part: "text", anchor: "start" });
581
- }
582
- if (props.badge !== void 0) {
583
- labels.push({ x: right, y: baseline, text: props.badge, kind: "badge", part: "axis", anchor: "end" });
584
- }
585
- cursor += TITLE_ROW;
586
- }
587
- if (props.value !== void 0 || props.unit !== void 0) {
588
- if (props.value !== void 0) {
589
- labels.push({
590
- x: left,
591
- y: cursor + 30,
592
- text: formatValue(props.value, locale, props.numberFormat),
593
- kind: "value",
594
- part: "text",
595
- anchor: "start"
596
- });
597
- }
598
- if (props.unit !== void 0) {
599
- labels.push({ x: left, y: cursor + 46, text: props.unit, kind: "unit", part: "axis", anchor: "start" });
600
- }
601
- cursor += VALUE_ROW;
602
- }
603
- if (cursor > CARD_PADDING) cursor += HEADER_GAP;
604
- const area5 = { x: left, y: cursor, width: right - left, height: areaHeight2 };
605
- cursor += areaHeight2;
606
- if (props.footerLeft !== void 0 || props.footerRight !== void 0) {
607
- const ruleY = cursor + 8;
608
- strokes.push({ d: `M${left},${ruleY}H${right}`, role: "ornament", part: "rule" });
609
- if (props.footerLeft !== void 0) {
610
- labels.push({ x: left, y: ruleY + 18, text: props.footerLeft, kind: "footer", part: "axis", anchor: "start" });
611
- }
612
- if (props.footerRight !== void 0) {
613
- labels.push({ x: right, y: ruleY + 18, text: props.footerRight, kind: "footer", part: "axis", anchor: "end" });
614
- }
615
- cursor += FOOTER_ROW;
616
- }
617
- const height = cursor + CARD_PADDING;
618
- const inset2 = 0.5;
619
- strokes.unshift({
620
- d: `M${inset2},${inset2}H${width - inset2}V${height - inset2}H${inset2}Z`,
621
- role: "ornament",
622
- part: "rule"
623
- });
624
- return { viewBox: { x: 0, y: 0, width, height }, area: area5, strokes, labels };
625
- }
626
-
627
- // src/charts/shared/cells.ts
628
- function rectPath(rect) {
629
- const { x, y, width, height } = rect;
630
- return `M${x},${y}H${x + width}V${y + height}H${x}Z`;
631
- }
632
- function inset(rect, by) {
633
- return {
634
- x: rect.x + by,
635
- y: rect.y + by,
636
- width: Math.max(rect.width - 2 * by, 0),
637
- height: Math.max(rect.height - 2 * by, 0)
638
- };
639
- }
640
- function finite(raw) {
641
- return typeof raw === "number" && Number.isFinite(raw) ? raw : void 0;
642
- }
643
- function toneOf(ratio) {
644
- if (!(ratio > 0)) return 0;
645
- if (ratio <= 0.25) return 1;
646
- if (ratio <= 0.5) return 2;
647
- if (ratio <= 0.75) return 3;
648
- return 4;
649
- }
650
- function toneLevel(raw) {
651
- return Math.min(Math.max(Math.round(raw), 0), 4);
652
- }
653
- function warnValue(chart, property, message) {
654
- if (process.env.NODE_ENV !== "production") diagnose("SP002", chart, { property, message });
655
- }
656
-
657
- // src/charts/shared/cartesian.ts
658
- var AXIS_BAND = 20;
659
- var PLOT_INSET = 6;
660
- var LABEL_SPACING = 48;
661
- function cartesianPlot(area5) {
662
- return {
663
- x: area5.x + PLOT_INSET,
664
- y: area5.y + PLOT_INSET,
665
- width: Math.max(area5.width - 2 * PLOT_INSET, 1),
666
- height: Math.max(area5.height - AXIS_BAND - PLOT_INSET, 1)
667
- };
668
- }
669
- function readSeries(data, accessor, fallbackName) {
670
- let missing = 0;
671
- const points = data.map((datum, index) => {
672
- const raw = read(accessor, datum, index);
673
- const value = typeof raw === "number" && Number.isFinite(raw) ? raw : void 0;
674
- if (value === void 0) missing += 1;
675
- return { index, datum, value };
676
- });
677
- return { key: accessorName(accessor, fallbackName), points, missing };
678
- }
679
- var POINTS_PER_SERIES = 500;
680
- function checkVolume(chart, series) {
681
- for (const s of series) checkCount(chart, s.key, s.points.length);
682
- }
683
- function checkCount(chart, property, count) {
684
- if (process.env.NODE_ENV === "production" || count <= POINTS_PER_SERIES) return;
685
- diagnose("SP008", chart, { property, message: `${count} points; the ceiling is ${POINTS_PER_SERIES} per series.` });
686
- }
687
- function seriesValues(series) {
688
- return series.flatMap((s) => s.points.flatMap((p) => p.value === void 0 ? [] : [p.value]));
689
- }
690
- function valueAxis(plot, domain, options) {
691
- const bottom = plot.y + plot.height;
692
- const low = options.zero === false ? domain[0] : Math.min(0, domain[0]);
693
- const high = options.zero === false ? domain[1] : Math.max(0, domain[1]);
694
- const scale = linearScale([low, high], [bottom, plot.y], {
695
- chart: options.chart,
696
- property: options.property,
697
- padding: options.padding,
698
- nice: options.nice !== false,
699
- fromZero: options.zero !== false
700
- });
701
- const strokes = [];
702
- const labels = [];
703
- for (const tick of scale.ticks(4)) {
704
- const ty = scale(tick);
705
- if (tick === scale.domain[0]) continue;
706
- strokes.push({ d: `M${plot.x},${ty}H${plot.x + plot.width}`, role: "ornament", part: "grid" });
707
- labels.push({ x: plot.x, y: ty - 3, text: formatNumber(tick, options.locale, options.numberFormat), kind: "tick", part: "axis", anchor: "start" });
708
- }
709
- strokes.push({ d: `M${plot.x},${bottom}H${plot.x + plot.width}`, role: "ornament", part: "rule" });
710
- return { scale, strokes, labels };
711
- }
712
- function categoryAxis(xValues, plot, options) {
713
- const numeric = options.numeric !== false && xValues.length > 0 && xValues.every((v) => typeof v === "number" && Number.isFinite(v));
714
- if (numeric) {
715
- const numbers = xValues;
716
- const x = linearScale(extent(numbers) ?? [0, 0], [plot.x, plot.x + plot.width], {
717
- chart: options.chart,
718
- property: options.property,
719
- padding: options.padding
720
- });
721
- return { at: (index) => x(numbers[index] ?? 0), bandwidth: 0 };
722
- }
723
- const keys = xValues.map((_, index) => String(index));
724
- const band = bandScale(keys, [plot.x, plot.x + plot.width], { paddingInner: options.paddingInner, paddingOuter: options.paddingOuter });
725
- return { at: (index) => band.center(String(index)) ?? plot.x, bandwidth: band.bandwidth };
726
- }
727
- function categoryLabels(texts, at2, area5, plot) {
728
- const count = texts.length;
729
- const step = Math.max(1, Math.ceil(count / Math.max(2, Math.floor(plot.width / LABEL_SPACING))));
730
- const labels = [];
731
- for (let index = 0; index < count; index += step) {
732
- labels.push({
733
- x: at2(index),
734
- y: area5.y + area5.height - 5,
735
- text: texts[index] ?? "",
736
- kind: "tick",
737
- part: "axis",
738
- anchor: index === 0 ? "start" : "middle"
739
- });
740
- }
741
- return labels;
742
- }
743
- var LEGEND_BAND = 22;
744
- var TICK_CHAR = 5.2;
745
- var LEGEND_CHAR = TICK_CHAR;
746
- function legend(area5, entries) {
747
- const strokes = [];
748
- const labels = [];
749
- let x = area5.x + PLOT_INSET;
750
- for (const entry of entries) {
751
- const swatch = { x, y: area5.y + 4, width: 12, height: 7 };
752
- strokes.push({ d: rectPath(swatch), role: "ornament", part: entry.part, ...entry.tone ? { tone: entry.tone } : {}, ...entry.dash ? { dash: entry.dash } : {} });
753
- labels.push({ x: x + 16, y: area5.y + 11, text: entry.name, kind: "tick", part: "axis", anchor: "start" });
754
- x += 16 + entry.name.length * LEGEND_CHAR + 12;
755
- }
756
- return { area: { x: area5.x, y: area5.y + LEGEND_BAND, width: area5.width, height: Math.max(area5.height - LEGEND_BAND, 1) }, strokes, labels };
757
- }
758
- function pillPath(rect) {
759
- const { x, y, width, height } = rect;
760
- const r = Math.min(width, height) / 2;
761
- if (r <= 0) return `M${x},${y}H${x + width}V${y + height}H${x}Z`;
762
- return `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}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`;
763
- }
764
- function horizontalValueAxis(plot, area5, domain, options) {
765
- const scale = linearScale([Math.min(0, domain[0]), Math.max(0, domain[1])], [plot.x, plot.x + plot.width], {
766
- chart: options.chart,
767
- property: options.property,
768
- padding: options.padding,
769
- nice: true,
770
- fromZero: true
771
- });
772
- const strokes = [];
773
- const labels = [];
774
- for (const tick of scale.ticks(4)) {
775
- const tx = scale(tick);
776
- if (tick !== 0) strokes.push({ d: `M${tx},${plot.y}V${plot.y + plot.height}`, role: "ornament", part: "grid" });
777
- labels.push({ x: tx, y: area5.y + area5.height - 5, text: formatNumber(tick, options.locale, options.numberFormat), kind: "tick", part: "axis", anchor: "middle" });
778
- }
779
- strokes.push({ d: `M${scale(0)},${plot.y}V${plot.y + plot.height}`, role: "ornament", part: "rule" });
780
- return { scale, strokes, labels };
781
- }
782
-
783
- // src/charts/shared/shell.ts
784
- function modelBase(chart, props, context, fallbackName, table) {
785
- const { id } = context;
786
- const name = props.label ?? props.title ?? fallbackName;
787
- return {
788
- chart,
789
- id,
790
- chrome: props.chrome ?? "card",
791
- name,
792
- ids: { title: `${id}-title`, desc: `${id}-desc`, table: `${id}-table` },
793
- table: { caption: name, ...table },
794
- dataTable: props.dataTable ?? "hidden"
795
- };
796
- }
797
- function areaHeight(props) {
798
- return props.height ?? 160;
799
- }
800
- function measure(base, props, context) {
801
- const width = props.width ?? context.width;
802
- const height = areaHeight(props);
803
- if (width !== void 0 && width > 0 && height > 0) return { width, height };
804
- if (width !== void 0 && process.env.NODE_ENV !== "production") {
805
- diagnose("SP003", base.chart, {
806
- property: width <= 0 ? "width" : "height",
807
- message: `Measured ${width} \xD7 ${height} px.`
808
- });
809
- }
810
- const box = { x: 0, y: 0, width: 0, height: 0 };
811
- return {
812
- deferred: {
813
- ...base,
814
- status: "deferred",
815
- geometry: { viewBox: box, plot: box, strokes: [], labels: [], hitAreas: [], defs: [] },
816
- description: props.description ?? base.name
817
- }
818
- };
819
- }
820
- function emptyModel(base, props, context, frame, datasetEmpty) {
821
- if (datasetEmpty && process.env.NODE_ENV !== "production") {
822
- diagnose("SP001", base.chart, { property: "data" });
823
- }
824
- const { plot } = frame;
825
- const strokes = [...frame.strokes];
826
- if (context.emptyState.rule) {
827
- strokes.push({ d: `M${plot.x},${plot.y + plot.height}H${plot.x + plot.width}`, role: "ornament", part: "rule" });
828
- }
829
- const labels = [
830
- ...frame.labels,
831
- {
832
- x: plot.x + plot.width / 2,
833
- y: plot.y + plot.height / 2,
834
- text: context.emptyState.text,
835
- kind: "empty",
836
- part: "axis",
837
- anchor: "middle"
838
- }
839
- ];
840
- return {
841
- ...base,
842
- status: "ready",
843
- description: props.description ?? `${base.name}. ${context.emptyState.text}.`,
844
- geometry: roundGeometry({ viewBox: frame.viewBox, plot, strokes, labels, hitAreas: [], defs: [] })
845
- };
846
- }
847
- function readyModel(base, description, geometry) {
848
- return { ...base, status: "ready", description, geometry: roundGeometry({ ...geometry, defs: [] }) };
849
- }
850
-
851
192
  // src/charts/line-chart/demo.ts
852
193
  var LINE_CHART_DEMO = /* @__PURE__ */ Object.freeze(
853
194
  /* @__PURE__ */ [
@@ -1043,6 +384,12 @@ var NAVIGATION_KEYS = ["ArrowRight", "ArrowDown", "ArrowLeft", "ArrowUp", "Home"
1043
384
  function stepActive(geometry, current, key) {
1044
385
  if (!NAVIGATION_KEYS.includes(key)) return void 0;
1045
386
  if (key === "Escape") return null;
387
+ const hits = geometry.hitAreas;
388
+ if (hits[0]?.moves) {
389
+ const here = current ? hits.findIndex((hit) => hit.seriesKey === current.seriesKey && hit.index === current.index) : -1;
390
+ const to = here < 0 ? hits[0].moves[key === "End" ? "End" : "Home"] : hits[here]?.moves?.[key];
391
+ return toActiveItem(hits[to ?? Math.max(here, 0)]);
392
+ }
1046
393
  const grid = geometry.hitAreas.length > 0 && geometry.hitAreas.every((hit) => hit.cell !== void 0);
1047
394
  if (grid) return stepGrid(geometry.hitAreas, current, key);
1048
395
  const seriesKey = current?.seriesKey ?? geometry.hitAreas[0]?.seriesKey;
@@ -1192,7 +539,7 @@ function buildBulletChart(props, context) {
1192
539
  }
1193
540
  const rowHeight = plot.height / rows.length;
1194
541
  const barHeight = Math.min(MAX_BAR, rowHeight * 0.35);
1195
- const at2 = (percent) => plot.x + percent / 100 * plot.width;
542
+ const at = (percent) => plot.x + percent / 100 * plot.width;
1196
543
  let met = 0;
1197
544
  for (const row of rows) {
1198
545
  const top = plot.y + row.index * rowHeight;
@@ -1204,16 +551,16 @@ function buildBulletChart(props, context) {
1204
551
  warnValue(CHART2, actualName, `Row ${row.index} has no finite value; its bar is omitted.`);
1205
552
  } else {
1206
553
  const actual = clampPercent(row.actual, actualName, row.index);
1207
- const bar = { x: plot.x, y: barY, width: at2(actual) - plot.x, height: barHeight };
554
+ const bar = { x: plot.x, y: barY, width: at(actual) - plot.x, height: barHeight };
1208
555
  if (bar.width > 0) strokes.push({ d: rectPath(bar), role: "encoding", part: "ink", tone: 2 });
1209
556
  labels.push({ x: plot.x + plot.width, y: baseline, text: formatNumber(row.actual, locale, numberFormat), kind: "tick", part: "axis", anchor: "end" });
1210
- hitAreas.push({ seriesKey: actualName, index: row.index, datum: row.datum, value: row.actual, x: at2(actual), y: barY + barHeight / 2, box: bar });
557
+ hitAreas.push({ seriesKey: actualName, index: row.index, datum: row.datum, value: row.actual, x: at(actual), y: barY + barHeight / 2, box: bar });
1211
558
  if (row.target !== void 0 && row.actual >= row.target) met += 1;
1212
559
  }
1213
560
  if (row.target === void 0) {
1214
561
  warnValue(CHART2, targetName, `Row ${row.index} has no finite target; its marker is omitted.`);
1215
562
  } else {
1216
- const x = at2(clampPercent(row.target, targetName, row.index));
563
+ const x = at(clampPercent(row.target, targetName, row.index));
1217
564
  strokes.push({ d: `M${x},${barY - MARKER_REACH}V${barY + barHeight + MARKER_REACH}`, role: "encoding", part: "ink", weight: 2 });
1218
565
  }
1219
566
  }
@@ -1335,7 +682,6 @@ var CELL_GAP = 2;
1335
682
  var HEADER_BAND = 14;
1336
683
  var DIGIT_WIDTH = 5.5;
1337
684
  var LINE_HEIGHT = 12;
1338
- var CELL_SCALE = { 0: 0.4, 1: 0.55, 2: 0.7, 3: 0.85, 4: 1 };
1339
685
  function buildHeatmapChart(props, context) {
1340
686
  const usesDemo = props.data === void 0;
1341
687
  const data = props.data ?? HEATMAP_CHART_DEMO;
@@ -1408,7 +754,7 @@ function buildHeatmapChart(props, context) {
1408
754
  continue;
1409
755
  }
1410
756
  const tone = toneOf(value / scaleMax);
1411
- const scale = printed ? 1 : CELL_SCALE[tone];
757
+ const scale = printed ? 1 : TONE_SCALE[tone];
1412
758
  const drawn = { x: cx - cell.width * scale / 2, y: cy - cell.height * scale / 2, width: cell.width * scale, height: cell.height * scale };
1413
759
  strokes.push({ d: rectPath(drawn), role: "encoding", part: "ink", ...tone > 0 ? { tone } : {} });
1414
760
  if (printed) labels.push({ x: cx, y: cy + 4, text: formatNumber(value, locale, numberFormat), kind: "tick", part: "text", anchor: "middle" });
@@ -1719,8 +1065,8 @@ var CHART7 = "ActivityGrid";
1719
1065
  var PLOT_INSET7 = 6;
1720
1066
  var MONTH_BAND = 14;
1721
1067
  var DEFAULT_WEEKS = 26;
1722
- var DAY_MS2 = 864e5;
1723
- var CELL_SCALE2 = { 0: 0.4, 1: 0.55, 2: 0.7, 3: 0.85, 4: 1 };
1068
+ var DAY_MS = 864e5;
1069
+ var CELL_SCALE = { 0: 0.4, 1: 0.55, 2: 0.7, 3: 0.85, 4: 1 };
1724
1070
  var CELL_FILL = 0.86;
1725
1071
  var MONTH_GAP = 3;
1726
1072
  function buildActivityGrid(props, context) {
@@ -1785,7 +1131,7 @@ function buildActivityGrid(props, context) {
1785
1131
  const column = Math.floor(index / 7);
1786
1132
  const row = index % 7;
1787
1133
  if (row === 0) {
1788
- const name = month.format(new Date(d.day * DAY_MS2));
1134
+ const name = month.format(new Date(d.day * DAY_MS));
1789
1135
  const last = months.at(-1);
1790
1136
  if (name !== last?.name) {
1791
1137
  if (last && column - last.column < MONTH_GAP) {
@@ -1795,7 +1141,7 @@ function buildActivityGrid(props, context) {
1795
1141
  }
1796
1142
  }
1797
1143
  }
1798
- const side = slot * CELL_FILL * CELL_SCALE2[d.level];
1144
+ const side = slot * CELL_FILL * CELL_SCALE[d.level];
1799
1145
  const cx = plot.x + column * slot + slot / 2;
1800
1146
  const cy = top + row * slot + slot / 2;
1801
1147
  const cell = { x: cx - side / 2, y: cy - side / 2, width: side, height: side };
@@ -2495,109 +1841,6 @@ function buildFunnelChart(props, context) {
2495
1841
  }
2496
1842
  var funnelChart = /* @__PURE__ */ Object.freeze({ name: CHART15, build: buildFunnelChart });
2497
1843
 
2498
- // src/charts/shared/polar.ts
2499
- function polarFrame(area5, labelRoom = 0) {
2500
- return {
2501
- cx: area5.x + area5.width / 2,
2502
- cy: area5.y + area5.height / 2,
2503
- radius: Math.max(Math.min(area5.width, area5.height) / 2 - PLOT_INSET - labelRoom, 1)
2504
- };
2505
- }
2506
- var RIM_LABELS = 14;
2507
- function rimLabels(frame, entries, most = 24) {
2508
- const step = Math.max(1, Math.ceil(entries.length / most));
2509
- return entries.filter((_, i) => i % step === 0).map((e) => polarLabel(frame, e.angle, frame.radius + 8, e.text));
2510
- }
2511
- function pointAt(frame, angle, r) {
2512
- return { x: frame.cx + r * Math.sin(angle), y: frame.cy - r * Math.cos(angle) };
2513
- }
2514
- var EPSILON = 1e-9;
2515
- var at = (frame, angle, r) => {
2516
- const p = pointAt(frame, angle, r);
2517
- return `${p.x},${p.y}`;
2518
- };
2519
- function arcTo(frame, r, end, clockwise) {
2520
- return `A${r},${r},0,0,${clockwise ? 1 : 0},${at(frame, end, r)}`;
2521
- }
2522
- function sweep(frame, r, start, end, clockwise) {
2523
- if (Math.abs(end - start) <= Math.PI) return arcTo(frame, r, end, clockwise);
2524
- const middle = (start + end) / 2;
2525
- return arcTo(frame, r, middle, clockwise) + arcTo(frame, r, end, clockwise);
2526
- }
2527
- function arcPath(frame, r, start, end) {
2528
- if (Math.abs(end - start) < EPSILON || r <= 0) return "";
2529
- return `M${at(frame, start, r)}${sweep(frame, r, start, end, end > start)}`;
2530
- }
2531
- function sectorPath(frame, shape) {
2532
- const { inner, outer, start, end } = shape;
2533
- if (Math.abs(end - start) < EPSILON || outer <= 0) return "";
2534
- const clockwise = end > start;
2535
- const outerArc = `M${at(frame, start, outer)}${sweep(frame, outer, start, end, clockwise)}`;
2536
- if (inner <= 0) return `${outerArc}L${frame.cx},${frame.cy}Z`;
2537
- return `${outerArc}L${at(frame, end, inner)}${sweep(frame, inner, end, start, !clockwise)}Z`;
2538
- }
2539
- var POLE = 0.1;
2540
- function polarLabel(frame, angle, r, text, kind = "tick") {
2541
- const p = pointAt(frame, angle, r);
2542
- const side = Math.sin(angle);
2543
- const anchor = side > POLE ? "start" : side < -POLE ? "end" : "middle";
2544
- return { x: p.x, y: p.y + 3, text, kind, part: "axis", anchor };
2545
- }
2546
- function readSectors(data, nameKey, valueKey, chart, locale) {
2547
- const valueName = accessorName(valueKey, "value");
2548
- const seen = /* @__PURE__ */ new Map();
2549
- const sectors = [];
2550
- data.forEach((datum, index) => {
2551
- const value = finite(read(valueKey, datum, index));
2552
- if (value === void 0 || value < 0) {
2553
- warnValue(chart, valueName, `Row ${index} has a ${valueName} of ${String(read(valueKey, datum, index))}; a sector needs a finite value \u2265 0, so it is omitted.`);
2554
- return;
2555
- }
2556
- const given = read(nameKey, datum, index);
2557
- if (given === void 0 || given === null || given === "") warnValue(chart, accessorName(nameKey, "name"), `Row ${index} has no name; it is shown as "\u2014".`);
2558
- const raw = formatCategory(given, locale);
2559
- const count = (seen.get(raw) ?? 0) + 1;
2560
- seen.set(raw, count);
2561
- if (count > 1) warnValue(chart, accessorName(nameKey, "name"), `The name "${raw}" repeats; row ${index} is shown as "${raw} (${count})".`);
2562
- sectors.push({ index, datum, name: count > 1 ? `${raw} (${count})` : raw, value });
2563
- });
2564
- return sectors;
2565
- }
2566
- var SECTORS_PER_CHART = 60;
2567
- function checkSectors(chart, property, count) {
2568
- if (process.env.NODE_ENV === "production" || count <= SECTORS_PER_CHART) return;
2569
- diagnose("SP008", chart, { property, message: `${count} sectors; the ceiling is ${SECTORS_PER_CHART}.` });
2570
- }
2571
- var RING_TONES = [1, 2, 3, 4];
2572
- function ringTone(index, count) {
2573
- const tone = RING_TONES[index % RING_TONES.length];
2574
- if (count > 1 && index === count - 1 && tone === RING_TONES[0]) return RING_TONES[2];
2575
- return tone;
2576
- }
2577
- function ringTones(values) {
2578
- const drawn = values.filter((v) => v > 0).length;
2579
- let k = 0;
2580
- return values.map((v) => v > 0 ? ringTone(k++, drawn) : ringTone(Math.min(k, Math.max(drawn - 1, 0)), drawn));
2581
- }
2582
- var LEGEND_ROW = 14;
2583
- function sectorLegend(area5, entries) {
2584
- const strokes = [];
2585
- const labels = [];
2586
- const fits2 = Math.max(Math.floor(area5.height / LEGEND_ROW), 1);
2587
- const shown = entries.length > fits2 ? fits2 - 1 : entries.length;
2588
- const top = area5.y + (area5.height - Math.min(entries.length, fits2) * LEGEND_ROW) / 2;
2589
- entries.slice(0, shown).forEach((entry, row) => {
2590
- const y = top + row * LEGEND_ROW;
2591
- strokes.push({ d: rectPath({ x: area5.x, y: y + 3, width: 9, height: 7 }), role: "ornament", part: "ink", tone: entry.tone });
2592
- labels.push({ x: area5.x + 14, y: y + 10, text: entry.name, kind: "tick", part: "text", anchor: "start" });
2593
- labels.push({ x: area5.x + area5.width, y: y + 10, text: entry.share, kind: "tick", part: "axis", anchor: "end" });
2594
- });
2595
- if (shown < entries.length) {
2596
- labels.push({ x: area5.x + 14, y: top + shown * LEGEND_ROW + 10, text: `+${entries.length - shown} more`, kind: "tick", part: "axis", anchor: "start" });
2597
- }
2598
- return { strokes, labels };
2599
- }
2600
-
2601
1844
  // src/charts/donut-chart/demo.ts
2602
1845
  var DONUT_CHART_DEMO = /* @__PURE__ */ Object.freeze(
2603
1846
  /* @__PURE__ */ [
@@ -2824,8 +2067,8 @@ function buildPolarBarChart(props, context) {
2824
2067
  const tip = hole + b.value / largest * reach;
2825
2068
  const d = sectorPath(frame, { inner: hole, outer: tip, start, end });
2826
2069
  if (d && tip > hole) strokes.push({ d, role: "encoding", part: "ink", tone: 2 });
2827
- const at2 = pointAt(frame, (start + end) / 2, tip);
2828
- hitAreas.push({ seriesKey: valueName, index: b.index, datum: b.datum, value: b.value, x: at2.x, y: at2.y });
2070
+ const at = pointAt(frame, (start + end) / 2, tip);
2071
+ hitAreas.push({ seriesKey: valueName, index: b.index, datum: b.datum, value: b.value, x: at.x, y: at.y });
2829
2072
  });
2830
2073
  labels.push(...rimLabels(frame, bars.map((b, k) => ({ angle: (k + 0.5) * slot, text: b.name }))));
2831
2074
  const top = bars.reduce((a, b) => b.value > a.value ? b : a);
@@ -2887,8 +2130,8 @@ function buildCoxcombChart(props, context) {
2887
2130
  const r = frame.radius * Math.sqrt(s.value / largest);
2888
2131
  const d = sectorPath(frame, { inner: 0, outer: r, start: from, end: from + slot });
2889
2132
  if (d) strokes.push({ d, role: "encoding", part: "ink", tone: tones[k] });
2890
- const at2 = pointAt(frame, from + slot / 2, r * 0.6);
2891
- hitAreas.push({ seriesKey: valueName, index: s.index, datum: s.datum, value: s.value, x: at2.x, y: at2.y });
2133
+ const at = pointAt(frame, from + slot / 2, r * 0.6);
2134
+ hitAreas.push({ seriesKey: valueName, index: s.index, datum: s.datum, value: s.value, x: at.x, y: at.y });
2892
2135
  });
2893
2136
  labels.push(...rimLabels(frame, sectors.map((s, k) => ({ angle: start + (k + 0.5) * slot, text: s.name }))));
2894
2137
  const top = sectors.reduce((a, b) => b.value > a.value ? b : a);
@@ -3045,9 +2288,9 @@ function buildScalar(family, props, context) {
3045
2288
  const drawing = family.draw(frame, value);
3046
2289
  const strokes = [...card.strokes, ...drawing.strokes];
3047
2290
  const labels = [...card.labels, ...drawing.labels];
3048
- const at2 = family.readoutAt(frame);
3049
- labels.push({ x: frame.cx, y: at2.value, text: printed, kind: "value", part: "text", anchor: "middle" });
3050
- if (caption) labels.push({ x: frame.cx, y: at2.caption, text: caption, kind: "tick", part: "axis", anchor: "middle" });
2291
+ const at = family.readoutAt(frame);
2292
+ labels.push({ x: frame.cx, y: at.value, text: printed, kind: "value", part: "text", anchor: "middle" });
2293
+ if (caption) labels.push({ x: frame.cx, y: at.caption, text: caption, kind: "tick", part: "axis", anchor: "middle" });
3051
2294
  const hitAreas = [];
3052
2295
  if (value !== void 0 && drawing.tip) {
3053
2296
  hitAreas.push({ seriesKey: "value", index: 0, datum: { value }, value, x: drawing.tip.x, y: drawing.tip.y });
@@ -3944,8 +3187,8 @@ function buildWindRose(props, context) {
3944
3187
  if (r <= 0 || r > frame.radius + 0.01) continue;
3945
3188
  strokes.push({ d: arcPath(frame, r, 0, 2 * Math.PI), role: "ornament", part: "grid" });
3946
3189
  if (r > frame.radius - RIM_LABELS) continue;
3947
- const at2 = pointAt(frame, width / 2, r);
3948
- labels.push({ x: at2.x + 2, y: at2.y - 2, text: `${formatNumber(tick, locale, { maximumFractionDigits: 0 })}%`, kind: "tick", part: "axis", anchor: "start" });
3190
+ const at = pointAt(frame, width / 2, r);
3191
+ labels.push({ x: at.x + 2, y: at.y - 2, text: `${formatNumber(tick, locale, { maximumFractionDigits: 0 })}%`, kind: "tick", part: "axis", anchor: "start" });
3949
3192
  }
3950
3193
  tally.forEach((row, k) => {
3951
3194
  const start = k * width - width / 2 + width * SECTOR_GAP;
@@ -4204,13 +3447,13 @@ var POINTER = 7;
4204
3447
  var CHAR2 = 5.2;
4205
3448
  var CAP = 7;
4206
3449
  var AIR = 1;
4207
- function fits(frame, name, at2, inner, outer, start, end) {
3450
+ function fits(frame, name, at, inner, outer, start, end) {
4208
3451
  const width = name.length * CHAR2;
4209
3452
  const corners = [
4210
- [at2.x - width / 2, at2.y + 3 - CAP],
4211
- [at2.x + width / 2, at2.y + 3 - CAP],
4212
- [at2.x - width / 2, at2.y + 3],
4213
- [at2.x + width / 2, at2.y + 3]
3453
+ [at.x - width / 2, at.y + 3 - CAP],
3454
+ [at.x + width / 2, at.y + 3 - CAP],
3455
+ [at.x - width / 2, at.y + 3],
3456
+ [at.x + width / 2, at.y + 3]
4214
3457
  ];
4215
3458
  const middle = (start + end) / 2;
4216
3459
  return corners.every(([x, y]) => {
@@ -5011,6 +4254,6 @@ function linkedMarks(model, state) {
5011
4254
  return linkedItems(model, state.key, state.value).map((index) => readout(model, toActiveItem(model.geometry.hitAreas[index])).marker.d);
5012
4255
  }
5013
4256
 
5014
- export { DASHBOARD_DEFAULTS, DEFAULTS, DISPLAY_FACE_PROBE, FORCED_PRECISION_QUERY, LINE_CHART_DEMO, LINE_CHART_DEMO_KEYS, MIN_TOUCH_TARGET, NAVIGATION_KEYS, NullInker, PATH_BYTE_BUDGET, SilverpointError, __setDiagnosticSink, activityGrid, addDays, areaChart, bandScale, barChart, breakpointOf, bubbleChart, bulletChart, candlestickChart, cellChartBox, checkTypeface, chordRing, circlePath, composedChart, coxcombChart, createPrng, dashboardView, deriveSeed, diagnose, donutChart, enforceHeightening, expandDomain, extent, fnv1a32, funnelChart, gaugeArc, heatmapChart, inCell, instanceId, isoDate, kpiCard, lineChart, linearScale, linkFrom, linkedItems, linkedMarks, max, meterChart, min, orbitChart, parseGeometry, parseIsoDate, pathBytes, perBreakpoint, polarBarChart, pyramidChart, radarChart, radialArcGroup, radialRings, rangeBandChart, readout, reduceInteraction, registerInker, resolveActive, resolveConfig, resolveDashboard, resolveInker, resolveLayout, resolveSeed, round2, roundGeometry, roundPathData, sameActive, sankeyChart, scatterChart, serializeGeometry, sparklineRows, stackedBarChart, stepActive, stepChart, streamChart, svgString, toSvgPoint, toSvgView, treemapChart, volvelleChart, waterfallChart, weekday, windRose };
4257
+ export { DASHBOARD_DEFAULTS, DISPLAY_FACE_PROBE, LINE_CHART_DEMO, LINE_CHART_DEMO_KEYS, MIN_TOUCH_TARGET, NAVIGATION_KEYS, NullInker, PATH_BYTE_BUDGET, activityGrid, areaChart, barChart, breakpointOf, bubbleChart, bulletChart, candlestickChart, cellChartBox, checkTypeface, chordRing, composedChart, coxcombChart, dashboardView, donutChart, enforceHeightening, funnelChart, gaugeArc, heatmapChart, inCell, kpiCard, lineChart, linkFrom, linkedItems, linkedMarks, meterChart, orbitChart, parseGeometry, pathBytes, perBreakpoint, polarBarChart, pyramidChart, radarChart, radialArcGroup, radialRings, rangeBandChart, readout, reduceInteraction, registerInker, resolveActive, resolveDashboard, resolveInker, resolveLayout, sameActive, sankeyChart, scatterChart, serializeGeometry, sparklineRows, stackedBarChart, stepActive, stepChart, streamChart, svgString, toSvgPoint, toSvgView, treemapChart, volvelleChart, waterfallChart, windRose };
5015
4258
  //# sourceMappingURL=index.js.map
5016
4259
  //# sourceMappingURL=index.js.map