@lightdash/cli 2.53.0 → 2.54.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.
|
@@ -27,6 +27,7 @@ fetch anything yourself; the only host interaction is through the helpers the ho
|
|
|
27
27
|
returns.
|
|
28
28
|
|
|
29
29
|
```tsx
|
|
30
|
+
const context = useVizContext();
|
|
30
31
|
const {
|
|
31
32
|
fieldMapping,
|
|
32
33
|
rows,
|
|
@@ -36,7 +37,7 @@ const {
|
|
|
36
37
|
ready,
|
|
37
38
|
underlyingData,
|
|
38
39
|
drillDown,
|
|
39
|
-
} =
|
|
40
|
+
} = context;
|
|
40
41
|
```
|
|
41
42
|
|
|
42
43
|
- `fieldMapping` — `Record<string, string>`: the field name you declared → the query field
|
|
@@ -47,6 +48,11 @@ const {
|
|
|
47
48
|
option you declared (the viewer's choice, else your declared `default`).
|
|
48
49
|
- `colorPalette` — `string[]`: the Lightdash palette resolved for this chart. Always pushed,
|
|
49
50
|
whether or not you declared `colorPalette`. Empty only when the host resolved none.
|
|
51
|
+
- `seriesColors` — `Record<string, string>`: final host-resolved colours keyed by backend
|
|
52
|
+
pivot column name. Read them through `resolveSeriesColor(context, column, index)`.
|
|
53
|
+
- `valueColors` — `Record<string, Record<string, string>>`: final host-resolved colours keyed
|
|
54
|
+
by query field id then raw value. Read them through
|
|
55
|
+
`resolveValueColor(context, fieldId, rawValue, index)`.
|
|
50
56
|
- `pivotDetails` — the complete backend-pivot layout, or `null` for ordinary rows. See
|
|
51
57
|
"Backend-pivoted results" below.
|
|
52
58
|
- `ready` — false until the first context arrives.
|
|
@@ -55,8 +61,8 @@ const {
|
|
|
55
61
|
- `drillDown` — host-mediated drill on a clicked data point. See "Data-point
|
|
56
62
|
actions" below.
|
|
57
63
|
|
|
58
|
-
Read all of them.
|
|
59
|
-
|
|
64
|
+
Read all of them. Pass the complete `context` to the colour helpers; they preserve model
|
|
65
|
+
colours and shared dashboard assignments before falling back to `colorPalette`.
|
|
60
66
|
|
|
61
67
|
### These app-level APIs do not apply to a viz
|
|
62
68
|
|
|
@@ -82,10 +88,15 @@ shadcn, charting, theming, floating surfaces, screenshots) still applies.
|
|
|
82
88
|
|
|
83
89
|
## Series colours
|
|
84
90
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
Use the query SDK's host-resolved colour helpers for every series or group:
|
|
92
|
+
|
|
93
|
+
- Backend-pivoted series: `resolveSeriesColor(context, column, index)`.
|
|
94
|
+
- Client-side groups: `resolveValueColor(context, fieldId, rawValue, index)`.
|
|
95
|
+
|
|
96
|
+
The helpers first honor model-defined fixed colours and Lightdash's shared dashboard colour
|
|
97
|
+
assignment, then fall back to `colorPalette[index % colorPalette.length]`. Keep a small
|
|
98
|
+
fallback array only for the case where the helper returns `undefined`, and declare
|
|
99
|
+
`colorPalette` in your output so the viewer gets the palette picker.
|
|
89
100
|
|
|
90
101
|
This is the same rule as the sandbox skill's "chart series colors must come from
|
|
91
102
|
`CHART_COLORS`" and `references/d3.md`'s "never hand-pick palettes" — the same Lightdash
|
|
@@ -132,11 +143,12 @@ const pivotedMetrics =
|
|
|
132
143
|
(column) => column.referenceField === metricId,
|
|
133
144
|
) ?? [];
|
|
134
145
|
|
|
135
|
-
const series = pivotedMetrics.map((column) => ({
|
|
146
|
+
const series = pivotedMetrics.map((column, index) => ({
|
|
136
147
|
columnId: column.pivotColumnName,
|
|
137
148
|
label:
|
|
138
149
|
column.pivotValues.find((value) => value.referenceField === seriesId)
|
|
139
150
|
?.formatted ?? 'Unknown',
|
|
151
|
+
color: resolveSeriesColor(context, column, index) ?? FALLBACK_COLORS[index % FALLBACK_COLORS.length],
|
|
140
152
|
}));
|
|
141
153
|
|
|
142
154
|
const categoryId = fieldMapping['category'];
|
|
@@ -151,7 +163,7 @@ const data = rows.map((row) => ({
|
|
|
151
163
|
}));
|
|
152
164
|
```
|
|
153
165
|
|
|
154
|
-
Use the order of `valuesColumns` for
|
|
166
|
+
Use the order of `valuesColumns` for the helper's fallback index. A chart with multiple
|
|
155
167
|
declared series fields builds its label from each matching `pivotValues` entry in declared
|
|
156
168
|
field order. Backend-pivoted rows do not have safe one-source-row provenance, so the host
|
|
157
169
|
sets `underlyingData.enabled` to false for them.
|
|
@@ -275,8 +287,8 @@ One entry per data column the component reads:
|
|
|
275
287
|
### `configOptions`
|
|
276
288
|
|
|
277
289
|
One entry per setting the viewer can change without regenerating the viz. Every option is a
|
|
278
|
-
whole-viz value applying to the entire chart — there is no per-series option.
|
|
279
|
-
|
|
290
|
+
whole-viz value applying to the entire chart — there is no per-series option. Colour series
|
|
291
|
+
and groups with the SDK's resolved-colour helpers.
|
|
280
292
|
|
|
281
293
|
Every option has:
|
|
282
294
|
|
|
@@ -301,9 +313,10 @@ Series colours are not in this list. They are declared separately, on `colorPale
|
|
|
301
313
|
### `colorPalette`
|
|
302
314
|
|
|
303
315
|
Whether the viewer gets the standard Lightdash palette picker. Declare
|
|
304
|
-
`{ "group": "..." }` when your component colours anything
|
|
305
|
-
when it colours nothing. `group` is optional and works like an
|
|
306
|
-
that tab, and gets a tab of its own when no option shares the
|
|
316
|
+
`{ "group": "..." }` when your component colours anything with the resolved-colour helpers
|
|
317
|
+
or `colorPalette`, or `null` when it colours nothing. `group` is optional and works like an
|
|
318
|
+
option's: the picker joins that tab, and gets a tab of its own when no option shares the
|
|
319
|
+
name.
|
|
307
320
|
|
|
308
321
|
This is not a config option. There is one palette per chart, it has no `name` and no
|
|
309
322
|
`default`, and its colours arrive on `colorPalette` — never on `options`.
|
|
@@ -313,19 +326,21 @@ This is not a config option. There is one palette per chart, it has no `name` an
|
|
|
313
326
|
Component and declaration lining up. Your chart will differ; the correspondence must not.
|
|
314
327
|
|
|
315
328
|
```tsx
|
|
316
|
-
import { useVizContext, getFormatted, getRaw } from '@lightdash/query-sdk';
|
|
329
|
+
import { useVizContext, getFormatted, getRaw, resolveValueColor } from '@lightdash/query-sdk';
|
|
317
330
|
import { Bar, BarChart, Cell, LabelList, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
|
|
318
331
|
|
|
319
332
|
function Chart() {
|
|
320
|
-
const
|
|
333
|
+
const context = useVizContext();
|
|
334
|
+
const { fieldMapping, rows, options, ready } = context;
|
|
321
335
|
if (!ready) return <div style={{ height: '100vh' }}>Loading…</div>;
|
|
322
336
|
const catField = fieldMapping['category']; // your field name -> column id
|
|
323
337
|
const valField = fieldMapping['value'];
|
|
324
338
|
const showLabels = options['showLabels'] as boolean; // your option name -> current value
|
|
325
339
|
const maxBars = options['maxBars'] as number;
|
|
326
|
-
const
|
|
340
|
+
const fallbackColors = ['#7162FF', '#1A1B1E'];
|
|
327
341
|
const data = rows.slice(0, maxBars).map((row) => ({
|
|
328
342
|
label: getFormatted(row, catField), // display text, e.g. "Completed"
|
|
343
|
+
category: getRaw(row, catField), // raw value for host-resolved colour
|
|
329
344
|
value: Number(getRaw(row, valField) ?? 0), // raw number
|
|
330
345
|
}));
|
|
331
346
|
return (
|
|
@@ -340,7 +355,12 @@ function Chart() {
|
|
|
340
355
|
<YAxis tickFormatter={(v) => v.toLocaleString()} />
|
|
341
356
|
<Tooltip />
|
|
342
357
|
<Bar dataKey="value">
|
|
343
|
-
{data.map((d, i) =>
|
|
358
|
+
{data.map((d, i) => (
|
|
359
|
+
<Cell
|
|
360
|
+
key={d.label}
|
|
361
|
+
fill={resolveValueColor(context, catField, d.category, i) ?? fallbackColors[i % fallbackColors.length]}
|
|
362
|
+
/>
|
|
363
|
+
))}
|
|
344
364
|
{showLabels && <LabelList dataKey="value" position="top" />}
|
|
345
365
|
</Bar>
|
|
346
366
|
</BarChart>
|
|
@@ -372,15 +392,16 @@ minimum, not a menu:
|
|
|
372
392
|
- every number you chose (bar width, max rows, decimal places, a threshold) → `number`
|
|
373
393
|
- every string you wrote into the chart (title, axis label, empty-state text) → `text`
|
|
374
394
|
- every accent colour that is not a series colour (a target line, a highlight) → `color`
|
|
375
|
-
- the series colours, whenever the chart draws more than one series →
|
|
395
|
+
- the series colours, whenever the chart draws more than one series → resolved-colour
|
|
396
|
+
helper plus `colorPalette`
|
|
376
397
|
|
|
377
398
|
Where the answer is yes, make that literal the option's `default`, declare the option, and
|
|
378
399
|
read the option in its place. Leave it hardcoded only where changing it would break the
|
|
379
400
|
chart.
|
|
380
401
|
|
|
381
402
|
Then check both directions: every key you read from `options` is declared, and every option
|
|
382
|
-
you declared is read somewhere. `colorPalette` is declared when you
|
|
383
|
-
`colorPalette` — it is never read from `options`.
|
|
403
|
+
you declared is read somewhere. `colorPalette` is declared when you use either resolved-
|
|
404
|
+
colour helper or colour from `colorPalette` — it is never read from `options`.
|
|
384
405
|
|
|
385
406
|
Finally, if any mark maps to exactly one source row, the data-point action
|
|
386
407
|
menu is wired: each interactive datum carries `sourceRow`, the underlying-data
|
|
@@ -1218,6 +1218,15 @@ function tableToCsv(columns: Column[], data: Row[], format: FormatFn): string {
|
|
|
1218
1218
|
</ScrollArea>
|
|
1219
1219
|
```
|
|
1220
1220
|
|
|
1221
|
+
### Table and query performance
|
|
1222
|
+
|
|
1223
|
+
Treat Safari/WebKit as the constrained target for layout-heavy apps. Test dense tables and filter interactions in Safari: an app that is smooth there will generally be smooth in Chrome, but the reverse is not guaranteed.
|
|
1224
|
+
|
|
1225
|
+
- **Bound data-derived columns.** Pivot-style tables that derive columns from dates, categories, or other result values must cap the rendered window. Paginate the column range or virtualize it horizontally; never render an unbounded `dates.map(...)` or equivalent column set.
|
|
1226
|
+
- **Keep sticky positioning to headers.** Never apply `position: sticky` to body cells. If a pinned first column is essential, render it as a separate fixed pane synchronized with the scrollable data pane.
|
|
1227
|
+
- **Virtualize individual rows, not multi-row groups.** For large tables, avoid mounting virtualized rows inside one shared `<table>` layout where scroll-driven row changes can relayout the whole table. Prefer block or grid rows with fixed column widths, and make each virtual item one row rather than a group containing many rows and cells.
|
|
1228
|
+
- **Batch filter-driven queries.** When a control change would refetch multiple queries, debounce the committed filter value or require an Apply action. Do not fire the full query fan-out on every date, granularity, or filter input change.
|
|
1229
|
+
|
|
1221
1230
|
### Resizable panels
|
|
1222
1231
|
|
|
1223
1232
|
Only when the user asks for adjustable panel sizing (or two sibling areas genuinely benefit from rebalancing), read `/app/references/resizable-panels.md` and use the pre-installed shadcn `Resizable`. Otherwise use fixed flex/grid proportions — don't reach for it by default.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.54.0",
|
|
4
4
|
"description": "Lightdash CLI tool",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"unique-names-generator": "4.7.1",
|
|
46
46
|
"uuid": "11.1.1",
|
|
47
47
|
"yaml": "2.8.3",
|
|
48
|
-
"@lightdash/
|
|
49
|
-
"@lightdash/
|
|
48
|
+
"@lightdash/warehouses": "2.54.0",
|
|
49
|
+
"@lightdash/common": "2.54.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/inquirer": "8.2.4",
|