@carto/ps-react-ui 6.1.1 → 6.3.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/dist/{actions-BWlS5tpP.js → actions-CkxKe8-J.js} +57 -47
- package/dist/actions-CkxKe8-J.js.map +1 -0
- package/dist/category-DULnoxvk.js +933 -0
- package/dist/category-DULnoxvk.js.map +1 -0
- package/dist/chat.js +1 -1
- package/dist/chat.js.map +1 -1
- package/dist/components-CTUpdQuj.js.map +1 -1
- package/dist/download-B4sykOFm.js.map +1 -1
- package/dist/{echart-CV8F50gn.js → echart-ysYFLa_T.js} +2 -2
- package/dist/echart-ysYFLa_T.js.map +1 -0
- package/dist/formula-DJS-JLpk.js.map +1 -1
- package/dist/{option-builders-DQivvvbb.js → item-color-B7xkIpDZ.js} +26 -9
- package/dist/item-color-B7xkIpDZ.js.map +1 -0
- package/dist/legend.js.map +1 -1
- package/dist/{markdown-Bn2nKCbn.js → markdown-DmvLi3vx.js} +2 -2
- package/dist/markdown-DmvLi3vx.js.map +1 -0
- package/dist/{markdown-content-kYNLOX0T.js → markdown-content-BpAH_V6S.js} +5 -4
- package/dist/markdown-content-BpAH_V6S.js.map +1 -0
- package/dist/range-BpU2zBmq.js.map +1 -1
- package/dist/smart-tooltip-Dc_rHhyI.js.map +1 -1
- package/dist/spread-CQwFIwuz.js.map +1 -1
- package/dist/stores-DcBOZlU3.js.map +1 -1
- package/dist/stores-mad-9yFn.js.map +1 -1
- package/dist/styles-BCEBm7xh.js.map +1 -1
- package/dist/table-DEdW_fDj.js.map +1 -1
- package/dist/types/widgets/bar/types.d.ts +6 -0
- package/dist/types/widgets/category/category-ui.d.ts +10 -2
- package/dist/types/widgets/category/category.d.ts +7 -1
- package/dist/types/widgets/category/components/category-bar-stacked.d.ts +8 -1
- package/dist/types/widgets/category/components/category-bar.d.ts +24 -2
- package/dist/types/widgets/category/components/category-row-multi.d.ts +3 -1
- package/dist/types/widgets/category/components/category-row-single.d.ts +3 -1
- package/dist/types/widgets/category/components/category-row-stacked.d.ts +10 -1
- package/dist/types/widgets/category/style.d.ts +33 -6
- package/dist/types/widgets/histogram/bins.d.ts +7 -0
- package/dist/types/widgets/histogram/download.d.ts +2 -2
- package/dist/types/widgets/histogram/index.d.ts +2 -1
- package/dist/types/widgets/histogram/options.d.ts +1 -1
- package/dist/types/widgets/histogram/transforms.d.ts +5 -4
- package/dist/types/widgets/histogram/types.d.ts +22 -5
- package/dist/types/widgets/index.d.ts +1 -1
- package/dist/types/widgets/pie/types.d.ts +6 -0
- package/dist/types/widgets/scatterplot/download.d.ts +2 -2
- package/dist/types/widgets/scatterplot/index.d.ts +2 -1
- package/dist/types/widgets/scatterplot/points.d.ts +7 -0
- package/dist/types/widgets/scatterplot/transforms.d.ts +4 -3
- package/dist/types/widgets/scatterplot/types.d.ts +21 -2
- package/dist/types/widgets/timeseries/types.d.ts +6 -0
- package/dist/types/widgets/utils/item-color.d.ts +26 -0
- package/dist/utils-C-eWwOhE.js.map +1 -1
- package/dist/widgets/actions.js +1 -1
- package/dist/widgets/bar.js +78 -70
- package/dist/widgets/bar.js.map +1 -1
- package/dist/widgets/category.js +1 -1
- package/dist/widgets/echart.js +1 -1
- package/dist/widgets/histogram.js +116 -85
- package/dist/widgets/histogram.js.map +1 -1
- package/dist/widgets/markdown.js +2 -2
- package/dist/widgets/pie.js +109 -90
- package/dist/widgets/pie.js.map +1 -1
- package/dist/widgets/scatterplot.js +131 -92
- package/dist/widgets/scatterplot.js.map +1 -1
- package/dist/widgets/timeseries.js +82 -74
- package/dist/widgets/timeseries.js.map +1 -1
- package/dist/widgets.js +5 -5
- package/dist/widgets.js.map +1 -1
- package/dist/zoom-toggle-MmLjMTEw.js.map +1 -1
- package/package.json +2 -2
- package/src/widgets/actions/fullscreen/fullscreen-store.test.tsx +77 -13
- package/src/widgets/actions/fullscreen/fullscreen.tsx +48 -5
- package/src/widgets/bar/options.test.ts +106 -0
- package/src/widgets/bar/options.ts +25 -14
- package/src/widgets/bar/types.ts +6 -0
- package/src/widgets/category/category-ui.test.tsx +139 -0
- package/src/widgets/category/category-ui.tsx +64 -11
- package/src/widgets/category/category.test.tsx +67 -0
- package/src/widgets/category/category.tsx +32 -15
- package/src/widgets/category/components/category-bar-stacked.test.tsx +18 -0
- package/src/widgets/category/components/category-bar-stacked.tsx +42 -29
- package/src/widgets/category/components/category-bar.test.tsx +66 -0
- package/src/widgets/category/components/category-bar.tsx +65 -9
- package/src/widgets/category/components/category-row-multi.tsx +21 -0
- package/src/widgets/category/components/category-row-single.tsx +4 -0
- package/src/widgets/category/components/category-row-stacked.tsx +24 -1
- package/src/widgets/category/style.ts +58 -14
- package/src/widgets/histogram/bins.ts +22 -0
- package/src/widgets/histogram/download.test.ts +10 -0
- package/src/widgets/histogram/download.ts +7 -3
- package/src/widgets/histogram/index.ts +3 -0
- package/src/widgets/histogram/options.test.ts +62 -0
- package/src/widgets/histogram/options.ts +38 -17
- package/src/widgets/histogram/transforms.test.ts +21 -7
- package/src/widgets/histogram/transforms.ts +26 -12
- package/src/widgets/histogram/types.ts +25 -5
- package/src/widgets/index.ts +6 -1
- package/src/widgets/pie/options.test.ts +91 -0
- package/src/widgets/pie/options.ts +50 -20
- package/src/widgets/pie/types.ts +6 -0
- package/src/widgets/scatterplot/download.test.ts +9 -0
- package/src/widgets/scatterplot/download.ts +5 -3
- package/src/widgets/scatterplot/index.ts +3 -0
- package/src/widgets/scatterplot/options.test.ts +78 -0
- package/src/widgets/scatterplot/options.ts +35 -11
- package/src/widgets/scatterplot/points.ts +35 -0
- package/src/widgets/scatterplot/transforms.test.ts +19 -0
- package/src/widgets/scatterplot/transforms.ts +23 -18
- package/src/widgets/scatterplot/types.ts +25 -2
- package/src/widgets/timeseries/options.test.ts +65 -0
- package/src/widgets/timeseries/options.ts +31 -14
- package/src/widgets/timeseries/types.ts +6 -0
- package/src/widgets/utils/item-color.test.ts +74 -0
- package/src/widgets/utils/item-color.ts +55 -0
- package/dist/actions-BWlS5tpP.js.map +0 -1
- package/dist/category-alzjKzvQ.js +0 -839
- package/dist/category-alzjKzvQ.js.map +0 -1
- package/dist/echart-CV8F50gn.js.map +0 -1
- package/dist/markdown-Bn2nKCbn.js.map +0 -1
- package/dist/markdown-content-kYNLOX0T.js.map +0 -1
- package/dist/option-builders-DQivvvbb.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import * as echarts from 'echarts'
|
|
2
3
|
import { createTheme, type Theme } from '@mui/material'
|
|
3
4
|
import { createTimeseriesOptionFactory, timeseriesOptions } from './options'
|
|
4
5
|
|
|
@@ -397,3 +398,67 @@ describe('createTimeseriesOptionFactory', () => {
|
|
|
397
398
|
expect(out.grid.bottom).toBe(96)
|
|
398
399
|
})
|
|
399
400
|
})
|
|
401
|
+
|
|
402
|
+
describe('createTimeseriesOptionFactory — per-item colour', () => {
|
|
403
|
+
interface Out {
|
|
404
|
+
series: {
|
|
405
|
+
showSymbol: boolean
|
|
406
|
+
itemStyle: { color: (p: unknown) => string }
|
|
407
|
+
}[]
|
|
408
|
+
}
|
|
409
|
+
const data = [
|
|
410
|
+
[
|
|
411
|
+
{ name: 1, value: 1, color: '#00ff00' },
|
|
412
|
+
{ name: 2, value: 2 },
|
|
413
|
+
],
|
|
414
|
+
]
|
|
415
|
+
const p = (dataIndex: number, name: number) => ({
|
|
416
|
+
dataIndex,
|
|
417
|
+
color: '#0000ff',
|
|
418
|
+
value: { name },
|
|
419
|
+
})
|
|
420
|
+
const dim = (c: string) => echarts.color.modifyAlpha(c, 0.15)
|
|
421
|
+
|
|
422
|
+
it('datum colour wins over the series colour; template next', () => {
|
|
423
|
+
const merge = createTimeseriesOptionFactory({
|
|
424
|
+
theme,
|
|
425
|
+
series: [{ name: 'S', color: '#0000ff' }],
|
|
426
|
+
})
|
|
427
|
+
const out = merge(
|
|
428
|
+
{ series: [{ type: 'line', itemStyle: { color: '#123456' } }] },
|
|
429
|
+
data,
|
|
430
|
+
) as Out
|
|
431
|
+
const colorFn = out.series[0]!.itemStyle.color
|
|
432
|
+
expect(colorFn(p(0, 1))).toBe('#00ff00')
|
|
433
|
+
expect(colorFn(p(1, 2))).toBe('#123456')
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
it('calls a function template itemStyle.color', () => {
|
|
437
|
+
const factory = createTimeseriesOptionFactory({
|
|
438
|
+
theme,
|
|
439
|
+
optionsOverride: {
|
|
440
|
+
series: [{ type: 'line', itemStyle: { color: () => '#ff0000' } }],
|
|
441
|
+
},
|
|
442
|
+
})
|
|
443
|
+
const out = factory(factory(undefined, undefined), [
|
|
444
|
+
[{ name: 1, value: 1 }],
|
|
445
|
+
]) as Out
|
|
446
|
+
expect(out.series[0]!.itemStyle.color(p(0, 1))).toBe('#ff0000')
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
it('dims item colours outside the selection', () => {
|
|
450
|
+
const merge = createTimeseriesOptionFactory({ theme, selection: [2] })
|
|
451
|
+
const out = merge({}, data) as Out
|
|
452
|
+
const colorFn = out.series[0]!.itemStyle.color
|
|
453
|
+
expect(colorFn(p(0, 1))).toBe(dim('#00ff00'))
|
|
454
|
+
expect(colorFn(p(1, 2))).toBe('#0000ff')
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
it('shows symbols when a point has its own colour, not otherwise', () => {
|
|
458
|
+
const merge = createTimeseriesOptionFactory({ theme })
|
|
459
|
+
expect((merge({}, data) as Out).series[0]!.showSymbol).toBe(true)
|
|
460
|
+
const plain = merge({}, [[{ name: 1, value: 1 }]]) as Out
|
|
461
|
+
expect(plain.series[0]!.showSymbol).toBe(false)
|
|
462
|
+
expect(plain.series[0]!.itemStyle.color(p(0, 1))).toBe('#0000ff')
|
|
463
|
+
})
|
|
464
|
+
})
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { ZOOM_LAYOUT } from '../actions/zoom-toggle'
|
|
13
13
|
import type { OptionFactory } from '../echart'
|
|
14
14
|
import { mergeOptions, resolveThemeColor } from '../utils'
|
|
15
|
+
import { createItemColorResolver } from '../utils/item-color'
|
|
15
16
|
import { positionDataZoomForLegend } from '../utils/data-zoom-layout'
|
|
16
17
|
import type {
|
|
17
18
|
TimeseriesEChartsOption,
|
|
@@ -237,23 +238,39 @@ export function createTimeseriesOptionFactory(
|
|
|
237
238
|
// and points would stay dimmed forever after an external clear.
|
|
238
239
|
// Always emitting lets normal merge swap the callback in place, no
|
|
239
240
|
// `replaceMerge` and no entry-animation flash on selection on/off.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
241
|
+
//
|
|
242
|
+
// The base colour is the point's own `color`, else the template's
|
|
243
|
+
// `itemStyle.color`, else the series colour / palette (`params.color`).
|
|
244
|
+
const makeDimItemStyle = (datums: readonly object[], template: unknown) => {
|
|
245
|
+
const baseColor = createItemColorResolver({
|
|
246
|
+
theme,
|
|
247
|
+
datums,
|
|
248
|
+
template,
|
|
249
|
+
fallback: (params) => params.color as string,
|
|
250
|
+
})
|
|
251
|
+
return {
|
|
252
|
+
color: (params: CallbackDataParams) => {
|
|
253
|
+
const datum = params.value as
|
|
254
|
+
{ name?: Date | number | string } | undefined
|
|
255
|
+
const raw = datum?.name
|
|
256
|
+
const base = baseColor(params)
|
|
257
|
+
if (!selectionSet || raw == null) return base
|
|
258
|
+
return selectionSet.has(normalizeName(raw))
|
|
259
|
+
? base
|
|
260
|
+
: echarts.color.modifyAlpha(base, 0.15)
|
|
261
|
+
},
|
|
262
|
+
}
|
|
251
263
|
}
|
|
264
|
+
// Per-point colours only show on markers, so surface them whenever a
|
|
265
|
+
// point carries its own `color` (same reason as the selection case).
|
|
266
|
+
const hasDatumColor = seriesArr.some((s) =>
|
|
267
|
+
s.some((d) => typeof d?.color === 'string' && d.color !== ''),
|
|
268
|
+
)
|
|
252
269
|
|
|
253
270
|
return {
|
|
254
271
|
...option,
|
|
255
272
|
dataset: seriesArr.map((s) => ({ source: s as readonly object[] })),
|
|
256
|
-
series: seriesArr.map((
|
|
273
|
+
series: seriesArr.map((s, i) => {
|
|
257
274
|
const template =
|
|
258
275
|
(seriesTemplates[i] as object | undefined) ??
|
|
259
276
|
(broadcastTemplate as object)
|
|
@@ -271,10 +288,10 @@ export function createTimeseriesOptionFactory(
|
|
|
271
288
|
// When a selection is active, surface markers so the per-point
|
|
272
289
|
// color callback has something to dim — a continuous line would
|
|
273
290
|
// hide the visual selection feedback.
|
|
274
|
-
showSymbol: selectionSet != null,
|
|
291
|
+
showSymbol: selectionSet != null || hasDatumColor,
|
|
275
292
|
...(area ? { areaStyle: {} } : {}),
|
|
276
293
|
emphasis: { focus: 'series' },
|
|
277
|
-
itemStyle:
|
|
294
|
+
itemStyle: makeDimItemStyle(s, template),
|
|
278
295
|
...(overrideColor
|
|
279
296
|
? { color: overrideColor, lineStyle: { color: overrideColor } }
|
|
280
297
|
: {}),
|
|
@@ -10,6 +10,12 @@ import type { WidgetSeries } from '../types'
|
|
|
10
10
|
export interface TimeseriesDatum {
|
|
11
11
|
name: Date | number | string
|
|
12
12
|
value: number
|
|
13
|
+
/**
|
|
14
|
+
* Optional colour for this item (CSS colour or theme palette path such as
|
|
15
|
+
* `'primary.main'`). Wins over the template's `itemStyle.color` and the
|
|
16
|
+
* series colour; selection dimming still applies on top.
|
|
17
|
+
*/
|
|
18
|
+
color?: string
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
/** Timeseries widget data — one array of points per series. */
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest'
|
|
2
|
+
import { createTheme } from '@mui/material'
|
|
3
|
+
import type { CallbackDataParams } from 'echarts/types/dist/shared'
|
|
4
|
+
import { createItemColorResolver } from './item-color'
|
|
5
|
+
|
|
6
|
+
const theme = createTheme({ palette: { primary: { main: '#1976d2' } } })
|
|
7
|
+
const params = (dataIndex: number) =>
|
|
8
|
+
({ dataIndex, color: '#fallback' }) as unknown as CallbackDataParams
|
|
9
|
+
const fallback = (p: CallbackDataParams) => p.color as string
|
|
10
|
+
|
|
11
|
+
describe('createItemColorResolver', () => {
|
|
12
|
+
it('uses the datum colour first', () => {
|
|
13
|
+
const resolve = createItemColorResolver({
|
|
14
|
+
theme,
|
|
15
|
+
datums: [{ color: '#00ff00' }],
|
|
16
|
+
template: { itemStyle: { color: '#123456' } },
|
|
17
|
+
fallback,
|
|
18
|
+
})
|
|
19
|
+
expect(resolve(params(0))).toBe('#00ff00')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('uses a string template itemStyle.color when the datum has none', () => {
|
|
23
|
+
const resolve = createItemColorResolver({
|
|
24
|
+
theme,
|
|
25
|
+
datums: [{}, 3],
|
|
26
|
+
template: { itemStyle: { color: '#123456' } },
|
|
27
|
+
fallback,
|
|
28
|
+
})
|
|
29
|
+
expect(resolve(params(0))).toBe('#123456')
|
|
30
|
+
expect(resolve(params(1))).toBe('#123456')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('calls a function template itemStyle.color with the ECharts params', () => {
|
|
34
|
+
const color = vi.fn(() => '#abcdef')
|
|
35
|
+
const resolve = createItemColorResolver({
|
|
36
|
+
theme,
|
|
37
|
+
datums: [{}],
|
|
38
|
+
template: { itemStyle: { color } },
|
|
39
|
+
fallback,
|
|
40
|
+
})
|
|
41
|
+
const p = params(0)
|
|
42
|
+
expect(resolve(p)).toBe('#abcdef')
|
|
43
|
+
expect(color).toHaveBeenCalledWith(p)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('falls back when neither datum nor template give a colour', () => {
|
|
47
|
+
const resolve = createItemColorResolver({
|
|
48
|
+
theme,
|
|
49
|
+
datums: [{ value: 1 }],
|
|
50
|
+
template: { itemStyle: { color: () => undefined } },
|
|
51
|
+
fallback,
|
|
52
|
+
})
|
|
53
|
+
expect(resolve(params(0))).toBe('#fallback')
|
|
54
|
+
expect(resolve(params(5))).toBe('#fallback')
|
|
55
|
+
const noTemplate = createItemColorResolver({
|
|
56
|
+
theme,
|
|
57
|
+
datums: [],
|
|
58
|
+
template: undefined,
|
|
59
|
+
fallback,
|
|
60
|
+
})
|
|
61
|
+
expect(noTemplate(params(0))).toBe('#fallback')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('resolves theme palette paths on datum and template colours', () => {
|
|
65
|
+
const resolve = createItemColorResolver({
|
|
66
|
+
theme,
|
|
67
|
+
datums: [{ color: 'primary.main' }, {}],
|
|
68
|
+
template: { itemStyle: { color: () => 'primary.main' } },
|
|
69
|
+
fallback,
|
|
70
|
+
})
|
|
71
|
+
expect(resolve(params(0))).toBe('#1976d2')
|
|
72
|
+
expect(resolve(params(1))).toBe('#1976d2')
|
|
73
|
+
})
|
|
74
|
+
})
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Theme } from '@mui/material'
|
|
2
|
+
import type { CallbackDataParams } from 'echarts/types/dist/shared'
|
|
3
|
+
import { resolveThemeColor } from './resolve-theme-color'
|
|
4
|
+
|
|
5
|
+
/** ECharts `itemStyle.color` callback, as emitted by the chart widgets. */
|
|
6
|
+
export type ItemColorCallback = (params: CallbackDataParams) => string
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Builds the callback that resolves the **base** colour of every item of one
|
|
10
|
+
* series, before any selection dimming. Priority:
|
|
11
|
+
*
|
|
12
|
+
* 1. the datum's own `color` (`datums[params.dataIndex].color`);
|
|
13
|
+
* 2. the consumer's `template.itemStyle.color` (from `optionsOverride`):
|
|
14
|
+
* a string is used as is, a function is called with the ECharts params;
|
|
15
|
+
* 3. `fallback` — the widget's default (series colour / palette).
|
|
16
|
+
*
|
|
17
|
+
* The datum is looked up by `params.dataIndex` in the widget's own data
|
|
18
|
+
* rather than read off `params.data`, so it works whatever the dataset row
|
|
19
|
+
* shape is (object rows, `[label, count]` tuples, `[x, y]` tuples).
|
|
20
|
+
*
|
|
21
|
+
* Datum and template colours go through {@link resolveThemeColor}, same as
|
|
22
|
+
* per-series colours, so palette paths such as `'primary.main'` work.
|
|
23
|
+
*/
|
|
24
|
+
export function createItemColorResolver({
|
|
25
|
+
theme,
|
|
26
|
+
datums,
|
|
27
|
+
template,
|
|
28
|
+
fallback,
|
|
29
|
+
}: {
|
|
30
|
+
theme: Theme
|
|
31
|
+
datums: readonly unknown[]
|
|
32
|
+
template: unknown
|
|
33
|
+
fallback: ItemColorCallback
|
|
34
|
+
}): ItemColorCallback {
|
|
35
|
+
const templateColor = (template as { itemStyle?: { color?: unknown } })
|
|
36
|
+
?.itemStyle?.color
|
|
37
|
+
return (params) => {
|
|
38
|
+
const datumColor = readColor(datums[params.dataIndex])
|
|
39
|
+
if (datumColor) return resolveThemeColor(theme, datumColor)!
|
|
40
|
+
const custom =
|
|
41
|
+
typeof templateColor === 'function'
|
|
42
|
+
? (templateColor as (p: CallbackDataParams) => unknown)(params)
|
|
43
|
+
: templateColor
|
|
44
|
+
if (typeof custom === 'string' && custom !== '') {
|
|
45
|
+
return resolveThemeColor(theme, custom)!
|
|
46
|
+
}
|
|
47
|
+
return fallback(params)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function readColor(datum: unknown): string | undefined {
|
|
52
|
+
if (datum == null || typeof datum !== 'object') return undefined
|
|
53
|
+
const color = (datum as { color?: unknown }).color
|
|
54
|
+
return typeof color === 'string' && color !== '' ? color : undefined
|
|
55
|
+
}
|