@opendata-ai/openchart-core 8.0.0-rc.2 → 8.0.0-rc.21
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.d.ts +490 -25
- package/dist/index.js +57 -19
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -2
- package/schema/chart.schema.json +485 -35
- package/schema/table.schema.json +35 -1
- package/schema/vizspec.schema.json +1305 -120
- package/src/accessibility/__tests__/alt-text.test.ts +0 -110
- package/src/accessibility/__tests__/aria.test.ts +0 -125
- package/src/accessibility/alt-text.ts +0 -155
- package/src/accessibility/aria.ts +0 -75
- package/src/accessibility/index.ts +0 -6
- package/src/colors/__tests__/colorblind.test.ts +0 -75
- package/src/colors/__tests__/contrast.test.ts +0 -119
- package/src/colors/__tests__/palettes.test.ts +0 -74
- package/src/colors/colorblind.ts +0 -131
- package/src/colors/contrast.ts +0 -143
- package/src/colors/index.ts +0 -36
- package/src/colors/palettes.ts +0 -206
- package/src/helpers/__tests__/deep-merge.test.ts +0 -54
- package/src/helpers/__tests__/spec-builders.test.ts +0 -338
- package/src/helpers/deep-merge.ts +0 -29
- package/src/helpers/spec-builders.ts +0 -479
- package/src/index.ts +0 -215
- package/src/labels/__tests__/collision.test.ts +0 -310
- package/src/labels/collision.ts +0 -249
- package/src/labels/index.ts +0 -13
- package/src/layout/__tests__/chrome.test.ts +0 -208
- package/src/layout/__tests__/text-measure.test.ts +0 -57
- package/src/layout/chrome.ts +0 -470
- package/src/layout/index.ts +0 -18
- package/src/layout/text-measure.ts +0 -404
- package/src/layout/text-wrap.ts +0 -93
- package/src/locale/__tests__/format.test.ts +0 -606
- package/src/locale/format.ts +0 -459
- package/src/locale/index.ts +0 -21
- package/src/responsive/__tests__/breakpoints.test.ts +0 -146
- package/src/responsive/__tests__/metrics.test.ts +0 -52
- package/src/responsive/breakpoints.ts +0 -172
- package/src/responsive/index.ts +0 -53
- package/src/responsive/metrics.ts +0 -299
- package/src/schema/__tests__/generated-artifacts.test.ts +0 -42
- package/src/schema/__tests__/schema.test.ts +0 -179
- package/src/styles/__tests__/reduced-motion-selectors.test.ts +0 -28
- package/src/styles/animation.css +0 -199
- package/src/styles/base.css +0 -102
- package/src/styles/chrome.css +0 -174
- package/src/styles/dark.css +0 -44
- package/src/styles/graph.css +0 -135
- package/src/styles/index.css +0 -28
- package/src/styles/keyframes.css +0 -135
- package/src/styles/legend.css +0 -18
- package/src/styles/reduced-motion.css +0 -67
- package/src/styles/series-search.css +0 -153
- package/src/styles/sparkline.css +0 -16
- package/src/styles/table-animation.css +0 -93
- package/src/styles/table.css +0 -398
- package/src/styles/token-definitions.ts +0 -199
- package/src/styles/tokens.css +0 -156
- package/src/styles/tooltip.css +0 -126
- package/src/styles/you-draw-it.css +0 -126
- package/src/theme/__tests__/dark-mode.test.ts +0 -232
- package/src/theme/__tests__/defaults.test.ts +0 -73
- package/src/theme/__tests__/resolve.test.ts +0 -277
- package/src/theme/dark-mode.ts +0 -258
- package/src/theme/defaults.ts +0 -110
- package/src/theme/index.ts +0 -8
- package/src/theme/presets.ts +0 -64
- package/src/theme/resolve.ts +0 -312
- package/src/types/__tests__/encoding.test.ts +0 -368
- package/src/types/__tests__/gradient.test.ts +0 -95
- package/src/types/__tests__/spec.test.ts +0 -499
- package/src/types/encoding.ts +0 -280
- package/src/types/events.ts +0 -154
- package/src/types/index.ts +0 -287
- package/src/types/layout.ts +0 -1966
- package/src/types/schema-roots.ts +0 -32
- package/src/types/spec.ts +0 -2867
- package/src/types/table.ts +0 -108
- package/src/types/theme.ts +0 -209
package/src/types/encoding.ts
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-mark-type encoding validation rules.
|
|
3
|
-
*
|
|
4
|
-
* Defines which encoding channels are required vs optional for each mark type.
|
|
5
|
-
* The engine compiler uses these rules to validate specs at runtime (TypeScript
|
|
6
|
-
* catches compile-time errors; these catch runtime JSON from Claude or APIs).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { FieldType, MarkType } from './spec';
|
|
10
|
-
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Encoding rule types
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
/** Constraint on what field types are valid for an encoding channel. */
|
|
16
|
-
export interface ChannelRule {
|
|
17
|
-
/** Whether this channel is required for the chart type. */
|
|
18
|
-
required: boolean;
|
|
19
|
-
/** Allowed field types. If empty, any field type is accepted. */
|
|
20
|
-
allowedTypes: FieldType[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Encoding rules for a single chart type: which channels are required/optional. */
|
|
24
|
-
export interface EncodingRule {
|
|
25
|
-
x: ChannelRule;
|
|
26
|
-
y: ChannelRule;
|
|
27
|
-
x2?: ChannelRule;
|
|
28
|
-
y2?: ChannelRule;
|
|
29
|
-
color: ChannelRule;
|
|
30
|
-
size: ChannelRule;
|
|
31
|
-
opacity?: ChannelRule;
|
|
32
|
-
strokeDash?: ChannelRule;
|
|
33
|
-
text?: ChannelRule;
|
|
34
|
-
tooltip?: ChannelRule;
|
|
35
|
-
theta?: ChannelRule;
|
|
36
|
-
detail: ChannelRule;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
// Mark encoding rules
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
|
|
43
|
-
/** Helper to create a required channel rule. */
|
|
44
|
-
function required(...types: FieldType[]): ChannelRule {
|
|
45
|
-
return { required: true, allowedTypes: types };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Helper to create an optional channel rule. */
|
|
49
|
-
function optional(...types: FieldType[]): ChannelRule {
|
|
50
|
-
return { required: false, allowedTypes: types };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Encoding rules per mark type.
|
|
55
|
-
*
|
|
56
|
-
* Defines which channels are required and what field types they accept.
|
|
57
|
-
* The compiler uses this map to validate user specs at runtime.
|
|
58
|
-
*
|
|
59
|
-
* Key design decisions:
|
|
60
|
-
* - line/area: x is temporal/ordinal (the axis), y is quantitative (the value)
|
|
61
|
-
* - bar: covers both horizontal and vertical orientations, so both axes accept
|
|
62
|
-
* all relevant types. The engine validates the combination later (one axis
|
|
63
|
-
* must be quantitative).
|
|
64
|
-
* - arc: no x axis; y is the value (quantitative), color is the category
|
|
65
|
-
* - circle: y is the category, x is quantitative
|
|
66
|
-
* - point: both axes are quantitative
|
|
67
|
-
* - text/rule: fully optional positioning
|
|
68
|
-
* - tick/rect: both axes required, any type
|
|
69
|
-
* - beeswarm: both axes optional at the channel level; the compiler enforces
|
|
70
|
-
* the combination (exactly one quantitative value axis, the other axis an
|
|
71
|
-
* optional nominal/ordinal lane channel)
|
|
72
|
-
* - waffle: no positional axes; y is the share value (quantitative, with
|
|
73
|
-
* theta accepted as an alias like arc), color is the category
|
|
74
|
-
* - calendar: x is the daily date (temporal), color the per-day value
|
|
75
|
-
* (quantitative); no y channel (the calendar owns its own geometry)
|
|
76
|
-
* - parliament: no positional axes; theta (aliased to y) is the seat count
|
|
77
|
-
* (quantitative), color the party
|
|
78
|
-
*/
|
|
79
|
-
export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
80
|
-
bar: {
|
|
81
|
-
x: required('quantitative', 'nominal', 'ordinal', 'temporal'),
|
|
82
|
-
y: required('quantitative', 'nominal', 'ordinal'),
|
|
83
|
-
x2: optional('quantitative'),
|
|
84
|
-
y2: optional('quantitative'),
|
|
85
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
86
|
-
size: optional(),
|
|
87
|
-
opacity: optional('quantitative'),
|
|
88
|
-
tooltip: optional(),
|
|
89
|
-
detail: optional('nominal'),
|
|
90
|
-
},
|
|
91
|
-
line: {
|
|
92
|
-
x: required('temporal', 'ordinal'),
|
|
93
|
-
y: required('quantitative'),
|
|
94
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
95
|
-
size: optional(),
|
|
96
|
-
opacity: optional('quantitative'),
|
|
97
|
-
strokeDash: optional('nominal', 'ordinal'),
|
|
98
|
-
tooltip: optional(),
|
|
99
|
-
detail: optional('nominal'),
|
|
100
|
-
},
|
|
101
|
-
area: {
|
|
102
|
-
x: required('temporal', 'ordinal'),
|
|
103
|
-
y: required('quantitative'),
|
|
104
|
-
y2: optional('quantitative'),
|
|
105
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
106
|
-
size: optional(),
|
|
107
|
-
opacity: optional('quantitative'),
|
|
108
|
-
tooltip: optional(),
|
|
109
|
-
detail: optional('nominal'),
|
|
110
|
-
},
|
|
111
|
-
point: {
|
|
112
|
-
x: required('quantitative', 'temporal', 'nominal', 'ordinal'),
|
|
113
|
-
y: required('quantitative', 'temporal', 'nominal', 'ordinal'),
|
|
114
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
115
|
-
size: optional('quantitative'),
|
|
116
|
-
opacity: optional('quantitative'),
|
|
117
|
-
tooltip: optional(),
|
|
118
|
-
detail: optional('nominal'),
|
|
119
|
-
},
|
|
120
|
-
circle: {
|
|
121
|
-
x: required('quantitative'),
|
|
122
|
-
y: required('nominal', 'ordinal'),
|
|
123
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
124
|
-
size: optional('quantitative'),
|
|
125
|
-
opacity: optional('quantitative'),
|
|
126
|
-
tooltip: optional(),
|
|
127
|
-
detail: optional('nominal'),
|
|
128
|
-
},
|
|
129
|
-
lollipop: {
|
|
130
|
-
x: required('quantitative'),
|
|
131
|
-
y: required('nominal', 'ordinal'),
|
|
132
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
133
|
-
size: optional('quantitative'),
|
|
134
|
-
opacity: optional('quantitative'),
|
|
135
|
-
tooltip: optional(),
|
|
136
|
-
detail: optional('nominal'),
|
|
137
|
-
},
|
|
138
|
-
beeswarm: {
|
|
139
|
-
x: optional('quantitative', 'nominal', 'ordinal'),
|
|
140
|
-
y: optional('quantitative', 'nominal', 'ordinal'),
|
|
141
|
-
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
142
|
-
size: optional('quantitative'),
|
|
143
|
-
opacity: optional('quantitative'),
|
|
144
|
-
tooltip: optional(),
|
|
145
|
-
detail: optional('nominal'),
|
|
146
|
-
},
|
|
147
|
-
// Range: x+x2 with nominal y (horizontal) or y+y2 with nominal x (vertical).
|
|
148
|
-
// The orientation-dependent x2/y2 requirement is enforced by a dedicated
|
|
149
|
-
// check in the validator; the static table can only mark them optional.
|
|
150
|
-
range: {
|
|
151
|
-
x: required('quantitative', 'nominal', 'ordinal'),
|
|
152
|
-
y: required('quantitative', 'nominal', 'ordinal'),
|
|
153
|
-
x2: optional('quantitative'),
|
|
154
|
-
y2: optional('quantitative'),
|
|
155
|
-
color: optional('nominal', 'ordinal'),
|
|
156
|
-
size: optional(),
|
|
157
|
-
opacity: optional('quantitative'),
|
|
158
|
-
tooltip: optional(),
|
|
159
|
-
detail: optional('nominal'),
|
|
160
|
-
},
|
|
161
|
-
arc: {
|
|
162
|
-
x: optional(),
|
|
163
|
-
y: optional('quantitative'),
|
|
164
|
-
theta: required('quantitative'),
|
|
165
|
-
color: required('nominal', 'ordinal'),
|
|
166
|
-
size: optional(),
|
|
167
|
-
opacity: optional('quantitative'),
|
|
168
|
-
tooltip: optional(),
|
|
169
|
-
detail: optional('nominal'),
|
|
170
|
-
},
|
|
171
|
-
waffle: {
|
|
172
|
-
x: optional(),
|
|
173
|
-
y: required('quantitative'),
|
|
174
|
-
color: required('nominal', 'ordinal'),
|
|
175
|
-
size: optional(),
|
|
176
|
-
opacity: optional('quantitative'),
|
|
177
|
-
tooltip: optional(),
|
|
178
|
-
theta: optional('quantitative'),
|
|
179
|
-
detail: optional('nominal'),
|
|
180
|
-
},
|
|
181
|
-
// parliament: hemicycle seat chart. Like arc/waffle, no positional axes;
|
|
182
|
-
// color is the party (required), theta the seat count (aliased to y in the
|
|
183
|
-
// sugar pass). y is accepted so the theta alias resolves before the rules
|
|
184
|
-
// check runs.
|
|
185
|
-
parliament: {
|
|
186
|
-
x: optional(),
|
|
187
|
-
y: required('quantitative'),
|
|
188
|
-
color: required('nominal', 'ordinal'),
|
|
189
|
-
size: optional(),
|
|
190
|
-
opacity: optional('quantitative'),
|
|
191
|
-
tooltip: optional(),
|
|
192
|
-
theta: optional('quantitative'),
|
|
193
|
-
detail: optional('nominal'),
|
|
194
|
-
},
|
|
195
|
-
text: {
|
|
196
|
-
x: optional(),
|
|
197
|
-
y: optional(),
|
|
198
|
-
color: optional(),
|
|
199
|
-
size: optional('quantitative'),
|
|
200
|
-
opacity: optional('quantitative'),
|
|
201
|
-
text: required(),
|
|
202
|
-
tooltip: optional(),
|
|
203
|
-
detail: optional('nominal'),
|
|
204
|
-
},
|
|
205
|
-
rule: {
|
|
206
|
-
x: optional(),
|
|
207
|
-
y: optional(),
|
|
208
|
-
x2: optional(),
|
|
209
|
-
y2: optional(),
|
|
210
|
-
color: optional(),
|
|
211
|
-
size: optional(),
|
|
212
|
-
opacity: optional('quantitative'),
|
|
213
|
-
strokeDash: optional('nominal', 'ordinal'),
|
|
214
|
-
tooltip: optional(),
|
|
215
|
-
detail: optional('nominal'),
|
|
216
|
-
},
|
|
217
|
-
tick: {
|
|
218
|
-
x: required(),
|
|
219
|
-
y: required(),
|
|
220
|
-
color: optional(),
|
|
221
|
-
size: optional(),
|
|
222
|
-
opacity: optional('quantitative'),
|
|
223
|
-
tooltip: optional(),
|
|
224
|
-
detail: optional('nominal'),
|
|
225
|
-
},
|
|
226
|
-
rect: {
|
|
227
|
-
x: required(),
|
|
228
|
-
y: required(),
|
|
229
|
-
x2: optional(),
|
|
230
|
-
y2: optional(),
|
|
231
|
-
color: optional(),
|
|
232
|
-
size: optional(),
|
|
233
|
-
opacity: optional('quantitative'),
|
|
234
|
-
tooltip: optional(),
|
|
235
|
-
detail: optional('nominal'),
|
|
236
|
-
},
|
|
237
|
-
// calendar: x is the daily date (temporal), color the per-day value
|
|
238
|
-
// (quantitative). No y channel: the calendar computes its own
|
|
239
|
-
// weeks-x-weekdays geometry, so y is left optional here and the dedicated
|
|
240
|
-
// validator rejects it with a pointed message.
|
|
241
|
-
calendar: {
|
|
242
|
-
x: required('temporal'),
|
|
243
|
-
y: optional(),
|
|
244
|
-
color: required('quantitative'),
|
|
245
|
-
size: optional(),
|
|
246
|
-
opacity: optional('quantitative'),
|
|
247
|
-
tooltip: optional(),
|
|
248
|
-
detail: optional('nominal'),
|
|
249
|
-
},
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
/** @deprecated Use MARK_ENCODING_RULES instead. */
|
|
253
|
-
export const CHART_ENCODING_RULES = MARK_ENCODING_RULES;
|
|
254
|
-
|
|
255
|
-
// ---------------------------------------------------------------------------
|
|
256
|
-
// Graph encoding rules
|
|
257
|
-
// ---------------------------------------------------------------------------
|
|
258
|
-
|
|
259
|
-
/** Encoding rule for a single graph visual channel. */
|
|
260
|
-
export interface GraphChannelRule {
|
|
261
|
-
/** Whether this channel is required. */
|
|
262
|
-
required: boolean;
|
|
263
|
-
/** Allowed field types. Empty means any type. */
|
|
264
|
-
allowedTypes: FieldType[];
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Encoding rules for graph visualizations.
|
|
269
|
-
*
|
|
270
|
-
* All graph encoding channels are optional since a graph can be rendered
|
|
271
|
-
* with just nodes and edges (uniform appearance). Encoding channels add
|
|
272
|
-
* visual differentiation based on data fields.
|
|
273
|
-
*/
|
|
274
|
-
export const GRAPH_ENCODING_RULES: Record<string, GraphChannelRule> = {
|
|
275
|
-
nodeColor: { required: false, allowedTypes: ['nominal', 'ordinal'] },
|
|
276
|
-
nodeSize: { required: false, allowedTypes: ['quantitative'] },
|
|
277
|
-
edgeColor: { required: false, allowedTypes: ['nominal', 'ordinal'] },
|
|
278
|
-
edgeWidth: { required: false, allowedTypes: ['quantitative'] },
|
|
279
|
-
nodeLabel: { required: false, allowedTypes: [] },
|
|
280
|
-
};
|
package/src/types/events.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chart interaction event types.
|
|
3
|
-
*
|
|
4
|
-
* These types define the callback signatures for user interactions with
|
|
5
|
-
* chart elements: clicking marks, hovering, legend toggles, and annotation clicks.
|
|
6
|
-
*
|
|
7
|
-
* Event handlers are optional and passed through MountOptions (vanilla) or
|
|
8
|
-
* ChartProps (React). The vanilla adapter wires DOM event listeners to
|
|
9
|
-
* mark elements and constructs these typed events from the raw browser events.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type {
|
|
13
|
-
Annotation,
|
|
14
|
-
AnnotationOffset,
|
|
15
|
-
DataRow,
|
|
16
|
-
RangeAnnotation,
|
|
17
|
-
RefLineAnnotation,
|
|
18
|
-
TextAnnotation,
|
|
19
|
-
} from './spec';
|
|
20
|
-
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
// Chrome key identifiers
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
|
|
25
|
-
/** Identifies a specific chrome text element (title, subtitle, source, byline, footer). */
|
|
26
|
-
export type ChromeKey = 'title' | 'subtitle' | 'source' | 'byline' | 'footer';
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Element references (identity for selection/edit callbacks)
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Reference to an editable chart element.
|
|
34
|
-
* Carries enough info to find the element in both the spec and the DOM.
|
|
35
|
-
* The `annotation` variant uses two-tier identity: `id` (when the consumer provides one)
|
|
36
|
-
* and `index` (always available, position in the spec's annotations array).
|
|
37
|
-
*/
|
|
38
|
-
export type ElementRef =
|
|
39
|
-
| { type: 'annotation'; index: number; id?: string }
|
|
40
|
-
| { type: 'chrome'; key: ChromeKey }
|
|
41
|
-
| { type: 'series-label'; series: string }
|
|
42
|
-
| { type: 'legend' }
|
|
43
|
-
| { type: 'legend-entry'; series: string; index: number };
|
|
44
|
-
|
|
45
|
-
/** Helper constructors for ergonomic ElementRef creation. */
|
|
46
|
-
export const elementRef = {
|
|
47
|
-
annotation: (index: number, id?: string): ElementRef => ({ type: 'annotation', index, id }),
|
|
48
|
-
chrome: (key: ChromeKey): ElementRef => ({ type: 'chrome', key }),
|
|
49
|
-
seriesLabel: (series: string): ElementRef => ({ type: 'series-label', series }),
|
|
50
|
-
legend: (): ElementRef => ({ type: 'legend' }),
|
|
51
|
-
legendEntry: (series: string, index: number): ElementRef => ({
|
|
52
|
-
type: 'legend-entry',
|
|
53
|
-
series,
|
|
54
|
-
index,
|
|
55
|
-
}),
|
|
56
|
-
} as const;
|
|
57
|
-
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
// Element edit events
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Discriminated union of all element edit events.
|
|
64
|
-
* Fired by the `onEdit` callback when any editable chart element is modified.
|
|
65
|
-
* Covers repositioning (drag), deletion (Delete key), and text editing (double-click).
|
|
66
|
-
* Selection events (onSelect/onDeselect) are separate callbacks, not part of this union.
|
|
67
|
-
*
|
|
68
|
-
* For the `annotation` variant:
|
|
69
|
-
* - `annotation` is the ORIGINAL spec annotation (may have a stale or missing offset)
|
|
70
|
-
* - `offset` is the NEW accumulated position after the drag completes
|
|
71
|
-
* - To persist a drag edit back into your spec: `{ ...edit.annotation, offset: edit.offset }`
|
|
72
|
-
*/
|
|
73
|
-
export type ElementEdit =
|
|
74
|
-
| { type: 'annotation'; annotation: TextAnnotation; offset: AnnotationOffset }
|
|
75
|
-
| {
|
|
76
|
-
type: 'annotation-connector';
|
|
77
|
-
annotation: TextAnnotation;
|
|
78
|
-
endpoint: 'from' | 'to';
|
|
79
|
-
offset: AnnotationOffset;
|
|
80
|
-
}
|
|
81
|
-
| { type: 'range-label'; annotation: RangeAnnotation; labelOffset: AnnotationOffset }
|
|
82
|
-
| { type: 'refline-label'; annotation: RefLineAnnotation; labelOffset: AnnotationOffset }
|
|
83
|
-
| { type: 'chrome'; key: ChromeKey; text: string; offset: AnnotationOffset }
|
|
84
|
-
| { type: 'series-label'; series: string; offset: AnnotationOffset }
|
|
85
|
-
| { type: 'legend'; offset: AnnotationOffset }
|
|
86
|
-
| { type: 'legend-toggle'; series: string; hidden: boolean }
|
|
87
|
-
| { type: 'delete'; element: ElementRef }
|
|
88
|
-
| { type: 'text-edit'; element: ElementRef; oldText: string; newText: string };
|
|
89
|
-
|
|
90
|
-
// ---------------------------------------------------------------------------
|
|
91
|
-
// Mark events
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Event fired when a user interacts with a data mark (bar, point, line segment, etc.).
|
|
96
|
-
*
|
|
97
|
-
* Contains the underlying data row, the series it belongs to (if multi-series),
|
|
98
|
-
* the position within the chart container, and the raw browser MouseEvent.
|
|
99
|
-
*/
|
|
100
|
-
export interface MarkEvent {
|
|
101
|
-
/** The data row associated with the mark that was interacted with. */
|
|
102
|
-
datum: DataRow;
|
|
103
|
-
/** Series identifier, if the chart has multiple series (e.g. multi-line). */
|
|
104
|
-
series?: string;
|
|
105
|
-
/** Position of the interaction relative to the chart container. */
|
|
106
|
-
position: { x: number; y: number };
|
|
107
|
-
/** The raw browser MouseEvent. */
|
|
108
|
-
event: MouseEvent;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ---------------------------------------------------------------------------
|
|
112
|
-
// Chart event handler interface
|
|
113
|
-
// ---------------------------------------------------------------------------
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Event handler callbacks for chart interactions.
|
|
117
|
-
*
|
|
118
|
-
* All handlers are optional. Pass these through MountOptions (vanilla adapter)
|
|
119
|
-
* or ChartProps (React component) to receive interaction callbacks.
|
|
120
|
-
*/
|
|
121
|
-
export interface ChartEventHandlers {
|
|
122
|
-
/** Called when a data mark is clicked. */
|
|
123
|
-
onMarkClick?: (event: MarkEvent) => void;
|
|
124
|
-
/** Called when the mouse enters a data mark. */
|
|
125
|
-
onMarkHover?: (event: MarkEvent) => void;
|
|
126
|
-
/** Called when the mouse leaves a data mark. */
|
|
127
|
-
onMarkLeave?: () => void;
|
|
128
|
-
/** Called when a legend entry is toggled (clicked to show/hide a series). */
|
|
129
|
-
onLegendToggle?: (series: string, visible: boolean) => void;
|
|
130
|
-
/**
|
|
131
|
-
* Called when the series search (`seriesSearch`) changes the highlight set.
|
|
132
|
-
* Receives the full set of highlighted values after the change, including
|
|
133
|
-
* the authored `encoding.color.highlight` baseline.
|
|
134
|
-
*/
|
|
135
|
-
onHighlightChange?: (values: string[]) => void;
|
|
136
|
-
/** Called when an annotation element is clicked. */
|
|
137
|
-
onAnnotationClick?: (annotation: Annotation, event: MouseEvent) => void;
|
|
138
|
-
/** Called when a text annotation label is dragged to a new position. */
|
|
139
|
-
onAnnotationEdit?: (annotation: TextAnnotation, updatedOffset: AnnotationOffset) => void;
|
|
140
|
-
/** Unified edit callback. Fires for any spec-modifying edit (repositioning, deletion, text editing). */
|
|
141
|
-
onEdit?: (edit: ElementEdit) => void;
|
|
142
|
-
/** Fired when an element is selected via click or programmatic select(). */
|
|
143
|
-
onSelect?: (element: ElementRef) => void;
|
|
144
|
-
/** Fired when the current element is deselected (click empty, Escape, or new selection replaces old). */
|
|
145
|
-
onDeselect?: (element: ElementRef) => void;
|
|
146
|
-
/** Fired when inline text editing commits. Also flows through onEdit as a 'text-edit' event. */
|
|
147
|
-
onTextEdit?: (element: ElementRef, oldText: string, newText: string) => void;
|
|
148
|
-
/**
|
|
149
|
-
* Fired when a "you draw it" (`youDrawIt`) drawing is revealed (button click
|
|
150
|
-
* or programmatic reveal), with the reader's guess in data coordinates,
|
|
151
|
-
* ordered by x. For newsrooms aggregating reader guesses.
|
|
152
|
-
*/
|
|
153
|
-
onReveal?: (guess: Array<{ x: string | number; y: number }>) => void;
|
|
154
|
-
}
|