@pond-ts/charts 0.69.0 → 0.71.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/AGENTS.md +3 -1
- package/API.md +55 -56
- package/CHANGELOG.md +177 -1
- package/dist/AreaChart.d.ts +30 -22
- package/dist/AreaChart.js +37 -22
- package/dist/BandChart.d.ts +20 -1
- package/dist/BandChart.js +18 -2
- package/dist/BoxPlot.js +5 -3
- package/dist/Candlestick.d.ts +3 -3
- package/dist/Candlestick.js +5 -5
- package/dist/ChartContainer.d.ts +8 -149
- package/dist/ChartContainer.js +68 -111
- package/dist/ChartRow.d.ts +1 -12
- package/dist/ChartRow.js +15 -30
- package/dist/HeatMap.d.ts +3 -3
- package/dist/HeatMap.js +3 -3
- package/dist/Layers.js +84 -34
- package/dist/XAxis.js +1 -0
- package/dist/area.d.ts +6 -5
- package/dist/area.js +13 -6
- package/dist/axis-events.d.ts +4 -4
- package/dist/band.d.ts +10 -2
- package/dist/band.js +38 -10
- package/dist/brush.d.ts +13 -21
- package/dist/brush.js +22 -36
- package/dist/context.d.ts +81 -96
- package/dist/cursors.d.ts +81 -51
- package/dist/cursors.js +164 -127
- package/dist/decimate.d.ts +10 -1
- package/dist/decimate.js +51 -10
- package/dist/elapsed.d.ts +1 -1
- package/dist/elapsed.js +1 -1
- package/dist/format.d.ts +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/selection-fixtures.d.ts +4 -7
- package/dist/selection-fixtures.js +0 -9
- package/dist/selection-stories.d.ts +4 -6
- package/dist/selection-stories.js +4 -4
- package/dist/selectors.d.ts +2 -3
- package/dist/selectors.js +2 -3
- package/dist/tracker.d.ts +10 -28
- package/dist/tracker.js +17 -40
- package/dist/tradingAxis.fixture.d.ts +19 -0
- package/dist/tradingAxis.fixture.js +24 -0
- package/dist/tradingTimeScale.d.ts +2 -2
- package/package.json +3 -3
package/dist/ChartContainer.js
CHANGED
|
@@ -6,12 +6,12 @@ import { scaleBand } from './bandScale.js';
|
|
|
6
6
|
import { scaleElapsed } from './elapsed.js';
|
|
7
7
|
import { Sequence, TimeZone } from 'pond-ts';
|
|
8
8
|
import { ContainerContext, CursorContext, } from './context.js';
|
|
9
|
-
import {
|
|
9
|
+
import { warnOnDuplicateGestureOwners } from './cursors.js';
|
|
10
10
|
import { effectiveSelectorEntries, resolveControlledHovered, resolveControlledSelected, selectorEntryEqual, warnInertClick, } from './selectors.js';
|
|
11
11
|
import { isDev } from './dev.js';
|
|
12
12
|
import { maxSlotWidths, sum } from './slots.js';
|
|
13
13
|
import { computeLabelLanes } from './annotations.js';
|
|
14
|
-
import { resolveCursorX
|
|
14
|
+
import { resolveCursorX } from './tracker.js';
|
|
15
15
|
import { clampToBounds } from './viewport.js';
|
|
16
16
|
import { resolveAxisFormat, resolveTimeFormat, } from './format.js';
|
|
17
17
|
import { TimeAxis } from './TimeAxis.js';
|
|
@@ -198,14 +198,7 @@ function AutoSizeContainer(props) {
|
|
|
198
198
|
* pass; a chart legitimately gated this long is not painting anyway. */
|
|
199
199
|
const ZERO_SIZE_WARNING_MS = 600;
|
|
200
200
|
/** {@link ChartContainer} with its width resolved to a concrete pixel number. */
|
|
201
|
-
function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidth, bandAlign = 'start', width, height, rowGap = 0, showAxis = true, trackerPosition, onTrackerChanged, onDrawStats, panZoom = false, axisPanZoom = false, bounds, onTimeRangeChange, minDuration = 1,
|
|
202
|
-
// ── Legacy cursor props (deprecated) ───────────────────────────────────────
|
|
203
|
-
// The string surface keeps working for one minor: the resolved mode is
|
|
204
|
-
// synthesized into the equivalent mounted preset below (`<LegacyCursor>`),
|
|
205
|
-
// and a dev warning names the replacement whenever any of the props is
|
|
206
|
-
// *explicitly* set (never on the defaults). Mounted cursor components in the
|
|
207
|
-
// same scope override the shim. See docs/rfcs/interaction.md §9 / A4.4.
|
|
208
|
-
const cursor = cursorProp ?? DEFAULT_CURSOR_MODE;
|
|
201
|
+
function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidth, bandAlign = 'start', width, height, rowGap = 0, showAxis = true, trackerPosition, onTrackerChanged, onDrawStats, panZoom = false, axisPanZoom = false, bounds, onTimeRangeChange, minDuration = 1, editAnnotations = false, creating = null, onCreate, onSelectAnnotation, onHoverAnnotation, onEditAnnotation, snap = true, timeFormat, origin, theme, discontinuities, calendar, timeZone: timeZoneProp, spacing, xScale: xScaleKind = 'linear', grid = true, sessionDividers = 'none', children, }) {
|
|
209
202
|
// [PND-HEIGHT] Whether this container owns vertical layout (see the
|
|
210
203
|
// `height` prop). Carried on the frame so a `<ChartRow flex>` can tell a
|
|
211
204
|
// home that can size it from one that never will.
|
|
@@ -223,43 +216,8 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
223
216
|
const declaredCategories = useMemo(() => categoriesProp === undefined ? null : [...categoriesProp],
|
|
224
217
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- content identity
|
|
225
218
|
[categoriesKey]);
|
|
226
|
-
const cursorTime = cursorTimeProp ?? false;
|
|
227
|
-
const crosshairSnap = crosshairSnapProp ?? true;
|
|
228
|
-
const warnedLegacyRef = useRef(false);
|
|
229
|
-
useEffect(() => {
|
|
230
|
-
if (!isDev || warnedLegacyRef.current)
|
|
231
|
-
return;
|
|
232
|
-
const legacy = [];
|
|
233
|
-
if (cursorProp !== undefined)
|
|
234
|
-
legacy.push(`cursor="${cursorProp}" → mount ${presetNameFor(cursorProp)}`);
|
|
235
|
-
if (crosshairSnapProp !== undefined)
|
|
236
|
-
legacy.push('crosshairSnap → <CrosshairCursor snap>');
|
|
237
|
-
if (cursorTimeProp !== undefined)
|
|
238
|
-
legacy.push('cursorTime → showTime on the mounted cursor');
|
|
239
|
-
if (cursorFormatProp !== undefined)
|
|
240
|
-
legacy.push('cursorFormat → format on <CrosshairCursor>');
|
|
241
|
-
if (cursorSequenceProp !== undefined)
|
|
242
|
-
legacy.push('cursorSequence → <RangeCursor sequence>');
|
|
243
|
-
if (onRegionSelect !== undefined)
|
|
244
|
-
legacy.push('onRegionSelect → <RangeCursor onDragRelease> (the payload becomes ' +
|
|
245
|
-
'{ x: [lo, hi] })');
|
|
246
|
-
if (regionSelectModifier !== undefined)
|
|
247
|
-
legacy.push('regionSelectModifier → <RangeCursor dragModifier>');
|
|
248
|
-
if (legacy.length === 0)
|
|
249
|
-
return;
|
|
250
|
-
warnedLegacyRef.current = true;
|
|
251
|
-
console.warn(legacyCursorWarning(legacy));
|
|
252
|
-
}, [
|
|
253
|
-
cursorProp,
|
|
254
|
-
crosshairSnapProp,
|
|
255
|
-
cursorTimeProp,
|
|
256
|
-
cursorFormatProp,
|
|
257
|
-
cursorSequenceProp,
|
|
258
|
-
onRegionSelect,
|
|
259
|
-
regionSelectModifier,
|
|
260
|
-
]);
|
|
261
219
|
// Mounted-cursor registry ({@link ContainerFrame.registerCursor}): the
|
|
262
|
-
// presets
|
|
220
|
+
// presets register their specs here; rows and
|
|
263
221
|
// `<XAxis>` render the effective set. Same per-instance-slot discipline as
|
|
264
222
|
// the tracker sources; register is idempotent under reference equality (the
|
|
265
223
|
// presets memoize their entries on props).
|
|
@@ -282,16 +240,12 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
282
240
|
useEffect(() => {
|
|
283
241
|
warnOnDuplicateGestureOwners(cursors, warnedGestureRef);
|
|
284
242
|
}, [cursors]);
|
|
285
|
-
// The registered cursors' resolution inputs
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
// entry wins (the shim registers before the children mount, so a bare
|
|
289
|
-
// first-wins would let the legacy synthesis shadow a real mount); the
|
|
290
|
-
// legacy prop is the fallback during the window. (`sequence` resolves the
|
|
243
|
+
// The registered cursors' resolution inputs: a mounted cursor's `format`
|
|
244
|
+
// feeds the shared readout channel (the x pill, marker indicators,
|
|
245
|
+
// annotation auto-labels). First mounted wins. (`sequence` resolves the
|
|
291
246
|
// same way, below the selector registry — a `<MultiSelector sequence>`
|
|
292
247
|
// feeds the same channel.)
|
|
293
|
-
const cursorFormat = useMemo(() => cursors.find((e) =>
|
|
294
|
-
cursorFormatProp, [cursors, cursorFormatProp]);
|
|
248
|
+
const cursorFormat = useMemo(() => cursors.find((e) => e.format !== undefined)?.format, [cursors]);
|
|
295
249
|
// Which axes the gestures own. **Pan follows zoom's degrees of freedom**: an
|
|
296
250
|
// axis that can be zoomed can be panned, because a zoomed axis shows less than
|
|
297
251
|
// all of itself and the reader needs to reach the rest. `'pan'` is the one
|
|
@@ -445,7 +399,7 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
445
399
|
setSelectableKeys(next);
|
|
446
400
|
}, []);
|
|
447
401
|
// Mounted-selector registry ({@link ContainerFrame.registerSelector}):
|
|
448
|
-
// `<Selector>`
|
|
402
|
+
// `<Selector>` / `<MultiSelector>` register here, and **the
|
|
449
403
|
// registration is what enables a plot click** (interaction RFC §7.1). Same
|
|
450
404
|
// per-instance-slot discipline as the cursors/tracker sources. Mirrored to a
|
|
451
405
|
// ref because `select` / `setHovered` are `[]`-stable callbacks that must not
|
|
@@ -477,15 +431,13 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
477
431
|
}, []);
|
|
478
432
|
const selectors = useMemo(() => Array.from(selectorMap.values()), [selectorMap]);
|
|
479
433
|
const selectorsRef = useRef(selectors);
|
|
480
|
-
// The shared snap-bucket sequence,
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
//
|
|
485
|
-
const cursorSequence = useMemo(() => cursors.find((e) =>
|
|
486
|
-
selectors.find((e) => e.sequence !== undefined)?.sequence
|
|
487
|
-
cursors.find((e) => e.sequence !== undefined)?.sequence ??
|
|
488
|
-
cursorSequenceProp, [cursors, selectors, cursorSequenceProp]);
|
|
434
|
+
// The shared snap-bucket sequence, resolved like `cursorFormat` above: a
|
|
435
|
+
// mounted `<RangeCursor sequence>` wins, then a mounted `<MultiSelector
|
|
436
|
+
// sequence>` (its sweep extends bucket by bucket over the same realized
|
|
437
|
+
// buckets — one channel, so the band and the sweep can never snap
|
|
438
|
+
// differently).
|
|
439
|
+
const cursorSequence = useMemo(() => cursors.find((e) => e.sequence !== undefined)?.sequence ??
|
|
440
|
+
selectors.find((e) => e.sequence !== undefined)?.sequence, [cursors, selectors]);
|
|
489
441
|
// Annotations register here so the container can do what a mark can't in
|
|
490
442
|
// isolation: draw its guide line across other rows, order regions, serve snap
|
|
491
443
|
// targets. Keyed by per-instance slot key (same discipline as the sources).
|
|
@@ -1201,10 +1153,10 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1201
1153
|
// briefly stale until the next pointer move — rare, and the bounds check below
|
|
1202
1154
|
// hides an out-of-plot crosshair meanwhile.
|
|
1203
1155
|
const cursorX = resolveCursorX(trackerPosition, hoverX, xScale);
|
|
1204
|
-
//
|
|
1156
|
+
// `<RangeCursor>` snap buckets — the intervals the band snaps to (and a drag
|
|
1205
1157
|
// extends bucket by bucket over). Two sources, in precedence order:
|
|
1206
1158
|
//
|
|
1207
|
-
// 1. **An explicit `
|
|
1159
|
+
// 1. **An explicit `sequence`** (time axis only): realized over the view
|
|
1208
1160
|
// (a `Sequence` → `.bounded`; a `BoundedSequence` used as-is). A `Sequence`
|
|
1209
1161
|
// bucket is a *time* interval, so it's gated to a time axis — realizing time
|
|
1210
1162
|
// buckets over a value domain is meaningless (it would shade the whole plot).
|
|
@@ -1231,9 +1183,9 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1231
1183
|
// or a time-axis histogram with no explicit sequence). `binIntervals` is only
|
|
1232
1184
|
// published by a vertical bar layer, so this is a no-op for
|
|
1233
1185
|
// line/area/scatter rows. On a **category** axis the bins are the unit
|
|
1234
|
-
// slots `[i, i+1)`: the
|
|
1235
|
-
//
|
|
1236
|
-
// them so it runs slot-edge to slot-edge — the band scale's `invert`
|
|
1186
|
+
// slots `[i, i+1)`: the `<RangeCursor>` band shades the slot under the
|
|
1187
|
+
// pointer ([PND-ORDCURSOR]), and the `<MultiSelector>` sweep's band snaps
|
|
1188
|
+
// over them so it runs slot-edge to slot-edge — the band scale's `invert`
|
|
1237
1189
|
// returns slot *centres*, and a centre-to-centre band disagreed with the
|
|
1238
1190
|
// snapped-outward span the release commits (RFC A7.6's edge rule).
|
|
1239
1191
|
//
|
|
@@ -1294,6 +1246,25 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1294
1246
|
'axis; key the data on the quantity itself (a `ValueSeries`) to get a ' +
|
|
1295
1247
|
'value axis you can scale.');
|
|
1296
1248
|
}
|
|
1249
|
+
// [PND-ORDCURSOR] A `<RangeCursor onDragRelease>` on a category axis draws
|
|
1250
|
+
// its slot band but never starts a drag (`resolveRangeDrag`): the callback
|
|
1251
|
+
// would silently never fire, so say so once. Same `sources.size` guard as
|
|
1252
|
+
// above — the kind is 'time' until the layers register.
|
|
1253
|
+
const rangeDragOnCategory = resolvedKind === 'category' &&
|
|
1254
|
+
sources.size > 0 &&
|
|
1255
|
+
cursors.some((e) => e.onDragRelease !== undefined && e.enableDrag !== false);
|
|
1256
|
+
const warnedRangeDragOnCategoryRef = useRef(false);
|
|
1257
|
+
useEffect(() => {
|
|
1258
|
+
if (!isDev || !rangeDragOnCategory)
|
|
1259
|
+
return;
|
|
1260
|
+
if (warnedRangeDragOnCategoryRef.current)
|
|
1261
|
+
return;
|
|
1262
|
+
warnedRangeDragOnCategoryRef.current = true;
|
|
1263
|
+
console.warn('[pond-charts] <RangeCursor onDragRelease> is mounted on a category x ' +
|
|
1264
|
+
'axis, where the range drag is off: the band shades the slot under the ' +
|
|
1265
|
+
'pointer, but `onDragRelease` never fires. To drag across bars and get ' +
|
|
1266
|
+
'them back, mount a <MultiSelector> instead.');
|
|
1267
|
+
}, [rangeDragOnCategory]);
|
|
1297
1268
|
const xIsLog = ((s) => {
|
|
1298
1269
|
const probe = s;
|
|
1299
1270
|
return (typeof probe.base === 'function' || typeof probe.constant === 'function');
|
|
@@ -1342,15 +1313,12 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1342
1313
|
rowGap,
|
|
1343
1314
|
setHoverX,
|
|
1344
1315
|
setHoverY,
|
|
1345
|
-
crosshairSnap,
|
|
1346
1316
|
cursorBuckets,
|
|
1347
1317
|
regionAnchor,
|
|
1348
1318
|
previewSpans,
|
|
1349
1319
|
setPreviewSpans,
|
|
1350
1320
|
setRegionAnchor,
|
|
1351
|
-
onRegionSelect,
|
|
1352
1321
|
reportDrawStats,
|
|
1353
|
-
regionSelectModifier,
|
|
1354
1322
|
draggingKey,
|
|
1355
1323
|
setDragging,
|
|
1356
1324
|
selected: selectedValue,
|
|
@@ -1358,8 +1326,6 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1358
1326
|
select,
|
|
1359
1327
|
hovered: hoveredValue,
|
|
1360
1328
|
setHovered,
|
|
1361
|
-
cursor,
|
|
1362
|
-
cursorTime,
|
|
1363
1329
|
editAnnotations,
|
|
1364
1330
|
creating,
|
|
1365
1331
|
snap,
|
|
@@ -1428,15 +1394,12 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1428
1394
|
rightGutter,
|
|
1429
1395
|
rowGap,
|
|
1430
1396
|
setHoverY,
|
|
1431
|
-
crosshairSnap,
|
|
1432
1397
|
cursorBuckets,
|
|
1433
1398
|
regionAnchor,
|
|
1434
1399
|
previewSpans,
|
|
1435
1400
|
setPreviewSpans,
|
|
1436
1401
|
setRegionAnchor,
|
|
1437
|
-
onRegionSelect,
|
|
1438
1402
|
reportDrawStats,
|
|
1439
|
-
regionSelectModifier,
|
|
1440
1403
|
draggingKey,
|
|
1441
1404
|
setDragging,
|
|
1442
1405
|
selectedValue,
|
|
@@ -1444,8 +1407,6 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1444
1407
|
select,
|
|
1445
1408
|
hoveredValue,
|
|
1446
1409
|
setHovered,
|
|
1447
|
-
cursor,
|
|
1448
|
-
cursorTime,
|
|
1449
1410
|
editAnnotations,
|
|
1450
1411
|
creating,
|
|
1451
1412
|
snap,
|
|
@@ -1499,37 +1460,33 @@ function ResolvedChartContainer({ range, categories: categoriesProp, maxBandWidt
|
|
|
1499
1460
|
registerRow,
|
|
1500
1461
|
firstRowKey,
|
|
1501
1462
|
]);
|
|
1502
|
-
return (_jsx(ContainerContext.Provider, { value: frame, children:
|
|
1503
|
-
|
|
1504
|
-
//
|
|
1505
|
-
//
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
: {}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
// child's floor is its content and nothing can ever get
|
|
1531
|
-
// smaller.
|
|
1532
|
-
...(height !== undefined ? { flex: '1 1 0%', minHeight: 0 } : {}),
|
|
1533
|
-
}, children: children }), showAxis && _jsx(TimeAxis, {})] })] }) }));
|
|
1463
|
+
return (_jsx(ContainerContext.Provider, { value: frame, children: _jsx(CursorContext.Provider, { value: cursorFrame, children: _jsxs("div", { style: {
|
|
1464
|
+
width: `${width}px`,
|
|
1465
|
+
// [PND-HEIGHT] A managed height makes the outer box a flex
|
|
1466
|
+
// column: the rows block below flexes, the axis strip keeps its
|
|
1467
|
+
// natural height at the bottom, and CSS subtracts one from the
|
|
1468
|
+
// other. That subtraction being layout rather than arithmetic is
|
|
1469
|
+
// the feature — the strip's height varies with label, font size,
|
|
1470
|
+
// calendar bands and pill lanes, so no constant is correct.
|
|
1471
|
+
...(height !== undefined
|
|
1472
|
+
? {
|
|
1473
|
+
height: `${height}px`,
|
|
1474
|
+
display: 'flex',
|
|
1475
|
+
flexDirection: 'column',
|
|
1476
|
+
}
|
|
1477
|
+
: {}),
|
|
1478
|
+
}, children: [_jsx("div", { style: {
|
|
1479
|
+
display: 'flex',
|
|
1480
|
+
flexDirection: 'column',
|
|
1481
|
+
gap: `${rowGap}px`,
|
|
1482
|
+
// The positioned ancestor for overlay chrome (`<Legend>`): the
|
|
1483
|
+
// card anchors to the rows block, never the axis strip below.
|
|
1484
|
+
position: 'relative',
|
|
1485
|
+
// The rows block takes what the axis strip leaves. `minHeight:
|
|
1486
|
+
// 0` lets it shrink below its content — without it a flex
|
|
1487
|
+
// child's floor is its content and nothing can ever get
|
|
1488
|
+
// smaller.
|
|
1489
|
+
...(height !== undefined ? { flex: '1 1 0%', minHeight: 0 } : {}),
|
|
1490
|
+
}, children: children }), showAxis && _jsx(TimeAxis, {})] }) }) }));
|
|
1534
1491
|
}
|
|
1535
1492
|
//# sourceMappingURL=ChartContainer.js.map
|
package/dist/ChartRow.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
import { type CursorMode } from './context.js';
|
|
3
2
|
export interface ChartRowProps {
|
|
4
3
|
/**
|
|
5
4
|
* Row height in CSS pixels — the **fixed** sizing mode. Omit it (or pass
|
|
@@ -39,16 +38,6 @@ export interface ChartRowProps {
|
|
|
39
38
|
* hidden, so a `display: none` tab switch does not discard its scales.
|
|
40
39
|
*/
|
|
41
40
|
flex?: number;
|
|
42
|
-
/**
|
|
43
|
-
* Cursor presentation for this row, overriding the container's default
|
|
44
|
-
* ({@link ChartContainerProps.cursor}). Omit to inherit. See {@link CursorMode}.
|
|
45
|
-
*
|
|
46
|
-
* @deprecated Mount a cursor component **inside the row** instead
|
|
47
|
-
* (`<ChartRow><CrosshairCursor /> …</ChartRow>`) — the per-row override with
|
|
48
|
-
* the same nearest-mount-wins semantics. Works for one more minor; a mounted
|
|
49
|
-
* cursor in the row overrides this prop.
|
|
50
|
-
*/
|
|
51
|
-
cursor?: CursorMode;
|
|
52
41
|
children?: ReactNode;
|
|
53
42
|
}
|
|
54
43
|
/**
|
|
@@ -68,5 +57,5 @@ export interface ChartRowProps {
|
|
|
68
57
|
* Children lay out left-to-right in author order, so `<YAxis side="left"/>` goes
|
|
69
58
|
* before `<Layers/>` and `<YAxis side="right"/>` after.
|
|
70
59
|
*/
|
|
71
|
-
export declare function ChartRow({ height: heightProp, flex,
|
|
60
|
+
export declare function ChartRow({ height: heightProp, flex, children, }: ChartRowProps): import("react/jsx-runtime").JSX.Element;
|
|
72
61
|
//# sourceMappingURL=ChartRow.d.ts.map
|
package/dist/ChartRow.js
CHANGED
|
@@ -8,7 +8,6 @@ import { resolveAxisFormat } from './format.js';
|
|
|
8
8
|
import { resolveYTickCount } from './yticks.js';
|
|
9
9
|
import { placeAxisSlots } from './slots.js';
|
|
10
10
|
import { useSlotKey } from './use-slot-key.js';
|
|
11
|
-
import { LegacyCursor } from './cursors.js';
|
|
12
11
|
import { YAxis } from './YAxis.js';
|
|
13
12
|
import { ContainerContext, RowContext, } from './context.js';
|
|
14
13
|
/**
|
|
@@ -139,7 +138,7 @@ const TOP_LABEL_HEADER = 16;
|
|
|
139
138
|
* Children lay out left-to-right in author order, so `<YAxis side="left"/>` goes
|
|
140
139
|
* before `<Layers/>` and `<YAxis side="right"/>` after.
|
|
141
140
|
*/
|
|
142
|
-
export function ChartRow({ height: heightProp, flex,
|
|
141
|
+
export function ChartRow({ height: heightProp, flex, children, }) {
|
|
143
142
|
const container = useContext(ContainerContext);
|
|
144
143
|
if (container === null) {
|
|
145
144
|
throw new Error('<ChartRow> must be rendered inside a <ChartContainer>');
|
|
@@ -212,18 +211,6 @@ export function ChartRow({ height: heightProp, flex, cursor, children, }) {
|
|
|
212
211
|
const { registerRow } = container;
|
|
213
212
|
useEffect(() => registerRow(rowKey), [registerRow, rowKey]);
|
|
214
213
|
const isFirstRow = container.firstRowKey === rowKey;
|
|
215
|
-
// Deprecation notice for the legacy `cursor` prop (dev, once per row): the
|
|
216
|
-
// per-row override is now a cursor component mounted inside the row. The
|
|
217
|
-
// prop keeps working via the shim rendered below.
|
|
218
|
-
const warnedCursorRef = useRef(false);
|
|
219
|
-
useEffect(() => {
|
|
220
|
-
if (!isDev || cursor === undefined || warnedCursorRef.current)
|
|
221
|
-
return;
|
|
222
|
-
warnedCursorRef.current = true;
|
|
223
|
-
console.warn(`[pond-charts] <ChartRow cursor="${cursor}"> is deprecated (it keeps ` +
|
|
224
|
-
'working this minor, removed next) — mount the cursor component ' +
|
|
225
|
-
'inside the row instead (docs/rfcs/interaction.md §9).');
|
|
226
|
-
}, [cursor]);
|
|
227
214
|
// Keyed by a stable per-instance id (Map preserves insertion order; setting an
|
|
228
215
|
// existing key updates in place). So a re-register on a prop change keeps the
|
|
229
216
|
// entry's slot — the axis-default (first axis) and layer z-order stay stable
|
|
@@ -378,7 +365,7 @@ export function ChartRow({ height: heightProp, flex, cursor, children, }) {
|
|
|
378
365
|
const extents = needsExtents(ax)
|
|
379
366
|
? layerList
|
|
380
367
|
.filter((entry) => (entry.axisId ?? defaultAxisId) === ax.id)
|
|
381
|
-
.map((entry) => entry.layer.yExtent())
|
|
368
|
+
.map((entry) => entry.layer.yExtent(ax.scale))
|
|
382
369
|
: [];
|
|
383
370
|
const [lo, hi] = resolveYDomain(ax.min, ax.max, extents, ax.pad, ax.scale);
|
|
384
371
|
// Reserve a header band at the top when any axis draws a `'top'` title,
|
|
@@ -483,7 +470,7 @@ export function ChartRow({ height: heightProp, flex, cursor, children, }) {
|
|
|
483
470
|
// about.
|
|
484
471
|
const message = logAxisWarning(ax, layerList
|
|
485
472
|
.filter((entry) => (entry.axisId ?? defaultAxisId) === ax.id)
|
|
486
|
-
.map((entry) => entry.layer.yExtent()));
|
|
473
|
+
.map((entry) => entry.layer.yExtent(ax.scale)));
|
|
487
474
|
if (message === null)
|
|
488
475
|
warned.delete(ax.id);
|
|
489
476
|
else if (warned.get(ax.id) !== message) {
|
|
@@ -626,7 +613,6 @@ export function ChartRow({ height: heightProp, flex, cursor, children, }) {
|
|
|
626
613
|
const frame = useMemo(() => ({
|
|
627
614
|
height,
|
|
628
615
|
topInset: topHeader,
|
|
629
|
-
cursor,
|
|
630
616
|
isFirstRow,
|
|
631
617
|
rowKey,
|
|
632
618
|
yScales,
|
|
@@ -649,7 +635,6 @@ export function ChartRow({ height: heightProp, flex, cursor, children, }) {
|
|
|
649
635
|
}), [
|
|
650
636
|
height,
|
|
651
637
|
topHeader,
|
|
652
|
-
cursor,
|
|
653
638
|
isFirstRow,
|
|
654
639
|
rowKey,
|
|
655
640
|
yScales,
|
|
@@ -737,17 +722,17 @@ export function ChartRow({ height: heightProp, flex, cursor, children, }) {
|
|
|
737
722
|
"wrap the row's <Layers>, leaving each <YAxis> a direct child of the " +
|
|
738
723
|
'<ChartRow>.');
|
|
739
724
|
}, [axisInsideWrapper]);
|
|
740
|
-
return (
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
725
|
+
return (_jsx(RowContext.Provider, { value: frame, children: _jsxs("div", { ref: boxRef, style: {
|
|
726
|
+
display: 'flex',
|
|
727
|
+
flexDirection: 'row',
|
|
728
|
+
width: `${container.width}px`,
|
|
729
|
+
// Fixed rows keep their pixels; a flex row is sized by the
|
|
730
|
+
// container's column layout and reads the result back
|
|
731
|
+
// ([PND-HEIGHT]). `minHeight: 0` is what lets it actually shrink —
|
|
732
|
+
// a flex child's default min-height is its content.
|
|
733
|
+
...(isFlex
|
|
734
|
+
? { flex: `${flexGrow} 1 0%`, minHeight: 0 }
|
|
735
|
+
: { height: `${height}px` }),
|
|
736
|
+
}, children: [leftPad > 0 && _jsx("div", { style: { flex: `0 0 ${leftPad}px` } }), leftAxisEls, plotEls, rightAxisEls, rightPad > 0 && _jsx("div", { style: { flex: `0 0 ${rightPad}px` } })] }) }));
|
|
752
737
|
}
|
|
753
738
|
//# sourceMappingURL=ChartRow.js.map
|
package/dist/HeatMap.d.ts
CHANGED
|
@@ -161,9 +161,9 @@ export interface HeatMapProps<S extends SeriesSchema = SeriesSchema, VS extends
|
|
|
161
161
|
* theme, and the M5 "theme tokens optional-with-default" gate has to land
|
|
162
162
|
* first. Borrowing defers that decision instead of pre-empting it.
|
|
163
163
|
*
|
|
164
|
-
* **
|
|
165
|
-
*
|
|
166
|
-
*
|
|
164
|
+
* **Mount no cursor component with it.** A `<LineCursor>` draws the shared
|
|
165
|
+
* vertical line, and on a grid that is a *second, weaker* cursor competing
|
|
166
|
+
* with the one that already works: the cell under the pointer takes an
|
|
167
167
|
* outline, which says both axes at once. The line says only x, and a heat map's
|
|
168
168
|
* x position is rarely the question. The pointer's own crosshair shape plus the
|
|
169
169
|
* cell outline is the whole affordance.
|
package/dist/HeatMap.js
CHANGED
|
@@ -61,9 +61,9 @@ function marksOf(set) {
|
|
|
61
61
|
* theme, and the M5 "theme tokens optional-with-default" gate has to land
|
|
62
62
|
* first. Borrowing defers that decision instead of pre-empting it.
|
|
63
63
|
*
|
|
64
|
-
* **
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* **Mount no cursor component with it.** A `<LineCursor>` draws the shared
|
|
65
|
+
* vertical line, and on a grid that is a *second, weaker* cursor competing
|
|
66
|
+
* with the one that already works: the cell under the pointer takes an
|
|
67
67
|
* outline, which says both axes at once. The line says only x, and a heat map's
|
|
68
68
|
* x position is rarely the question. The pointer's own crosshair shape plus the
|
|
69
69
|
* cell outline is the whole affordance.
|