@object-ui/plugin-charts 16.1.0 → 17.2.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/CHANGELOG.md +472 -1
- package/dist/AdvancedChartImpl.d.ts +67 -13
- package/dist/ChartContainerImpl.d.ts +19 -3
- package/dist/ChartRenderer.d.ts +46 -0
- package/dist/ObjectChart.d.ts +17 -1
- package/dist/index.js +1136 -730
- package/dist/index.umd.cjs +2 -2
- package/dist/normalizeChartSchema.d.ts +207 -0
- package/package.json +9 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,476 @@
|
|
|
1
1
|
# @object-ui/plugin-charts
|
|
2
2
|
|
|
3
|
+
## 17.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4a51e77: Stop declaring 14 symbols across ten packages under names `@objectstack/spec`
|
|
8
|
+
owns (objectui#3161, objectstack#4115 batch 7 — the long tail, one or two
|
|
9
|
+
entries per package). All ten packages leave the ledger, which drops from 17
|
|
10
|
+
collisions across 11 packages to 3 across 1.
|
|
11
|
+
|
|
12
|
+
**Renamed exports** — in every case the spec exports the same name for a
|
|
13
|
+
_different_ thing, so the old name was a mis-description rather than a dialect:
|
|
14
|
+
|
|
15
|
+
| package | was | now | what the spec's same-named export is |
|
|
16
|
+
| :------------------------- | :--------------------------------- | :--------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `@object-ui/fields` | `FieldWidgetProps` | `FieldWidgetComponentProps` | the DECLARED field-widget plugin props contract (a zod object; `field.type` is the `FieldType` enum, `readonly`/`required` carry defaults) |
|
|
18
|
+
| `@object-ui/layout` | `PageHeaderProps` | `PageHeaderComponentProps` | the authored `page:header` node — a zod schema of `title`, `subtitle`, an icon NAME, `breadcrumb`, `actions: string[]` |
|
|
19
|
+
| `@object-ui/layout` | `Page` | `PageNodeRenderer` | the authored page metadata DOCUMENT (`name`, `label`, `type`, `regions`) |
|
|
20
|
+
| `@object-ui/plugin-detail` | `ObjectFieldLike` | `ObjectDefFieldLike` | the i18n duck type `translateObject` walks (`help`/`description`, plus `[key: string]: any`) |
|
|
21
|
+
| `@object-ui/plugin-grid` | `ColumnSummaryConfig` | `ColumnSummarySetting` | the OBJECT form of `ListColumn.summary` **only** — the local one was the whole union, shorthand included |
|
|
22
|
+
| `@object-ui/plugin-grid` | `isMultiValueField` | `hasMultiValueShape` | the spec's classifier, which requires a def with a `type`; the local one is called with `undefined` |
|
|
23
|
+
| `@object-ui/collaboration` | `RealtimeConfig` | `RealtimeSubscriptionConfig` | the app's realtime DECLARATION (`enabled`, `transport`, `subscriptions[]`) |
|
|
24
|
+
| `@object-ui/plugin-charts` | `ChartConfig` | `ChartContainerConfig` | the authored chart document (`type`, `xAxis`, `series`, `showLegend`, …) |
|
|
25
|
+
| `@object-ui/plugin-form` | `FormSection` / `FormSectionProps` | `FormSectionContainer` / `FormSectionContainerProps` | the authored form-section metadata (`name`, `pane`, `visibleWhen`, `fields`) |
|
|
26
|
+
| `@object-ui/providers` | `Theme` | `ThemePreference` | a whole theme DOCUMENT (`name`, `label`, `colors`, `typography`) |
|
|
27
|
+
| `@object-ui/runner` | `App` (default export) | `RunnerApp` | the authored application metadata type **and** the `App.create()` builder |
|
|
28
|
+
| `@object-ui/sdui-parser` | `ValidationResult` | `ManifestValidationResult` | plugin-manifest validation (`{ valid, errors?, warnings? }`), exported from both `kernel` and `contracts` |
|
|
29
|
+
|
|
30
|
+
`ManifestValidationResult` follows the `<what was validated>Validation<Error|Result>`
|
|
31
|
+
convention registered on objectstack#4115 (`@object-ui/core` took
|
|
32
|
+
`SchemaNodeValidationResult` in batch 4). `PageHeaderComponentProps` deliberately
|
|
33
|
+
reuses the name `@object-ui/app-shell` already chose for its own header props in
|
|
34
|
+
batch 3, so one concept does not acquire two dialect names one package apart.
|
|
35
|
+
|
|
36
|
+
**Now derived from the spec instead of hand-written:**
|
|
37
|
+
|
|
38
|
+
- `@object-ui/fields` — `isFileIdToken` is re-exported from
|
|
39
|
+
`@objectstack/spec/data`. The local copy was character-for-character identical
|
|
40
|
+
to the spec's function while its comment said it "mirrors" it, so every
|
|
41
|
+
behaviour test passed and only reference identity could tell the two apart.
|
|
42
|
+
The regex is a wire decision: widening it server-side while a copy here kept
|
|
43
|
+
the old bound would make every new id read as "not a reference", and the
|
|
44
|
+
widget would submit the legacy inline blob to a backend expecting a reference.
|
|
45
|
+
- `@object-ui/plugin-detail` — `FeedFilterMode` is re-exported from
|
|
46
|
+
`@objectstack/spec/data`, in a file that already imported the sibling
|
|
47
|
+
`FeedItemType` from the spec.
|
|
48
|
+
- `@object-ui/plugin-grid` — the eleven-member aggregation union is now the
|
|
49
|
+
spec's `ColumnSummary` enum, so the total `Record<ColumnSummaryType, string>`
|
|
50
|
+
label map turns a member the spec adds into a compile error instead of a
|
|
51
|
+
blank footer cell. `ColumnSummarySetting` is `NonNullable<ListColumn['summary']>`,
|
|
52
|
+
i.e. whatever forms the spec itself accepts. `hasMultiValueShape` delegates to
|
|
53
|
+
the spec's `isMultiValueField` rather than re-deriving it from
|
|
54
|
+
`MULTI_OPTION_TYPES` / `MULTI_CAPABLE_TYPES`.
|
|
55
|
+
- `@object-ui/providers` — `ThemePreference` is the spec's `ThemeMode` union
|
|
56
|
+
plus the one legacy `'system'` spelling this provider still honours for stored
|
|
57
|
+
preferences, read off the schema's own `_zod` carrier so the package takes no
|
|
58
|
+
zod dependency.
|
|
59
|
+
|
|
60
|
+
`@objectstack/spec` moves from `devDependencies` to `dependencies` in
|
|
61
|
+
`@object-ui/fields` (it re-exports a runtime function) and `@object-ui/providers`
|
|
62
|
+
(its public `.d.ts` now references the spec).
|
|
63
|
+
|
|
64
|
+
Scored `minor`, not `major`, per this repo's fixed-group rule — objectui's major
|
|
65
|
+
tracks `@objectstack`, so breaking changes of our own ship as minor with the
|
|
66
|
+
semantics spelled out above (see AGENTS.md §版本号策略). A `major` here would carry
|
|
67
|
+
all 39 packages of the fixed group to `18.0.0` and off objectstack's 17.x line.
|
|
68
|
+
|
|
69
|
+
### Patch Changes
|
|
70
|
+
|
|
71
|
+
- Updated dependencies [4ae0ac4]
|
|
72
|
+
- Updated dependencies [696e3c1]
|
|
73
|
+
- Updated dependencies [bca45cc]
|
|
74
|
+
- Updated dependencies [a889e31]
|
|
75
|
+
- Updated dependencies [09d30a4]
|
|
76
|
+
- Updated dependencies [4bf612c]
|
|
77
|
+
- Updated dependencies [335041c]
|
|
78
|
+
- Updated dependencies [b414983]
|
|
79
|
+
- Updated dependencies [256f8cc]
|
|
80
|
+
- Updated dependencies [d9668a7]
|
|
81
|
+
- Updated dependencies [4b470b9]
|
|
82
|
+
- Updated dependencies [cb82705]
|
|
83
|
+
- Updated dependencies [f572849]
|
|
84
|
+
- Updated dependencies [f6e8d78]
|
|
85
|
+
- Updated dependencies [ea96284]
|
|
86
|
+
- Updated dependencies [d3584c6]
|
|
87
|
+
- Updated dependencies [a8ad6c0]
|
|
88
|
+
- Updated dependencies [444457c]
|
|
89
|
+
- Updated dependencies [850033c]
|
|
90
|
+
- Updated dependencies [022e4c3]
|
|
91
|
+
- Updated dependencies [009e25d]
|
|
92
|
+
- Updated dependencies [726b89c]
|
|
93
|
+
- @object-ui/types@17.2.0
|
|
94
|
+
- @object-ui/components@17.2.0
|
|
95
|
+
- @object-ui/core@17.2.0
|
|
96
|
+
- @object-ui/react@17.2.0
|
|
97
|
+
- @object-ui/i18n@17.2.0
|
|
98
|
+
|
|
99
|
+
## 17.1.0
|
|
100
|
+
|
|
101
|
+
### Minor Changes
|
|
102
|
+
|
|
103
|
+
- f1c04b6: fix(charts): a spec `series[].type` override actually draws, and a spec-shape `series` plots at all (#2945)
|
|
104
|
+
|
|
105
|
+
#2945 listed `combo` (`plugin-charts`) as renderer-local dialect to "promote or
|
|
106
|
+
delete". Neither: the spec **already models a combo chart**, per-series, and its
|
|
107
|
+
own field comment says so —
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
// spec/src/ui/chart.zod.ts — ChartSeriesSchema
|
|
111
|
+
/** Series type override (combo charts) */
|
|
112
|
+
type: ChartTypeSchema.optional().describe('Override chart type for this series'),
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
— exactly as it models stacking with `ChartSeries.stack` rather than a
|
|
116
|
+
`stacked-bar` family. So `combo` is not a name an author should reach for; it is
|
|
117
|
+
what "the series disagree about their family" looks like from the renderer's
|
|
118
|
+
side. `effectiveChartFamily` now derives it, and `combo` stays a documented
|
|
119
|
+
renderer-local marker (internal callers pass it directly today).
|
|
120
|
+
|
|
121
|
+
Chasing that turned up two live bugs, both silent, on the path a spec author
|
|
122
|
+
takes.
|
|
123
|
+
|
|
124
|
+
**1. The per-series override was parsed, carried, and then dropped.** Only the
|
|
125
|
+
renderer's `chartType === 'combo'` branch read `series[].chartType`, so
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
{ type: 'bar', series: [{ name: 'revenue' }, { name: 'margin', type: 'line' }] }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
drew `margin` as a bar. Nothing was wrong at any layer but the last — a unit test
|
|
132
|
+
even asserted the value was carried.
|
|
133
|
+
|
|
134
|
+
**2. A spec-shape `series` rendered nothing at all.** `series` is the one binding
|
|
135
|
+
both shapes spell with the same key, so `ChartRenderer`'s blanket "internal props
|
|
136
|
+
win" rule let the author's `[{ name }]` shadow the normalized `[{ dataKey }]` and
|
|
137
|
+
reach a renderer that reads `dataKey`. Blank chart. Every other spec binding has a
|
|
138
|
+
distinct name (`xAxis` vs `xAxisKey`), which is why only this one broke — and why
|
|
139
|
+
the isolated normalization tests all passed over a dead path. The raw array is now
|
|
140
|
+
preferred only when it already speaks the internal shape, so internal callers are
|
|
141
|
+
byte-for-byte unchanged and a mixed array works too.
|
|
142
|
+
|
|
143
|
+
**Also fixed in passing:** the combo branch had an `area` arm under a `BarChart`
|
|
144
|
+
container, and Recharts renders an `<Area>` child of `BarChart` as nothing — so an
|
|
145
|
+
authored combo with an `area` series drew a blank series. The container is now
|
|
146
|
+
`ComposedChart`, which is what Recharts provides for mixed marks.
|
|
147
|
+
|
|
148
|
+
Widening only. A chart whose series all resolve to one family keeps its own
|
|
149
|
+
family, an explicit `combo` is untouched, and a family with no per-series meaning
|
|
150
|
+
(`pie`, `horizontal-bar`, …) is never widened. A derived combo binds series to the
|
|
151
|
+
left axis unless one asks for `yAxis: 'right'` — the spec's own default — so
|
|
152
|
+
widening changes the series' mark and not its scale; the legacy bar→left/line→right
|
|
153
|
+
guess is kept for an authored `combo`, where it was historically the only way to
|
|
154
|
+
reach a second axis.
|
|
155
|
+
|
|
156
|
+
Guards: `effectiveChartFamily` / `comboBaseFamily` are unit-tested over the whole
|
|
157
|
+
family matrix; DOM-level tests assert the **marks** rather than the derived family,
|
|
158
|
+
since the carry was already covered and the drawing was what broke; and
|
|
159
|
+
`spec-derived-unions.test.ts` asserts `combo` is absent from the spec's
|
|
160
|
+
`ChartTypeSchema`, so the day it is adopted upstream the derivation is named as the
|
|
161
|
+
thing to retire.
|
|
162
|
+
|
|
163
|
+
### Patch Changes
|
|
164
|
+
|
|
165
|
+
- Updated dependencies [62311b6]
|
|
166
|
+
- Updated dependencies [fc0272a]
|
|
167
|
+
- Updated dependencies [9e7349e]
|
|
168
|
+
- Updated dependencies [8864971]
|
|
169
|
+
- Updated dependencies [1cf0de7]
|
|
170
|
+
- Updated dependencies [752e18f]
|
|
171
|
+
- Updated dependencies [c785740]
|
|
172
|
+
- Updated dependencies [b41f401]
|
|
173
|
+
- Updated dependencies [19e9fa0]
|
|
174
|
+
- Updated dependencies [d61efd1]
|
|
175
|
+
- Updated dependencies [95b7214]
|
|
176
|
+
- Updated dependencies [7d9734d]
|
|
177
|
+
- Updated dependencies [6ae818e]
|
|
178
|
+
- Updated dependencies [9eb932b]
|
|
179
|
+
- Updated dependencies [746dd00]
|
|
180
|
+
- Updated dependencies [aebfa4f]
|
|
181
|
+
- Updated dependencies [38ca8be]
|
|
182
|
+
- Updated dependencies [3cb9646]
|
|
183
|
+
- Updated dependencies [68ef584]
|
|
184
|
+
- Updated dependencies [4952edf]
|
|
185
|
+
- Updated dependencies [7f0252e]
|
|
186
|
+
- Updated dependencies [c4d7b20]
|
|
187
|
+
- Updated dependencies [c769d3d]
|
|
188
|
+
- Updated dependencies [7639a61]
|
|
189
|
+
- Updated dependencies [94e63ef]
|
|
190
|
+
- Updated dependencies [c735bf7]
|
|
191
|
+
- Updated dependencies [02aef0c]
|
|
192
|
+
- Updated dependencies [6f29aa5]
|
|
193
|
+
- Updated dependencies [d21794c]
|
|
194
|
+
- Updated dependencies [c4db402]
|
|
195
|
+
- Updated dependencies [5319bf1]
|
|
196
|
+
- Updated dependencies [49e5671]
|
|
197
|
+
- Updated dependencies [9a04d25]
|
|
198
|
+
- Updated dependencies [b5b97e2]
|
|
199
|
+
- Updated dependencies [f59f2c1]
|
|
200
|
+
- Updated dependencies [07de839]
|
|
201
|
+
- Updated dependencies [2a40b5e]
|
|
202
|
+
- Updated dependencies [df613fa]
|
|
203
|
+
- Updated dependencies [4874117]
|
|
204
|
+
- Updated dependencies [ad0183a]
|
|
205
|
+
- Updated dependencies [ce08d55]
|
|
206
|
+
- Updated dependencies [eb4b740]
|
|
207
|
+
- Updated dependencies [5b084eb]
|
|
208
|
+
- Updated dependencies [aa1240a]
|
|
209
|
+
- Updated dependencies [2374a49]
|
|
210
|
+
- Updated dependencies [390c071]
|
|
211
|
+
- Updated dependencies [d10f526]
|
|
212
|
+
- Updated dependencies [2d5d594]
|
|
213
|
+
- Updated dependencies [ea7f477]
|
|
214
|
+
- Updated dependencies [379728f]
|
|
215
|
+
- Updated dependencies [7f23cd0]
|
|
216
|
+
- Updated dependencies [0ded602]
|
|
217
|
+
- Updated dependencies [24e0e0a]
|
|
218
|
+
- Updated dependencies [f8a95e5]
|
|
219
|
+
- Updated dependencies [3a6cf24]
|
|
220
|
+
- Updated dependencies [aa35561]
|
|
221
|
+
- Updated dependencies [03bd53b]
|
|
222
|
+
- Updated dependencies [3c1f321]
|
|
223
|
+
- Updated dependencies [a045a32]
|
|
224
|
+
- Updated dependencies [912496d]
|
|
225
|
+
- Updated dependencies [80edbd4]
|
|
226
|
+
- Updated dependencies [9867281]
|
|
227
|
+
- @object-ui/core@17.1.0
|
|
228
|
+
- @object-ui/components@17.1.0
|
|
229
|
+
- @object-ui/react@17.1.0
|
|
230
|
+
- @object-ui/types@17.1.0
|
|
231
|
+
- @object-ui/i18n@17.1.0
|
|
232
|
+
|
|
233
|
+
## 17.0.0
|
|
234
|
+
|
|
235
|
+
### Minor Changes
|
|
236
|
+
|
|
237
|
+
- aa88056: feat(charts): honor `ChartAxis.stepSize`, `ChartConfig.description` and `ChartConfig.height` (framework#3752)
|
|
238
|
+
|
|
239
|
+
The tail of the declared-≠-delivered sweep from framework#3729 / #2880. Three
|
|
240
|
+
`ChartConfig` props reached the renderer and did nothing:
|
|
241
|
+
|
|
242
|
+
- **`ChartAxis.stepSize`** — Recharts has no "a tick every N units" prop
|
|
243
|
+
(`tickCount` is a hint it may ignore, `interval` is for categorical axes), so
|
|
244
|
+
honoring a step means handing it the tick array outright. `ticksFor` builds it
|
|
245
|
+
from the axis's own `min`/`max` where declared and from the plotted values
|
|
246
|
+
otherwise, so a step works with or without a pinned domain. A data-derived max
|
|
247
|
+
rounds UP to the next step (otherwise the topmost bar sits above the last
|
|
248
|
+
gridline and the axis reads as truncated); an explicit `max` clamps instead,
|
|
249
|
+
since a tick outside a pinned domain would be drawn outside the plot. A step
|
|
250
|
+
that would produce more than 200 ticks is refused rather than rendered — that
|
|
251
|
+
is a wrong config, and drawing it would hang the page instead of surfacing the
|
|
252
|
+
mistake.
|
|
253
|
+
- **`ChartConfig.description`** — the accessibility description. A chart is a
|
|
254
|
+
picture to a screen reader; the container now carries `role="img"` +
|
|
255
|
+
`aria-label`. Without a description it stays an ordinary div, because
|
|
256
|
+
stamping `role="img"` on an _unlabelled_ graphic is worse than leaving one a
|
|
257
|
+
screen reader can skip.
|
|
258
|
+
- **`ChartConfig.height`** — was read only by the legacy `ChartBarRenderer`, not
|
|
259
|
+
by the advanced path that draws every real chart. Now applied to the chart
|
|
260
|
+
container as an inline style, which beats its default `h-[350px]` class.
|
|
261
|
+
|
|
262
|
+
`height` and `description` ride on the shared container props, so they apply to
|
|
263
|
+
all eight chart families rather than one branch.
|
|
264
|
+
|
|
265
|
+
- 9b53d72: feat(charts): ObjectChart honors the spec `ChartConfig` author shape (objectui#2880 / framework#3729)
|
|
266
|
+
|
|
267
|
+
`ChartConfigSchema` is the chart protocol, but the renderer only ever read a
|
|
268
|
+
Recharts-flavoured internal shape — `chartType`, `xAxisKey`, `series[].dataKey`.
|
|
269
|
+
Everything an author wrote in the SPEC shape reached the renderer and was
|
|
270
|
+
silently dropped, which is exactly what ADR-0078 forbids. framework#3725
|
|
271
|
+
documented the gap by trimming the published contract down to the props that
|
|
272
|
+
actually worked; this closes it the other way round.
|
|
273
|
+
|
|
274
|
+
**S1 — one normalization boundary.** `normalizeChartSchema` translates the
|
|
275
|
+
author shape into the internal pipeline contract in a single place, rather than
|
|
276
|
+
scattering `??` fallbacks through the render tree (framework PD #12: one
|
|
277
|
+
translation is a contract mapping, N fallbacks are a second dialect):
|
|
278
|
+
|
|
279
|
+
- `type` → `chartType`, `xAxis: { field }` → `xAxisKey`, `series: [{ name }]` →
|
|
280
|
+
`series: [{ dataKey }]`
|
|
281
|
+
- the report surface's bare-string `xAxis`/`yAxis` resolve too
|
|
282
|
+
- `yAxis: [{ field }]` alone plots, with no `series` declared
|
|
283
|
+
- **internal props win**, so `DashboardRenderer`, `ObjectView` and the dataset
|
|
284
|
+
path are byte-for-byte unaffected — there is no migration
|
|
285
|
+
|
|
286
|
+
**The `type` collision.** `ChartConfig.type` is the chart family, but on any
|
|
287
|
+
surface that flattens chart config into a props bag `type` is already the SDUI
|
|
288
|
+
envelope's component discriminator. Spreading props last let an author's
|
|
289
|
+
`type="bar"` replace `object-chart` so the block stopped resolving; stamping the
|
|
290
|
+
discriminator last ate the author's value instead. The react-page wrapper now
|
|
291
|
+
keeps both: the discriminator wins the `type` slot and the author's value is
|
|
292
|
+
preserved beside it as `specType`, which the normalizer reads back.
|
|
293
|
+
|
|
294
|
+
**S2 — axis presentation.** `ChartAxis.format` drives the tick formatter (via
|
|
295
|
+
`Intl.NumberFormat`, no new dependency), `min`/`max` pin the domain,
|
|
296
|
+
`logarithmic` swaps the scale, `title` labels the axis, and `showGridLines` is
|
|
297
|
+
honored. A second `yAxis` entry (or `position: 'right'`) turns on the secondary
|
|
298
|
+
axis that `series[].yAxis` binds to — in combo charts an explicit binding now
|
|
299
|
+
beats the family-derived bar→left/line→right guess. `showLegend` is honored,
|
|
300
|
+
and `title`/`subtitle` render above the plot instead of only titling the
|
|
301
|
+
drill-down drawer.
|
|
302
|
+
|
|
303
|
+
**S3 — `series[].stack`, `annotations`, `interaction`.** Stacking passes the
|
|
304
|
+
author's group name through as Recharts' `stackId`. Annotations render as
|
|
305
|
+
`ReferenceLine` (`type: 'line'`) / `ReferenceArea` (`type: 'region'`) with the
|
|
306
|
+
declared axis, colour, style and label. `interaction.tooltips: false` suppresses
|
|
307
|
+
the hover card and `interaction.brush: true` adds the range selector;
|
|
308
|
+
`showDataLabels` prints values on the marks. `interaction.zoom` has no Recharts
|
|
309
|
+
primitive behind it and is deliberately still unimplemented rather than faked.
|
|
310
|
+
|
|
311
|
+
### Patch Changes
|
|
312
|
+
|
|
313
|
+
- 7b35e4b: fix(dashboard,charts): resolve `{current_user_id}` in widget filters (framework #3574)
|
|
314
|
+
|
|
315
|
+
A dashboard widget filtered on `{current_user_id}` rendered `0`. The token
|
|
316
|
+
reached SQL as a literal, matched no row, and nothing was logged on the client
|
|
317
|
+
or the server — a silent zero that reads as "you have no work" rather than
|
|
318
|
+
"this filter did not resolve". The same token in a list-view filter resolved
|
|
319
|
+
correctly, so a user-scoped list and a user-scoped widget over the same data
|
|
320
|
+
disagreed.
|
|
321
|
+
|
|
322
|
+
There was no shared resolver. Three ad-hoc implementations had grown up
|
|
323
|
+
independently — `ObjectView` for list views, `ObjectDataPage` for URL filter
|
|
324
|
+
triples, `NavigationRenderer` for hrefs — and each understood only the filter
|
|
325
|
+
shape its own surface used. `ObjectView`'s opened with
|
|
326
|
+
`if (!Array.isArray(filter)) return filter`, so it could not have been reused
|
|
327
|
+
by dashboard widgets even in principle: widget filters are MongoDB-style
|
|
328
|
+
objects. Widgets therefore got no resolution at all — `DatasetWidget` called
|
|
329
|
+
`resolveDateMacros` and nothing else, which is why `{today}` worked in a widget
|
|
330
|
+
and `{current_user_id}` silently did not.
|
|
331
|
+
|
|
332
|
+
- **`@object-ui/core`** — new `utils/filter-tokens.ts` with
|
|
333
|
+
`resolveContextTokens` and `resolveFilterPlaceholders`. The latter expands
|
|
334
|
+
_every_ placeholder vocabulary in one call and is what surfaces should use;
|
|
335
|
+
resolving only some of them is the whole defect. The walk handles arrays and
|
|
336
|
+
plain objects uniformly, so one resolver covers both platform filter shapes.
|
|
337
|
+
- **`@object-ui/react`** — new `FilterScopeProvider` / `useFilterScope`. The
|
|
338
|
+
renderer packages deliberately do not depend on `@object-ui/auth`, so the
|
|
339
|
+
shell supplies the session values. This is a separate context from
|
|
340
|
+
`PredicateScopeContext`, which is the expression evaluation scope and carries
|
|
341
|
+
no organization.
|
|
342
|
+
- **`@object-ui/plugin-dashboard` / `@object-ui/plugin-charts`** — all six
|
|
343
|
+
widgets that previously resolved date macros only now resolve both
|
|
344
|
+
vocabularies: `DatasetWidget`, `ObjectMetricWidget`, `ObjectDataTable`,
|
|
345
|
+
`ObjectPivotTable`, and `ObjectChart` (dataset-bound and inline paths). The
|
|
346
|
+
chart's `compareTo` comparison filter gets the session pass too — otherwise
|
|
347
|
+
the overlay series silently ignored the owner clause the primary series
|
|
348
|
+
honoured.
|
|
349
|
+
- **`@object-ui/app-shell`** — `ObjectView`'s local `substituteFilterTokens`
|
|
350
|
+
and `ObjectDataPage`'s inline `=== '{current_user_id}'` ternary now delegate
|
|
351
|
+
to the shared resolver, so both also gain `{current_org_id}` and date macros.
|
|
352
|
+
Two of the three ad-hoc implementations are gone rather than joined by a
|
|
353
|
+
fourth.
|
|
354
|
+
|
|
355
|
+
An unresolvable token is left intact rather than dropped: leaving it yields an
|
|
356
|
+
empty result, whereas dropping the clause would _widen_ the result set and show
|
|
357
|
+
a signed-out viewer everyone's data. It is no longer silent — the resolver
|
|
358
|
+
warns, naming the token, and suggests the intended spelling for known
|
|
359
|
+
near-misses (`{current_user}`, `{user_id}`, `{organization_id}`). Authoring-time
|
|
360
|
+
enforcement lands separately as `filter-token-unknown` in `@objectstack/lint`.
|
|
361
|
+
|
|
362
|
+
- e16ed2d: fix(dashboard,charts): send widget `dateGranularity`/`sortBy`/`limit` to the query, and give funnels a real stage order (framework#3588)
|
|
363
|
+
|
|
364
|
+
`DatasetWidget` never read `widget.options`. Four keys an author writes there
|
|
365
|
+
change the query the server compiles, so a widget declaring
|
|
366
|
+
`options: { dateGranularity: 'month' }` grouped by the raw timestamp and drew
|
|
367
|
+
one bar per record, and `sortBy`/`sortOrder` produced no ordering at all.
|
|
368
|
+
|
|
369
|
+
- `DatasetWidget` lowers `options.dateGranularity`, `options.sortBy` +
|
|
370
|
+
`options.sortOrder`, and `options.limit` into the `DatasetSelection` it posts.
|
|
371
|
+
A `sortBy` naming something the widget does not project is dropped rather than
|
|
372
|
+
sent, so a stale sort key left by an edit degrades to "unordered" instead of
|
|
373
|
+
failing the widget against the server's stricter validation. These keys also
|
|
374
|
+
join the refetch signature, so editing one in the designer refetches instead
|
|
375
|
+
of re-rendering the previous grid.
|
|
376
|
+
- Funnel stages follow a **declared order**. `AdvancedChartImpl` sorted funnel
|
|
377
|
+
segments by value descending, unconditionally — which overrode any server
|
|
378
|
+
ordering and rendered a sales pipeline as a tidy narrowing shape whatever the
|
|
379
|
+
stages' real sequence, hiding the very anomaly (a bulge at Proposal) the chart
|
|
380
|
+
exists to show. It now honours a `categoryOrder`, which `DatasetWidget`
|
|
381
|
+
derives from the dimension field's picklist option order — the pipeline order
|
|
382
|
+
an author already declared on the object — or from an explicit
|
|
383
|
+
`options.stageOrder`. With no declared order the value-descending default is
|
|
384
|
+
unchanged, and a category missing from the order is kept (after the declared
|
|
385
|
+
ones), never dropped.
|
|
386
|
+
- New `@object-ui/core` helpers `buildCategoryOrder` / `buildCategoryRank`,
|
|
387
|
+
keyed by both the stored value and the display label like the existing
|
|
388
|
+
`buildOptionColorMap`, so ordering works whether or not the server resolved
|
|
389
|
+
the dimension's labels.
|
|
390
|
+
|
|
391
|
+
Requires the framework-side fix in objectstack#3588 for the selection keys to
|
|
392
|
+
take effect server-side.
|
|
393
|
+
|
|
394
|
+
- 6e8fd3c: fix(charts): a fieldless `count` aggregate keyed its value column `undefined`, so the chart plotted nothing (framework#3701)
|
|
395
|
+
|
|
396
|
+
framework#3701 pinned down what an OBJECT-bound chart aggregate names its result
|
|
397
|
+
columns — the raw field names it was given (`groupBy` for the category, `field`
|
|
398
|
+
for the value; no `sum_`-style decoration, unlike a dataset measure), plus the
|
|
399
|
+
literal `count` when a `count` omits `field`, which is the alias the engine
|
|
400
|
+
projects `COUNT(*)` under. `os validate` now lints page sources against that
|
|
401
|
+
convention, so the paths that build these rows have to honour it exactly.
|
|
402
|
+
|
|
403
|
+
Three of the four did. The odd one out was `count` — the one function that may
|
|
404
|
+
legitimately omit `field` — because every row builder read `params.field`
|
|
405
|
+
directly:
|
|
406
|
+
|
|
407
|
+
- `aggregateRecords` / `ObjectDataSource.aggregateClientSide` emitted
|
|
408
|
+
`{ [groupBy]: key, [undefined]: value }`, i.e. a column literally named
|
|
409
|
+
`undefined` that no axis binding could ever name;
|
|
410
|
+
- the legacy analytics path was worse: it remapped the server's `count` measure
|
|
411
|
+
onto `params.field` and **deleted** the original key, so the value the server
|
|
412
|
+
did return was thrown away before the chart saw it.
|
|
413
|
+
|
|
414
|
+
All of them now resolve the column through one helper (`aggregateValueKey`) so a
|
|
415
|
+
fieldless count lands under `count`, matching the framework contract. The
|
|
416
|
+
comparison-overlay column is derived from the same key (`count__comparison`
|
|
417
|
+
instead of `undefined__comparison`), and `aggregate.field` is typed optional to
|
|
418
|
+
match the spec's `ChartAggregateSchema`. Charts that name a field are unchanged.
|
|
419
|
+
|
|
420
|
+
- Updated dependencies [7b21891]
|
|
421
|
+
- Updated dependencies [0b3be01]
|
|
422
|
+
- Updated dependencies [3c4d935]
|
|
423
|
+
- Updated dependencies [4b60d2d]
|
|
424
|
+
- Updated dependencies [952b978]
|
|
425
|
+
- Updated dependencies [de5e40c]
|
|
426
|
+
- Updated dependencies [1a03af6]
|
|
427
|
+
- Updated dependencies [3e886eb]
|
|
428
|
+
- Updated dependencies [cfc675e]
|
|
429
|
+
- Updated dependencies [20df08c]
|
|
430
|
+
- Updated dependencies [1767124]
|
|
431
|
+
- Updated dependencies [8ecf5a6]
|
|
432
|
+
- Updated dependencies [af705b9]
|
|
433
|
+
- Updated dependencies [0502a7c]
|
|
434
|
+
- Updated dependencies [7b35e4b]
|
|
435
|
+
- Updated dependencies [8fb1295]
|
|
436
|
+
- Updated dependencies [e16ed2d]
|
|
437
|
+
- Updated dependencies [c6fd752]
|
|
438
|
+
- Updated dependencies [f9bbddb]
|
|
439
|
+
- Updated dependencies [dfd3705]
|
|
440
|
+
- Updated dependencies [c77108c]
|
|
441
|
+
- Updated dependencies [2735de6]
|
|
442
|
+
- Updated dependencies [c19ac11]
|
|
443
|
+
- Updated dependencies [6dee2cb]
|
|
444
|
+
- Updated dependencies [e05f052]
|
|
445
|
+
- Updated dependencies [0502a7c]
|
|
446
|
+
- Updated dependencies [faad45e]
|
|
447
|
+
- Updated dependencies [09c6a17]
|
|
448
|
+
- Updated dependencies [c7cff19]
|
|
449
|
+
- Updated dependencies [ba73a02]
|
|
450
|
+
- Updated dependencies [cd09a7b]
|
|
451
|
+
- Updated dependencies [f1abf0e]
|
|
452
|
+
- Updated dependencies [f05b84e]
|
|
453
|
+
- Updated dependencies [9b4b952]
|
|
454
|
+
- Updated dependencies [2f947e4]
|
|
455
|
+
- Updated dependencies [7d46648]
|
|
456
|
+
- Updated dependencies [9b53d72]
|
|
457
|
+
- Updated dependencies [bb4aa25]
|
|
458
|
+
- Updated dependencies [75f1cdf]
|
|
459
|
+
- Updated dependencies [662bdf9]
|
|
460
|
+
- Updated dependencies [059a052]
|
|
461
|
+
- Updated dependencies [53642d4]
|
|
462
|
+
- Updated dependencies [8aae006]
|
|
463
|
+
- Updated dependencies [c6cfdf1]
|
|
464
|
+
- Updated dependencies [d147a13]
|
|
465
|
+
- Updated dependencies [c6aaed8]
|
|
466
|
+
- Updated dependencies [263f885]
|
|
467
|
+
- Updated dependencies [dc334da]
|
|
468
|
+
- @object-ui/components@17.0.0
|
|
469
|
+
- @object-ui/i18n@17.0.0
|
|
470
|
+
- @object-ui/react@17.0.0
|
|
471
|
+
- @object-ui/types@17.0.0
|
|
472
|
+
- @object-ui/core@17.0.0
|
|
473
|
+
|
|
3
474
|
## 16.1.0
|
|
4
475
|
|
|
5
476
|
### Patch Changes
|
|
@@ -429,7 +900,7 @@
|
|
|
429
900
|
`ObjectView` emit the dataset shape. The legacy inline aggregate is kept as a
|
|
430
901
|
deprecated fallback so pre-ADR-0021 metadata keeps rendering.
|
|
431
902
|
|
|
432
|
-
Refs objectstack-ai/
|
|
903
|
+
Refs objectstack-ai/objectstack#1890
|
|
433
904
|
|
|
434
905
|
- ab168e4: Dashboard charts no longer render blank on first paint. Recharts'
|
|
435
906
|
`ResponsiveContainer` was a child of a `flex … justify-center` box, so it
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ChartContainerConfig } from './ChartContainerImpl';
|
|
2
|
+
import { NormalizedAxis, NormalizedSeries } from './normalizeChartSchema';
|
|
2
3
|
/**
|
|
3
4
|
* ObjectUI
|
|
4
5
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -8,18 +9,20 @@ import { ChartConfig } from './ChartContainerImpl';
|
|
|
8
9
|
*/
|
|
9
10
|
import * as React from "react";
|
|
10
11
|
export interface AdvancedChartImplProps {
|
|
12
|
+
/**
|
|
13
|
+
* Chart family. `combo` is renderer-local and rarely needs to be passed:
|
|
14
|
+
* series declaring different families derive it (`effectiveChartFamily`),
|
|
15
|
+
* which is how `@objectstack/spec` expresses a combo chart.
|
|
16
|
+
*/
|
|
11
17
|
chartType?: 'bar' | 'column' | 'horizontal-bar' | 'line' | 'area' | 'pie' | 'donut' | 'radar' | 'scatter' | 'funnel' | 'combo' | 'treemap' | 'sankey';
|
|
12
18
|
data?: Array<Record<string, any>>;
|
|
13
|
-
config?:
|
|
19
|
+
config?: ChartContainerConfig;
|
|
14
20
|
xAxisKey?: string;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
dashArray?: string;
|
|
21
|
-
label?: string;
|
|
22
|
-
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Plotted series, in the renderer's internal shape. Authors write the spec
|
|
23
|
+
* `series: [{ name, stack, yAxis, … }]`; `normalizeChartSchema` translates.
|
|
24
|
+
*/
|
|
25
|
+
series?: NormalizedSeries[];
|
|
23
26
|
className?: string;
|
|
24
27
|
/** Categorical/series colour palette. Overrides the theme's `--chart-1..n`
|
|
25
28
|
* defaults so a page/dashboard can brand its charts (data-screens). */
|
|
@@ -33,6 +36,20 @@ export interface AdvancedChartImplProps {
|
|
|
33
36
|
* categories absent here fall back to the positional palette, then the theme.
|
|
34
37
|
*/
|
|
35
38
|
categoryColors?: Record<string, string>;
|
|
39
|
+
/**
|
|
40
|
+
* Declared category order for ordered-sequence charts (funnel / pyramid),
|
|
41
|
+
* keyed like {@link categoryColors} by the category VALUE or its display
|
|
42
|
+
* LABEL, listed in domain order.
|
|
43
|
+
*
|
|
44
|
+
* A funnel's shape asserts a sequence, so without this the renderer can only
|
|
45
|
+
* guess at one and sorts by value descending. That is right for a generic
|
|
46
|
+
* "biggest first" funnel and wrong for a sales pipeline, where the stages
|
|
47
|
+
* have a declared order (Qualification → Needs Analysis → Proposal →
|
|
48
|
+
* Negotiation) that a healthy pipeline happens to narrow along — and an
|
|
49
|
+
* unhealthy one does not. When supplied, this order wins; categories not
|
|
50
|
+
* listed keep their incoming relative order after the listed ones.
|
|
51
|
+
*/
|
|
52
|
+
categoryOrder?: string[];
|
|
36
53
|
/**
|
|
37
54
|
* Optional drill-down click handler. Fires when a chart segment is clicked
|
|
38
55
|
* with `{ category, series, value }`. Wired for bar/horizontal-bar/line/
|
|
@@ -43,6 +60,40 @@ export interface AdvancedChartImplProps {
|
|
|
43
60
|
series?: string;
|
|
44
61
|
value?: number;
|
|
45
62
|
}) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Spec `ChartAxis` presentation for the category axis — `format` (tick
|
|
65
|
+
* formatter), `title`, `showGridLines`. Its `field` already arrived as
|
|
66
|
+
* {@link AdvancedChartImplProps.xAxisKey}. Resolved by
|
|
67
|
+
* `normalizeChartSchema`, so the renderer never parses the author shape.
|
|
68
|
+
*/
|
|
69
|
+
xAxis?: NormalizedAxis;
|
|
70
|
+
/**
|
|
71
|
+
* Spec `ChartConfig.yAxis` — one entry per value axis, in declaration order.
|
|
72
|
+
* Index 0 is the primary axis; a second entry (or one with
|
|
73
|
+
* `position: 'right'`) turns on the secondary axis that `series[].yAxis`
|
|
74
|
+
* binds to. Carries `min`/`max` (domain), `format` (ticks), `logarithmic`
|
|
75
|
+
* (scale) and `title`.
|
|
76
|
+
*/
|
|
77
|
+
yAxes?: NormalizedAxis[];
|
|
78
|
+
/** Spec `ChartConfig.showLegend`. Omitted → shown (the schema default). */
|
|
79
|
+
showLegend?: boolean;
|
|
80
|
+
/** Spec `ChartConfig.showDataLabels` — print each point's value on the mark. */
|
|
81
|
+
showDataLabels?: boolean;
|
|
82
|
+
/** Spec `ChartConfig.title` / `.subtitle`, rendered above the plot. */
|
|
83
|
+
title?: string;
|
|
84
|
+
subtitle?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Spec `ChartConfig.description` — the accessibility description. A chart is
|
|
87
|
+
* a picture to a screen reader; without this it announces as an unlabelled
|
|
88
|
+
* graphic, so the container carries it as `role="img"` + `aria-label`.
|
|
89
|
+
*/
|
|
90
|
+
description?: string;
|
|
91
|
+
/** Spec `ChartConfig.height` — fixed plot height in pixels. */
|
|
92
|
+
height?: number;
|
|
93
|
+
/** Spec `ChartConfig.annotations` — reference lines / bands. */
|
|
94
|
+
annotations?: Array<Record<string, any>>;
|
|
95
|
+
/** Spec `ChartConfig.interaction` — `tooltips`, `brush`. */
|
|
96
|
+
interaction?: Record<string, any>;
|
|
46
97
|
/**
|
|
47
98
|
* Disable Recharts' entrance animation when `false`. Animations drive the
|
|
48
99
|
* reveal via `requestAnimationFrame`, which browsers throttle/pause in
|
|
@@ -55,7 +106,10 @@ export interface AdvancedChartImplProps {
|
|
|
55
106
|
isAnimationActive?: boolean;
|
|
56
107
|
}
|
|
57
108
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
109
|
+
* Public entry point. A THIN wrapper purely so the unreadable-data guard can
|
|
110
|
+
* short-circuit without breaking the rules of hooks: the condition depends on
|
|
111
|
+
* `data`, which arrives asynchronously, so an early return inside the renderer
|
|
112
|
+
* would change its hook count between renders. The wrapper's own hook list is
|
|
113
|
+
* fixed, and the renderer below is reached with data it can actually plot.
|
|
60
114
|
*/
|
|
61
|
-
export default function AdvancedChartImpl(
|
|
115
|
+
export default function AdvancedChartImpl(props: AdvancedChartImplProps): React.JSX.Element;
|
|
@@ -11,7 +11,23 @@ declare const THEMES: {
|
|
|
11
11
|
readonly light: "";
|
|
12
12
|
readonly dark: ".dark";
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Per-series presentation for `<ChartContainer>`: a map from series dataKey to
|
|
16
|
+
* the legend label, icon and colour (or per-theme colours) that key renders
|
|
17
|
+
* with. Shadcn's chart primitive, kept in this package's own copy of it.
|
|
18
|
+
*
|
|
19
|
+
* Named `ChartContainerConfig`, not `ChartConfig` (objectui#3161,
|
|
20
|
+
* objectstack#4115 ledger batch 7). `@objectstack/spec/ui` owns `ChartConfig`
|
|
21
|
+
* for the authored chart METADATA — `type: bar | line | pie | …`, `xAxis`,
|
|
22
|
+
* `yAxis`, `series`, `showLegend`, `annotations` — and the collision was not
|
|
23
|
+
* theoretical here: `AdvancedChartImpl.tsx` declares `config?: ChartConfig`
|
|
24
|
+
* meaning THIS map, three lines above doc comments that say "Spec
|
|
25
|
+
* `ChartConfig.yAxis`" and "Spec `ChartConfig.showLegend`" meaning the other
|
|
26
|
+
* one. One identifier, two concepts, one file. `normalizeChartSchema` is the
|
|
27
|
+
* seam between them: it reads the authored spec chart and produces the
|
|
28
|
+
* renderer's axes/series, of which this map is the styling half.
|
|
29
|
+
*/
|
|
30
|
+
export type ChartContainerConfig = {
|
|
15
31
|
[k in string]: {
|
|
16
32
|
label?: React.ReactNode;
|
|
17
33
|
icon?: React.ComponentType;
|
|
@@ -24,7 +40,7 @@ export type ChartConfig = {
|
|
|
24
40
|
});
|
|
25
41
|
};
|
|
26
42
|
declare function ChartContainer({ id, className, children, config, disableSettleRemount, ...props }: React.ComponentProps<"div"> & {
|
|
27
|
-
config:
|
|
43
|
+
config: ChartContainerConfig;
|
|
28
44
|
children: React.ComponentProps<typeof ResponsiveContainer>["children"];
|
|
29
45
|
/**
|
|
30
46
|
* Skip the settle re-mount below. Set by callers that render their series with
|
|
@@ -36,7 +52,7 @@ declare function ChartContainer({ id, className, children, config, disableSettle
|
|
|
36
52
|
}): React.JSX.Element;
|
|
37
53
|
declare const ChartStyle: ({ id, config }: {
|
|
38
54
|
id: string;
|
|
39
|
-
config:
|
|
55
|
+
config: ChartContainerConfig;
|
|
40
56
|
}) => React.JSX.Element | null;
|
|
41
57
|
declare const ChartTooltip: typeof Tooltip;
|
|
42
58
|
declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }: any): React.JSX.Element | null;
|