@dschz/solid-uplot 0.1.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.
@@ -0,0 +1,443 @@
1
+ import { P as PluginFactory, S as SolidUplotPluginBus } from '../createPluginBus-B_Gp5BCB.js';
2
+ import { C as CursorData } from '../getCursorData-2qxURGuZ.js';
3
+ import { Component, JSX } from 'solid-js';
4
+ import uPlot from 'uplot';
5
+ import { S as SeriesDatum } from '../getSeriesData-D1zBqQ9Y.js';
6
+ import 'solid-js/store';
7
+
8
+ /**
9
+ * Message structure for cursor plugin communication via the plugin bus.
10
+ */
11
+ type CursorPluginMessage = {
12
+ /**
13
+ * The ID of the plot instance that originated this cursor message.
14
+ * Used to identify which chart is the source of cursor updates.
15
+ */
16
+ readonly sourceId?: string;
17
+ /**
18
+ * State object containing cursor data for each plot instance.
19
+ * Key is the plot ID, value is the cursor data for that plot.
20
+ */
21
+ readonly state: {
22
+ [plotId: string]: CursorData | undefined;
23
+ };
24
+ };
25
+ /**
26
+ * The message bus interface for the cursor plugin.
27
+ * Defines the structure of cursor-related data shared between plugins.
28
+ */
29
+ type CursorPluginMessageBus = {
30
+ /**
31
+ * Cursor plugin message containing state and source information.
32
+ */
33
+ cursor?: CursorPluginMessage;
34
+ };
35
+ /**
36
+ * Creates a cursor plugin that tracks and shares cursor position and state across charts.
37
+ *
38
+ * This plugin enables cursor synchronization between multiple charts and provides
39
+ * cursor data to other plugins (like tooltips) via the plugin bus system.
40
+ *
41
+ * **Features:**
42
+ * - Tracks cursor position and x-series data indices
43
+ * - Transmits cursor data via plugin bus for cross-plugin synchronization
44
+ *
45
+ * **Usage:**
46
+ * ```typescript
47
+ * import { createPluginBus } from '@dschz/solid-uplot';
48
+ * import { cursor, type CursorPluginMessageBus } from '@dschz/solid-uplot/plugins';
49
+ *
50
+ * const bus = createPluginBus<CursorPluginMessageBus>();
51
+ *
52
+ * <SolidUplot
53
+ * // ... other props
54
+ * plugins={[cursor()]}
55
+ * pluginBus={bus}
56
+ * />
57
+ * ```
58
+ *
59
+ * **Plugin Bus Data:**
60
+ * The plugin populates `bus.data.cursor` with:
61
+ * - `sourceId`: ID of the chart that last updated the cursor
62
+ * - `state[plotId]`: Cursor data for each chart instance
63
+ *
64
+ * See {@link CursorPluginMessage} for the complete data structure.
65
+ *
66
+ * @returns A plugin factory function that creates the cursor plugin instance
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * // Use with other plugins that depend on cursor data
71
+ * const plugins = [
72
+ * cursor(),
73
+ * tooltip(MyTooltipComponent),
74
+ * focusSeries()
75
+ * ];
76
+ * ```
77
+ */
78
+ declare const cursor: () => PluginFactory<CursorPluginMessageBus>;
79
+
80
+ /**
81
+ * Target a series by its label.
82
+ */
83
+ type SeriesByLabel = {
84
+ /**
85
+ * The label of the series.
86
+ */
87
+ readonly label: string;
88
+ readonly index?: never;
89
+ readonly zeroIndex?: never;
90
+ };
91
+ /**
92
+ * Target a series by its uPlot index.
93
+ */
94
+ type SeriesByIndex = {
95
+ readonly label?: never;
96
+ /**
97
+ * The index of the y-series as according to uPlot.
98
+ *
99
+ * For example, if we have 3 y-series, they would have the following uPlot-based indices:
100
+ * - 1
101
+ * - 2
102
+ * - 3
103
+ *
104
+ * Note that the x-series is not included in this indexing (which starts at index 0 within uPlot).
105
+ */
106
+ readonly index: number;
107
+ readonly zeroIndex?: never;
108
+ };
109
+ /**
110
+ * Target a series by its zero-based index.
111
+ */
112
+ type SeriesByZeroIndex = {
113
+ readonly label?: never;
114
+ readonly index?: never;
115
+ /**
116
+ * The zero-based index of the series.
117
+ *
118
+ * This is the index of the y-series if we were to treat them with zero-based indexing.
119
+ *
120
+ * For example, if we have 3 y-series, they would have the following zero-based indices:
121
+ * - 0
122
+ * - 1
123
+ * - 2
124
+ *
125
+ * Note that the x-series is not included in this zero-based indexing.
126
+ */
127
+ readonly zeroIndex: number;
128
+ };
129
+ /**
130
+ * Defines how to target a specific series for focusing.
131
+ * Can target by label, uPlot index, or zero-based index.
132
+ */
133
+ type SeriesFocusTarget = SeriesByLabel | SeriesByIndex | SeriesByZeroIndex;
134
+ /**
135
+ * Message structure for focus series plugin communication via the plugin bus.
136
+ */
137
+ type FocusSeriesPluginMessage = {
138
+ /**
139
+ * The id of the source that triggered the focus series event.
140
+ */
141
+ readonly sourceId: string;
142
+ /**
143
+ * The list of target series to focus.
144
+ */
145
+ readonly targets: SeriesFocusTarget[];
146
+ };
147
+ /**
148
+ * The message bus interface for the focus series plugin.
149
+ * Defines the structure of focus series data shared between plugins.
150
+ */
151
+ type FocusSeriesPluginMessageBus = {
152
+ /**
153
+ * Focus series plugin message containing source and target information.
154
+ */
155
+ focusSeries?: FocusSeriesPluginMessage;
156
+ };
157
+ /**
158
+ * Configuration options for the focus series plugin.
159
+ */
160
+ type FocusSeriesPluginOptions = {
161
+ /**
162
+ * The vertical distance in pixels required to focus a series.
163
+ * If the cursor's Y position is within this threshold of a Y value, that series is considered focused.
164
+ *
165
+ * @default 5
166
+ */
167
+ readonly pxThreshold?: number;
168
+ /**
169
+ * The alpha value to set for unfocused series.
170
+ *
171
+ * @default 0.1
172
+ */
173
+ readonly unfocusedAlpha?: number;
174
+ /**
175
+ * The alpha value to set for focused series.
176
+ *
177
+ * @default 1
178
+ */
179
+ readonly focusedAlpha?: number;
180
+ /**
181
+ * Whether to rebuild the paths of the series during redraw.
182
+ * When set to `false`, uPlot will use the cached Path2D objects for the series.
183
+ *
184
+ * @default false
185
+ */
186
+ readonly rebuildPaths?: boolean;
187
+ };
188
+ /**
189
+ * Creates a focus series plugin that visually highlights series based on cursor proximity.
190
+ *
191
+ * This plugin dims non-focused series and highlights the series closest to the cursor position.
192
+ * When the cursor is within the specified pixel threshold of a series data point, that series
193
+ * becomes focused while others are dimmed.
194
+ *
195
+ * **Features:**
196
+ * - Automatic series focusing based on cursor proximity
197
+ * - Configurable pixel threshold for focus detection
198
+ * - Cross-chart focus synchronization via plugin bus
199
+ * - Smooth visual feedback with alpha transparency
200
+ * - Support for targeting series by label, index, or zero-based index
201
+ *
202
+ * **Requirements:**
203
+ * - Requires the cursor plugin to be active for position tracking
204
+ * - Needs a plugin bus for cursor data communication
205
+ *
206
+ * **Usage:**
207
+ * ```typescript
208
+ * import { createPluginBus } from '@dschz/solid-uplot';
209
+ * import { cursor, focusSeries, type CursorPluginMessageBus, type FocusSeriesPluginMessageBus } from '@dschz/solid-uplot/plugins';
210
+ *
211
+ * const bus = createPluginBus<CursorPluginMessageBus & FocusSeriesPluginMessageBus>();
212
+ *
213
+ * <SolidUplot
214
+ * // ... other props
215
+ * plugins={[cursor(), focusSeries({ pxThreshold: 10 })]}
216
+ * pluginBus={bus}
217
+ * />
218
+ * ```
219
+ *
220
+ * @param options - Configuration options for focus behavior
221
+ * @returns A plugin factory function that creates the focus series plugin instance
222
+ */
223
+ declare const focusSeries: (options?: FocusSeriesPluginOptions) => PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
224
+
225
+ /**
226
+ * Simple legend placement options - only top corners to avoid axis conflicts
227
+ */
228
+ type LegendPlacement = "top-left" | "top-right";
229
+ type LegendProps = {
230
+ readonly u: uPlot;
231
+ readonly seriesData: SeriesDatum[];
232
+ readonly bus: SolidUplotPluginBus<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
233
+ };
234
+ type LegendRootProps = {
235
+ /**
236
+ * HTML id attribute for the legend root
237
+ * @default "solid-uplot-legend-root"
238
+ */
239
+ readonly id?: string;
240
+ /**
241
+ * CSS class name for the legend root
242
+ */
243
+ readonly class?: string;
244
+ /**
245
+ * Inline styles for the legend root
246
+ */
247
+ readonly style?: JSX.CSSProperties;
248
+ /**
249
+ * The z-index of the legend root
250
+ * @default 10
251
+ */
252
+ readonly zIndex?: number;
253
+ };
254
+ type LegendConfigOptions = {
255
+ /**
256
+ * Legend placement within the chart area
257
+ * @default "top-left"
258
+ */
259
+ readonly placement?: LegendPlacement;
260
+ /**
261
+ * Pixel offset from the chart edges
262
+ * @default 8
263
+ */
264
+ readonly pxOffset?: number;
265
+ };
266
+ type LegendPluginOptions = LegendRootProps & LegendConfigOptions;
267
+ /**
268
+ * Creates a simple, opinionated legend plugin that displays custom legend content
269
+ * overlaid on the chart's drawing area.
270
+ *
271
+ * **Design Philosophy:**
272
+ * - Opinionated positioning: only top-left or top-right corners
273
+ * - Size-constrained: legend cannot exceed chart drawing area dimensions
274
+ * - Layout-agnostic: user controls internal layout and styling
275
+ * - Non-interfering: designed to work harmoniously with chart interactions
276
+ *
277
+ * **Features:**
278
+ * - Positioned within u.over element (chart drawing area)
279
+ * - Automatic size constraints to prevent overflow
280
+ * - Scroll handling for overflowing content
281
+ * - Plugin bus integration for reactive updates
282
+ *
283
+ * @param Component - SolidJS component to render as the legend content
284
+ * @param options - Configuration options for legend behavior and styling
285
+ * @returns A plugin factory function that creates the legend plugin instance
286
+ */
287
+ declare const legend: (Component: Component<LegendProps>, options?: LegendPluginOptions) => PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
288
+
289
+ /**
290
+ * Defines the preferred placement of the tooltip relative to the cursor position.
291
+ */
292
+ type TooltipCursorPlacement = "top-left" | "top-right" | "bottom-left" | "bottom-right";
293
+ /**
294
+ * Props passed to the custom tooltip SolidJS component.
295
+ *
296
+ * The tooltip plugin automatically provides these props to your custom component,
297
+ * ensuring it always receives the latest cursor data from the cursor plugin via
298
+ * the plugin bus system. This creates a reactive data flow where cursor movements
299
+ * immediately trigger tooltip updates with fresh position and data information.
300
+ */
301
+ type TooltipProps = {
302
+ /** The uPlot instance for accessing chart configuration and data */
303
+ readonly u: uPlot;
304
+ /**
305
+ * Current cursor data including position and data index, automatically updated
306
+ * by the cursor plugin and passed via the plugin bus system
307
+ */
308
+ readonly cursor: CursorData;
309
+ /** Array of series metadata for all series in the chart */
310
+ readonly seriesData: SeriesDatum[];
311
+ /**
312
+ * Optional focus series data from the focusSeries plugin.
313
+ *
314
+ * This is automatically updated by the focusSeries plugin and passed via the plugin bus system.
315
+ * You can use this to determine if a series is focused and apply different styling for content
316
+ * in your tooltip component.
317
+ */
318
+ readonly focusedSeries?: FocusSeriesPluginMessage;
319
+ };
320
+ /**
321
+ * Container styling and accessibility props for the tooltip wrapper.
322
+ */
323
+ type TooltipRootProps = {
324
+ /**
325
+ * HTML id attribute for the tooltip root
326
+ *
327
+ * @default "solid-uplot-tooltip-root"
328
+ */
329
+ readonly id?: string;
330
+ /**
331
+ * CSS class name for the tooltip root
332
+ *
333
+ * @default undefined
334
+ */
335
+ readonly class?: string;
336
+ /**
337
+ * Inline styles for the tooltip root
338
+ *
339
+ * @default {}
340
+ */
341
+ readonly style?: JSX.CSSProperties;
342
+ /**
343
+ * The z-index of the tooltip root
344
+ * @default 20
345
+ */
346
+ readonly zIndex?: number;
347
+ };
348
+ /**
349
+ * Configuration options for tooltip behavior.
350
+ */
351
+ type TooltipConfigOptions = {
352
+ /**
353
+ * Preferred corner of the tooltip (relative to the cursor)
354
+ * @default "top-left"
355
+ */
356
+ readonly placement?: TooltipCursorPlacement;
357
+ };
358
+ /**
359
+ * Combined options for the tooltip plugin including container props and behavior config.
360
+ */
361
+ type TooltipPluginOptions = TooltipRootProps & TooltipConfigOptions;
362
+ /**
363
+ * Creates a tooltip plugin that displays custom content when hovering over charts.
364
+ *
365
+ * This plugin renders a custom SolidJS component as a tooltip that follows the cursor
366
+ * and displays contextual information about the data point being hovered.
367
+ *
368
+ * **Features:**
369
+ * - Custom SolidJS component rendering
370
+ * - Automatic positioning with edge detection and flipping
371
+ * - Scroll-aware positioning that works with page scrolling
372
+ * - Configurable placement preferences
373
+ * - Accessible tooltip with proper ARIA attributes
374
+ * - Automatic cleanup and memory management
375
+ *
376
+ * **Requirements:**
377
+ * - Requires the cursor plugin to be active for position tracking
378
+ * - Needs a plugin bus for cursor data communication
379
+ *
380
+ * **Usage:**
381
+ * ```typescript
382
+ * import { createPluginBus } from '@dschz/solid-uplot';
383
+ * import { cursor, tooltip, type CursorPluginMessageBus, type TooltipProps } from '@dschz/solid-uplot/plugins';
384
+ * import type { Component } from 'solid-js';
385
+ *
386
+ * const bus = createPluginBus<CursorPluginMessageBus>();
387
+ *
388
+ * // Custom tooltip component MUST accept TooltipProps
389
+ * const MyTooltip: Component<TooltipProps> = (props) => {
390
+ * const xDate = () => new Date(props.cursor.xValue * 1000).toLocaleDateString();
391
+ *
392
+ * return (
393
+ * <div style={{
394
+ * background: "white", border: "1px solid #ccc", padding: "8px",
395
+ * "border-radius": "4px", "box-shadow": "0 2px 4px rgba(0,0,0,0.1)"
396
+ * }}>
397
+ * <div style={{ "font-weight": "bold", "margin-bottom": "8px" }}>
398
+ * {xDate()}
399
+ * </div>
400
+ * <For each={props.seriesData}>
401
+ * {(series) => {
402
+ * // Fetch data value using series index and cursor position
403
+ * const value = () => props.u.data[series.seriesIdx]?.[props.cursor.idx];
404
+ *
405
+ * return (
406
+ * <Show when={series.visible}>
407
+ * <div style={{ display: "flex", "align-items": "center", "margin-bottom": "4px" }}>
408
+ * <div style={{
409
+ * width: "10px", height: "10px", "border-radius": "50%",
410
+ * "background-color": series.stroke, "margin-right": "6px"
411
+ * }} />
412
+ * <span style={{ color: series.stroke }}>
413
+ * {series.label}: {value()?.toFixed(2)}
414
+ * </span>
415
+ * </div>
416
+ * </Show>
417
+ * );
418
+ * }}
419
+ * </For>
420
+ * </div>
421
+ * );
422
+ * };
423
+ *
424
+ * <SolidUplot
425
+ * // ... other props
426
+ * plugins={[cursor(), tooltip(MyTooltip, { placement: "top-right" })]}
427
+ * pluginBus={bus}
428
+ * />
429
+ * ```
430
+ *
431
+ * **Custom Tooltip Component Requirements:**
432
+ * - Must accept `TooltipProps` as props type (exported from '@dschz/solid-uplot/plugins')
433
+ * - Must be a valid SolidJS Component
434
+ * - Receives: `u` (uPlot instance), `cursor` (position/data), `seriesData` (series metadata)
435
+ * - Use `props.u.data[series.seriesIdx][props.cursor.idx]` to fetch data values
436
+ *
437
+ * @param Component - SolidJS component to render as the tooltip content
438
+ * @param options - Configuration options for tooltip behavior and styling
439
+ * @returns A plugin factory function that creates the tooltip plugin instance
440
+ */
441
+ declare const tooltip: (Component: Component<TooltipProps>, options?: TooltipPluginOptions) => PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
442
+
443
+ export { type CursorPluginMessage, type CursorPluginMessageBus, type FocusSeriesPluginMessage, type FocusSeriesPluginMessageBus, type LegendProps, type TooltipProps, cursor, focusSeries, legend, tooltip };