@lightdash/cli 1.142.1 → 1.144.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.
|
@@ -21,11 +21,14 @@ instead stays frozen until somebody regenerates the whole viz.
|
|
|
21
21
|
|
|
22
22
|
## The hook
|
|
23
23
|
|
|
24
|
-
`useVizContext()` from `@lightdash/query-sdk` is the only
|
|
25
|
-
not add a message listener and do not
|
|
24
|
+
`useVizContext()` from `@lightdash/query-sdk` is the only channel to the host — data,
|
|
25
|
+
settings, and host actions all come from it. Do not add a message listener and do not
|
|
26
|
+
fetch anything yourself; the only host interaction is through the helpers the hook
|
|
27
|
+
returns.
|
|
26
28
|
|
|
27
29
|
```tsx
|
|
28
|
-
const { fieldMapping, rows, options, colorPalette, ready } =
|
|
30
|
+
const { fieldMapping, rows, options, colorPalette, ready, underlyingData } =
|
|
31
|
+
useVizContext();
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
- `fieldMapping` — `Record<string, string>`: the field name you declared → the query field
|
|
@@ -37,9 +40,11 @@ const { fieldMapping, rows, options, colorPalette, ready } = useVizContext();
|
|
|
37
40
|
- `colorPalette` — `string[]`: the Lightdash palette resolved for this chart. Always pushed,
|
|
38
41
|
whether or not you declared `colorPalette`. Empty only when the host resolved none.
|
|
39
42
|
- `ready` — false until the first context arrives.
|
|
43
|
+
- `underlyingData` — host-mediated access to the raw rows behind a clicked data point.
|
|
44
|
+
See "Data-point actions" below.
|
|
40
45
|
|
|
41
|
-
Read all
|
|
42
|
-
nobody can configure.
|
|
46
|
+
Read all of them. Ignoring `options` and `colorPalette` is the most common way to build a
|
|
47
|
+
viz nobody can configure.
|
|
43
48
|
|
|
44
49
|
### These app-level APIs do not apply to a viz
|
|
45
50
|
|
|
@@ -76,6 +81,48 @@ palette, delivered differently. An app imports `CHART_COLORS`; a viz reads the r
|
|
|
76
81
|
colours off the hook, because the viewer picks the palette per chart. In a viz, use the
|
|
77
82
|
hook, not `CHART_COLORS`.
|
|
78
83
|
|
|
84
|
+
## Data-point actions: underlying data
|
|
85
|
+
|
|
86
|
+
When `underlyingData.enabled` is true, viewers expect the standard Lightdash action on
|
|
87
|
+
chart marks: click a data point → small action menu → "View underlying data" → a dialog
|
|
88
|
+
listing the raw rows behind that point, with a Download button. When it is false (host
|
|
89
|
+
too old, viewer lacks permission, embed), render no menu item — never a disabled one.
|
|
90
|
+
|
|
91
|
+
Provenance is the contract: **every interactive datum keeps a reference to its
|
|
92
|
+
untransformed source row.** When mapping `rows` into chart data, carry the row:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
const data = rows.map((row) => ({
|
|
96
|
+
label: getFormatted(row, catField),
|
|
97
|
+
value: Number(getRaw(row, valField) ?? 0),
|
|
98
|
+
sourceRow: row, // ← required for underlying data
|
|
99
|
+
}));
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Only attach the action where one mark maps to exactly ONE source row and ONE metric-slot
|
|
103
|
+
field. A mark that aggregates several rows (a binned bucket, a "top N + other" slice)
|
|
104
|
+
gets no underlying-data item.
|
|
105
|
+
|
|
106
|
+
On click, fetch and render in a dialog themed like the rest of the viz:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
const result = await underlyingData.get({ row: datum.sourceRow, metric: 'value' });
|
|
110
|
+
// result.rows / result.columns / result.format — render as a table
|
|
111
|
+
// Download button:
|
|
112
|
+
// await underlyingData.download({ row: datum.sourceRow, metric: 'value', fileType: 'csv' });
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`metric` is the declared field NAME from your `fields` (the same key you read from
|
|
116
|
+
`fieldMapping`), not a query field id. Show `get()`/`download()` rejection messages in
|
|
117
|
+
the dialog — they are written for viewers.
|
|
118
|
+
|
|
119
|
+
Keep the dialog table dense — underlying data is often wide and long. Compact cell
|
|
120
|
+
padding (the table is for scanning, not presenting). If the header is sticky: pin it
|
|
121
|
+
flush at `top: 0` with an opaque background, and put NO padding on the scroll
|
|
122
|
+
container itself — pad the cells, not the scroller. A sticky header pins to the
|
|
123
|
+
container's content edge, so any container padding becomes a strip that rows
|
|
124
|
+
visibly scroll through above the header.
|
|
125
|
+
|
|
79
126
|
## The declaration
|
|
80
127
|
|
|
81
128
|
Alongside the component you emit one structured declaration — as **structured output, not a
|
|
@@ -206,3 +253,6 @@ chart.
|
|
|
206
253
|
Then check both directions: every key you read from `options` is declared, and every option
|
|
207
254
|
you declared is read somewhere. `colorPalette` is declared when you colour from
|
|
208
255
|
`colorPalette` — it is never read from `options`.
|
|
256
|
+
|
|
257
|
+
Finally, if the chart has clickable marks: each interactive datum carries `sourceRow`,
|
|
258
|
+
and the data-point action menu is gated on `underlyingData.enabled`.
|
|
@@ -25,6 +25,7 @@ Users describe features by what they see in the Lightdash editor. Translate:
|
|
|
25
25
|
| "delivery has all tabs", full data in scheduled deliveries | `delivery-render` | app code opt-in |
|
|
26
26
|
| external API data | `external-fetch` | app code opt-in |
|
|
27
27
|
| runs inside a dashboard tile | `viz-context` | required — see below |
|
|
28
|
+
| "view underlying data", raw rows behind a point (viz only) | `viz-underlying-data` | app code opt-in |
|
|
28
29
|
| light/dark mode, "matches my Lightdash theme" | `follow-host-theme` | CSS tokens — see below |
|
|
29
30
|
|
|
30
31
|
## Automatic (zero wiring — active on any current-SDK bundle)
|
|
@@ -98,6 +99,12 @@ re-rendering on every host toggle.
|
|
|
98
99
|
every tab's queries execute during capture while only the active tab stays
|
|
99
100
|
visible — never mount all tabs unconditionally (interactive loads must stay
|
|
100
101
|
lazy).
|
|
102
|
+
- `viz-underlying-data` (vizs only): keep the untransformed `sourceRow` on each
|
|
103
|
+
interactive datum, gate a data-point action menu on
|
|
104
|
+
`useVizContext().underlyingData.enabled`, render
|
|
105
|
+
`underlyingData.get({ row, metric })` in a themed dialog, and wire its
|
|
106
|
+
Download button to `underlyingData.download`. Full contract in the
|
|
107
|
+
`reusable-visualization` skill.
|
|
101
108
|
|
|
102
109
|
## After a template upgrade
|
|
103
110
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.144.1",
|
|
4
4
|
"description": "Lightdash CLI tool",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"unique-names-generator": "4.7.1",
|
|
43
43
|
"uuid": "11.1.1",
|
|
44
44
|
"yaml": "2.8.3",
|
|
45
|
-
"@lightdash/
|
|
46
|
-
"@lightdash/
|
|
45
|
+
"@lightdash/common": "1.144.1",
|
|
46
|
+
"@lightdash/warehouses": "1.144.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/inquirer": "8.2.4",
|