@opendata-ai/openchart-core 7.10.0 → 8.0.0-rc.1
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 +1154 -119
- package/dist/index.js +530 -41
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2 -1
- package/dist/styles.css.map +1 -0
- package/package.json +9 -3
- package/schema/chart.schema.json +8957 -0
- package/schema/table.schema.json +861 -0
- package/schema/vizspec.schema.json +17694 -0
- package/src/accessibility/alt-text.ts +39 -1
- package/src/accessibility/aria.ts +4 -2
- package/src/colors/__tests__/colorblind.test.ts +12 -0
- package/src/colors/colorblind.ts +11 -2
- package/src/colors/contrast.ts +11 -0
- package/src/colors/index.ts +9 -1
- package/src/colors/palettes.ts +47 -0
- package/src/helpers/__tests__/deep-merge.test.ts +54 -0
- package/src/helpers/__tests__/spec-builders.test.ts +3 -3
- package/src/helpers/deep-merge.ts +29 -0
- package/src/helpers/spec-builders.ts +7 -7
- package/src/index.ts +29 -1
- package/src/labels/collision.ts +1 -0
- package/src/layout/chrome.ts +24 -0
- package/src/layout/index.ts +1 -1
- package/src/locale/__tests__/format.test.ts +347 -11
- package/src/locale/format.ts +243 -18
- package/src/locale/index.ts +10 -1
- package/src/responsive/index.ts +2 -0
- package/src/responsive/metrics.ts +74 -9
- package/src/schema/__tests__/generated-artifacts.test.ts +42 -0
- package/src/schema/__tests__/schema.test.ts +179 -0
- package/src/styles/__tests__/reduced-motion-selectors.test.ts +28 -0
- package/src/styles/animation.css +197 -168
- package/src/styles/base.css +89 -62
- package/src/styles/chrome.css +173 -179
- package/src/styles/dark.css +38 -35
- package/src/styles/graph.css +116 -111
- package/src/styles/index.css +5 -0
- package/src/styles/keyframes.css +115 -100
- package/src/styles/legend.css +14 -12
- package/src/styles/reduced-motion.css +61 -40
- package/src/styles/series-search.css +153 -0
- package/src/styles/sparkline.css +14 -12
- package/src/styles/table-animation.css +82 -80
- package/src/styles/table.css +314 -302
- package/src/styles/token-definitions.ts +199 -0
- package/src/styles/tokens.css +132 -128
- package/src/styles/tooltip.css +109 -115
- package/src/styles/you-draw-it.css +126 -0
- package/src/types/__tests__/encoding.test.ts +86 -17
- package/src/types/__tests__/spec.test.ts +16 -12
- package/src/types/encoding.ts +69 -25
- package/src/types/events.ts +12 -0
- package/src/types/index.ts +39 -3
- package/src/types/layout.ts +414 -8
- package/src/types/schema-roots.ts +32 -0
- package/src/types/spec.ts +643 -84
- package/src/types/table.ts +3 -2
package/src/types/encoding.ts
CHANGED
|
@@ -28,15 +28,11 @@ export interface EncodingRule {
|
|
|
28
28
|
y2?: ChannelRule;
|
|
29
29
|
color: ChannelRule;
|
|
30
30
|
size: ChannelRule;
|
|
31
|
-
shape?: ChannelRule;
|
|
32
31
|
opacity?: ChannelRule;
|
|
33
32
|
strokeDash?: ChannelRule;
|
|
34
33
|
text?: ChannelRule;
|
|
35
34
|
tooltip?: ChannelRule;
|
|
36
|
-
href?: ChannelRule;
|
|
37
|
-
order?: ChannelRule;
|
|
38
35
|
theta?: ChannelRule;
|
|
39
|
-
radius?: ChannelRule;
|
|
40
36
|
detail: ChannelRule;
|
|
41
37
|
}
|
|
42
38
|
|
|
@@ -70,6 +66,15 @@ function optional(...types: FieldType[]): ChannelRule {
|
|
|
70
66
|
* - point: both axes are quantitative
|
|
71
67
|
* - text/rule: fully optional positioning
|
|
72
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
|
|
73
78
|
*/
|
|
74
79
|
export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
75
80
|
bar: {
|
|
@@ -81,8 +86,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
81
86
|
size: optional(),
|
|
82
87
|
opacity: optional('quantitative'),
|
|
83
88
|
tooltip: optional(),
|
|
84
|
-
href: optional(),
|
|
85
|
-
order: optional('quantitative', 'ordinal'),
|
|
86
89
|
detail: optional('nominal'),
|
|
87
90
|
},
|
|
88
91
|
line: {
|
|
@@ -93,8 +96,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
93
96
|
opacity: optional('quantitative'),
|
|
94
97
|
strokeDash: optional('nominal', 'ordinal'),
|
|
95
98
|
tooltip: optional(),
|
|
96
|
-
href: optional(),
|
|
97
|
-
order: optional('quantitative', 'ordinal'),
|
|
98
99
|
detail: optional('nominal'),
|
|
99
100
|
},
|
|
100
101
|
area: {
|
|
@@ -105,8 +106,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
105
106
|
size: optional(),
|
|
106
107
|
opacity: optional('quantitative'),
|
|
107
108
|
tooltip: optional(),
|
|
108
|
-
href: optional(),
|
|
109
|
-
order: optional('quantitative', 'ordinal'),
|
|
110
109
|
detail: optional('nominal'),
|
|
111
110
|
},
|
|
112
111
|
point: {
|
|
@@ -114,11 +113,8 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
114
113
|
y: required('quantitative', 'temporal', 'nominal', 'ordinal'),
|
|
115
114
|
color: optional('nominal', 'ordinal', 'quantitative'),
|
|
116
115
|
size: optional('quantitative'),
|
|
117
|
-
shape: optional('nominal', 'ordinal'),
|
|
118
116
|
opacity: optional('quantitative'),
|
|
119
117
|
tooltip: optional(),
|
|
120
|
-
href: optional(),
|
|
121
|
-
order: optional('quantitative', 'ordinal'),
|
|
122
118
|
detail: optional('nominal'),
|
|
123
119
|
},
|
|
124
120
|
circle: {
|
|
@@ -128,8 +124,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
128
124
|
size: optional('quantitative'),
|
|
129
125
|
opacity: optional('quantitative'),
|
|
130
126
|
tooltip: optional(),
|
|
131
|
-
href: optional(),
|
|
132
|
-
order: optional('quantitative', 'ordinal'),
|
|
133
127
|
detail: optional('nominal'),
|
|
134
128
|
},
|
|
135
129
|
lollipop: {
|
|
@@ -139,21 +133,63 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
139
133
|
size: optional('quantitative'),
|
|
140
134
|
opacity: optional('quantitative'),
|
|
141
135
|
tooltip: optional(),
|
|
142
|
-
|
|
143
|
-
|
|
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(),
|
|
144
159
|
detail: optional('nominal'),
|
|
145
160
|
},
|
|
146
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: {
|
|
147
186
|
x: optional(),
|
|
148
187
|
y: required('quantitative'),
|
|
149
188
|
color: required('nominal', 'ordinal'),
|
|
150
189
|
size: optional(),
|
|
151
190
|
opacity: optional('quantitative'),
|
|
152
191
|
tooltip: optional(),
|
|
153
|
-
href: optional(),
|
|
154
|
-
order: optional('quantitative', 'ordinal'),
|
|
155
192
|
theta: optional('quantitative'),
|
|
156
|
-
radius: optional('quantitative'),
|
|
157
193
|
detail: optional('nominal'),
|
|
158
194
|
},
|
|
159
195
|
text: {
|
|
@@ -164,7 +200,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
164
200
|
opacity: optional('quantitative'),
|
|
165
201
|
text: required(),
|
|
166
202
|
tooltip: optional(),
|
|
167
|
-
href: optional(),
|
|
168
203
|
detail: optional('nominal'),
|
|
169
204
|
},
|
|
170
205
|
rule: {
|
|
@@ -177,7 +212,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
177
212
|
opacity: optional('quantitative'),
|
|
178
213
|
strokeDash: optional('nominal', 'ordinal'),
|
|
179
214
|
tooltip: optional(),
|
|
180
|
-
href: optional(),
|
|
181
215
|
detail: optional('nominal'),
|
|
182
216
|
},
|
|
183
217
|
tick: {
|
|
@@ -187,7 +221,6 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
187
221
|
size: optional(),
|
|
188
222
|
opacity: optional('quantitative'),
|
|
189
223
|
tooltip: optional(),
|
|
190
|
-
href: optional(),
|
|
191
224
|
detail: optional('nominal'),
|
|
192
225
|
},
|
|
193
226
|
rect: {
|
|
@@ -199,8 +232,19 @@ export const MARK_ENCODING_RULES: Record<MarkType, EncodingRule> = {
|
|
|
199
232
|
size: optional(),
|
|
200
233
|
opacity: optional('quantitative'),
|
|
201
234
|
tooltip: optional(),
|
|
202
|
-
|
|
203
|
-
|
|
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(),
|
|
204
248
|
detail: optional('nominal'),
|
|
205
249
|
},
|
|
206
250
|
};
|
package/src/types/events.ts
CHANGED
|
@@ -127,6 +127,12 @@ export interface ChartEventHandlers {
|
|
|
127
127
|
onMarkLeave?: () => void;
|
|
128
128
|
/** Called when a legend entry is toggled (clicked to show/hide a series). */
|
|
129
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;
|
|
130
136
|
/** Called when an annotation element is clicked. */
|
|
131
137
|
onAnnotationClick?: (annotation: Annotation, event: MouseEvent) => void;
|
|
132
138
|
/** Called when a text annotation label is dragged to a new position. */
|
|
@@ -139,4 +145,10 @@ export interface ChartEventHandlers {
|
|
|
139
145
|
onDeselect?: (element: ElementRef) => void;
|
|
140
146
|
/** Fired when inline text editing commits. Also flows through onEdit as a 'text-edit' event. */
|
|
141
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;
|
|
142
154
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -12,7 +12,6 @@ export type {
|
|
|
12
12
|
GraphChannelRule,
|
|
13
13
|
} from './encoding';
|
|
14
14
|
export {
|
|
15
|
-
CHART_ENCODING_RULES,
|
|
16
15
|
GRAPH_ENCODING_RULES,
|
|
17
16
|
MARK_ENCODING_RULES,
|
|
18
17
|
} from './encoding';
|
|
@@ -43,10 +42,15 @@ export type {
|
|
|
43
42
|
ChartLayout,
|
|
44
43
|
CompileOptions,
|
|
45
44
|
CompileTableOptions,
|
|
45
|
+
CompileWarning,
|
|
46
|
+
ContinuousLegendBin,
|
|
47
|
+
ContinuousLegendLayout,
|
|
48
|
+
ContinuousLegendTick,
|
|
46
49
|
EndpointLabelEntry,
|
|
47
50
|
EndpointLabelsLayout,
|
|
48
51
|
FacetLayout,
|
|
49
52
|
FacetPanelLayout,
|
|
53
|
+
FillPatternType,
|
|
50
54
|
FlagTableCell,
|
|
51
55
|
GradientColorStop,
|
|
52
56
|
GradientLegendLayout,
|
|
@@ -56,10 +60,15 @@ export type {
|
|
|
56
60
|
Gridline,
|
|
57
61
|
HeatmapTableCell,
|
|
58
62
|
ImageTableCell,
|
|
63
|
+
LegendChannel,
|
|
59
64
|
LegendEntry,
|
|
60
65
|
LegendEntryPosition,
|
|
61
66
|
LegendLayout,
|
|
62
67
|
LineMark,
|
|
68
|
+
MapBorders,
|
|
69
|
+
MapFeatureMark,
|
|
70
|
+
MapFocusLayout,
|
|
71
|
+
MapLayout,
|
|
63
72
|
Margins,
|
|
64
73
|
Mark,
|
|
65
74
|
MarkAria,
|
|
@@ -75,13 +84,18 @@ export type {
|
|
|
75
84
|
ResolvedChrome,
|
|
76
85
|
ResolvedChromeElement,
|
|
77
86
|
ResolvedColumn,
|
|
87
|
+
ResolvedFillPattern,
|
|
78
88
|
ResolvedLabel,
|
|
79
89
|
ResolvedMetricBar,
|
|
80
90
|
ResolvedMetricCell,
|
|
91
|
+
ResolvedSeriesSearch,
|
|
92
|
+
ResolvedYouDrawIt,
|
|
81
93
|
RuleMarkLayout,
|
|
82
94
|
SankeyLayout,
|
|
83
95
|
SankeyLinkMark,
|
|
84
96
|
SankeyNodeMark,
|
|
97
|
+
SizeLegendCircle,
|
|
98
|
+
SizeLegendLayout,
|
|
85
99
|
SortState,
|
|
86
100
|
SparklineData,
|
|
87
101
|
SparklineTableCell,
|
|
@@ -97,9 +111,12 @@ export type {
|
|
|
97
111
|
TileMapTileMark,
|
|
98
112
|
TooltipContent,
|
|
99
113
|
TooltipField,
|
|
114
|
+
YouDrawItSample,
|
|
115
|
+
YouDrawItYInvert,
|
|
100
116
|
} from './layout';
|
|
101
117
|
// Spec types (user input)
|
|
102
118
|
export type {
|
|
119
|
+
A11yConfig,
|
|
103
120
|
AggregateOp,
|
|
104
121
|
AggregateTransform,
|
|
105
122
|
AnimationConfig,
|
|
@@ -117,14 +134,15 @@ export type {
|
|
|
117
134
|
BarListEncoding,
|
|
118
135
|
BarListSpec,
|
|
119
136
|
BarListSpecWithoutData,
|
|
137
|
+
BeeswarmEncoding,
|
|
120
138
|
BinParams,
|
|
121
139
|
BinTransform,
|
|
122
140
|
CalculateExpression,
|
|
123
141
|
CalculateTransform,
|
|
142
|
+
CalendarEncoding,
|
|
124
143
|
ChartSpec,
|
|
125
144
|
ChartSpecOverride,
|
|
126
145
|
ChartSpecWithoutData,
|
|
127
|
-
ChartType,
|
|
128
146
|
Chrome,
|
|
129
147
|
ChromeText,
|
|
130
148
|
ChromeTextStyle,
|
|
@@ -132,11 +150,14 @@ export type {
|
|
|
132
150
|
CircleEncoding,
|
|
133
151
|
Condition,
|
|
134
152
|
ConditionalValueDef,
|
|
153
|
+
ConnectorConfig,
|
|
154
|
+
ConnectorType,
|
|
135
155
|
DarkMode,
|
|
136
156
|
DataRow,
|
|
137
157
|
Display,
|
|
138
158
|
Encoding,
|
|
139
159
|
EncodingChannel,
|
|
160
|
+
EndpointLabelContent,
|
|
140
161
|
EndpointLabelsConfig,
|
|
141
162
|
FacetChannel,
|
|
142
163
|
FieldPredicate,
|
|
@@ -164,13 +185,21 @@ export type {
|
|
|
164
185
|
LogicalNot,
|
|
165
186
|
LogicalOr,
|
|
166
187
|
LollipopEncoding,
|
|
188
|
+
MapEncoding,
|
|
189
|
+
MapFocus,
|
|
190
|
+
MapGeo,
|
|
191
|
+
MapProjection,
|
|
192
|
+
MapSpec,
|
|
193
|
+
MapSpecWithoutData,
|
|
167
194
|
MarkDef,
|
|
168
195
|
MarkType,
|
|
169
196
|
Metric,
|
|
170
197
|
NodeOverride,
|
|
198
|
+
ParliamentEncoding,
|
|
171
199
|
PointEncoding,
|
|
172
200
|
RadialGradient,
|
|
173
201
|
RangeAnnotation,
|
|
202
|
+
RangeEncoding,
|
|
174
203
|
RectEncoding,
|
|
175
204
|
RefLineAnnotation,
|
|
176
205
|
RelativeTimeRef,
|
|
@@ -184,7 +213,9 @@ export type {
|
|
|
184
213
|
SankeySpecWithoutData,
|
|
185
214
|
ScaleConfig,
|
|
186
215
|
ScaleType,
|
|
216
|
+
SeriesSearchConfig,
|
|
187
217
|
SeriesStyle,
|
|
218
|
+
SortByField,
|
|
188
219
|
StoredVizSpec,
|
|
189
220
|
TableSpec,
|
|
190
221
|
TableSpecWithoutData,
|
|
@@ -199,15 +230,18 @@ export type {
|
|
|
199
230
|
TimeUnit,
|
|
200
231
|
TimeUnitTransform,
|
|
201
232
|
Transform,
|
|
233
|
+
ValueDef,
|
|
202
234
|
VizSpec,
|
|
235
|
+
WaffleEncoding,
|
|
203
236
|
WindowFieldDef,
|
|
204
237
|
WindowOp,
|
|
205
238
|
WindowSortField,
|
|
206
239
|
WindowTransform,
|
|
240
|
+
YouDrawItConfig,
|
|
207
241
|
} from './spec';
|
|
208
242
|
export {
|
|
209
|
-
CHART_TYPES,
|
|
210
243
|
getRepresentativeColor,
|
|
244
|
+
isAxislessMark,
|
|
211
245
|
isBarListSpec,
|
|
212
246
|
isChartSpec,
|
|
213
247
|
isConditionalDef,
|
|
@@ -215,12 +249,14 @@ export {
|
|
|
215
249
|
isGradientDef,
|
|
216
250
|
isGraphSpec,
|
|
217
251
|
isLayerSpec,
|
|
252
|
+
isMapSpec,
|
|
218
253
|
isRangeAnnotation,
|
|
219
254
|
isRefLineAnnotation,
|
|
220
255
|
isSankeySpec,
|
|
221
256
|
isTableSpec,
|
|
222
257
|
isTextAnnotation,
|
|
223
258
|
isTileMapSpec,
|
|
259
|
+
isValueDef,
|
|
224
260
|
MARK_DISPLAY_NAMES,
|
|
225
261
|
MARK_TYPES,
|
|
226
262
|
resolveMarkDef,
|