@fundar/data-chart-telling 1.0.0 → 1.1.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 +21 -0
- package/README.md +57 -18
- package/dist/configuration/config.svelte.js +13 -1
- package/dist/configuration/themes/index.d.ts +124 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/layout/base/BasePlotLayout.svelte +18 -5
- package/dist/layout/hover/HoverSettings.d.ts +20 -6
- package/dist/layout/hover/HoverSettings.js +29 -4
- package/dist/layout/legend/LegendState.svelte.d.ts +5 -0
- package/dist/layout/legend/LegendState.svelte.js +4 -0
- package/dist/layout/plot/Plot.svelte +6 -3
- package/dist/layout/plot/PublicPlotContext.d.ts +5 -4
- package/dist/layout/plot/PublicPlotContext.js +7 -3
- package/dist/layout/plot/Slice.js +4 -2
- package/dist/layout/scales/EdgeTicks.d.ts +39 -0
- package/dist/layout/scales/EdgeTicks.js +82 -0
- package/dist/layout/scales/NiceTicks.d.ts +40 -0
- package/dist/layout/scales/NiceTicks.js +72 -0
- package/dist/layout/scales/ScalesLayout.svelte +64 -30
- package/dist/layout/scales/ScalesLayout.svelte.d.ts +5 -0
- package/dist/layout/scales/SveltePlotScale.d.ts +15 -0
- package/dist/layout/scales/SveltePlotScale.js +79 -0
- package/dist/layout/styles/ValueLabels.js +3 -2
- package/dist/layout/timeline/Timeline.svelte +5 -2
- package/dist/layout/timeline/Timeline.svelte.d.ts +2 -0
- package/dist/layout/timeline/TimelineLayout.svelte +38 -12
- package/dist/layout/timeline/TimelineLayout.svelte.d.ts +7 -5
- package/dist/layout/timeline/TimelineRule.svelte +1 -0
- package/dist/layout/timeline/TimelineState.svelte.d.ts +13 -5
- package/dist/layout/timeline/TimelineState.svelte.js +42 -8
- package/dist/layout/timeline/TimelineTime.d.ts +18 -0
- package/dist/layout/timeline/TimelineTime.js +117 -0
- package/dist/layout/tooltip/Tooltip.svelte +6 -3
- package/dist/layout/tooltip/Tooltip.svelte.d.ts +2 -0
- package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -2
- package/dist/layout/tooltip/TooltipState.svelte.js +22 -3
- package/dist/markers/delta/DeltaMarker.svelte +9 -7
- package/dist/phases/Pipeline.js +3 -2
- package/dist/phases/data/DataPhase.d.ts +5 -11
- package/dist/phases/data/DataPhase.js +11 -8
- package/dist/phases/facet/FacetPanels.d.ts +54 -0
- package/dist/phases/facet/FacetPanels.js +95 -0
- package/dist/phases/facet/FacetPhase.d.ts +1 -42
- package/dist/phases/facet/FacetPhase.js +1 -87
- package/dist/phases/hover/HoverPhase.d.ts +6 -43
- package/dist/phases/hover/HoverPhase.js +19 -54
- package/dist/phases/mapping/MappingPhase.d.ts +1 -1
- package/dist/phases/mapping/MappingPhase.js +2 -4
- package/dist/phases/scales/ScalesPhase.d.ts +1 -3
- package/dist/phases/scales/ScalesPhase.js +17 -21
- package/dist/phases/sharedScales/SharedScalesPhase.d.ts +4 -1
- package/dist/phases/sharedScales/SharedScalesPhase.js +10 -7
- package/dist/phases/statistics/StatisticsPhase.js +3 -4
- package/dist/phases/tooltip/TooltipPhase.d.ts +4 -2
- package/dist/phases/tooltip/TooltipPhase.js +10 -3
- package/dist/phases/transforms/ProcessedPositions.d.ts +30 -0
- package/dist/phases/transforms/ProcessedPositions.js +74 -0
- package/dist/phases/transforms/TransformsPhase.d.ts +5 -42
- package/dist/phases/transforms/TransformsPhase.js +20 -57
- package/dist/plots/area/markers.js +1 -2
- package/dist/plots/bar/defaults.js +6 -10
- package/dist/plots/bar/markers.js +5 -4
- package/dist/plots/box/BoxSummaries.d.ts +19 -0
- package/dist/plots/box/BoxSummaries.js +101 -0
- package/dist/plots/box/Plot.svelte +42 -0
- package/dist/plots/box/Plot.svelte.d.ts +26 -0
- package/dist/plots/box/defaults.d.ts +12 -0
- package/dist/plots/box/defaults.js +34 -0
- package/dist/plots/box/markers.d.ts +12 -0
- package/dist/plots/box/markers.js +34 -0
- package/dist/plots/geo/phases/hover.js +5 -5
- package/dist/plots/geo/phases/markers.js +3 -4
- package/dist/plots/geo/slices.js +6 -3
- package/dist/plots/heatmap/markers.js +2 -1
- package/dist/plots/histogram/defaults.js +1 -1
- package/dist/plots/histogram/markers.js +4 -4
- package/dist/plots/line/markers.js +1 -2
- package/dist/plots/pyramid/defaults.js +3 -2
- package/dist/plots/pyramid/markers.js +3 -6
- package/dist/plots/scatter/defaults.js +3 -2
- package/dist/plots/scatter/markers.js +4 -3
- package/dist/types/configuration/styling.d.ts +24 -2
- package/dist/types/layout/composer.d.ts +5 -2
- package/dist/types/layout/scales.d.ts +16 -0
- package/dist/types/layout/timeline.d.ts +14 -5
- package/dist/types/phases/hover/phase.d.ts +6 -0
- package/dist/types/phases/state.d.ts +5 -2
- package/dist/types/phases/statistics/phase.d.ts +3 -1
- package/dist/types/phases/transforms/phase.d.ts +10 -0
- package/dist/types/plots/box/props.d.ts +10 -0
- package/dist/types/plots/box/props.js +1 -0
- package/dist/types/plots/box/state.d.ts +23 -0
- package/dist/types/plots/box/state.js +1 -0
- package/dist/types/plots/props.d.ts +2 -0
- package/docs/chrome.md +39 -8
- package/docs/composer.md +19 -3
- package/docs/concepts.md +1 -1
- package/docs/development.md +14 -5
- package/docs/facets.md +62 -8
- package/docs/getting-started.md +8 -9
- package/docs/legend.md +62 -15
- package/docs/markers.md +17 -6
- package/docs/plots.md +168 -42
- package/docs/scales.md +36 -19
- package/docs/state.md +1 -1
- package/docs/styles-and-segments.md +85 -31
- package/docs/theming.md +30 -19
- package/docs/timeline.md +62 -28
- package/docs/tooltip-and-hover.md +72 -24
- package/docs/transforms-and-statistics.md +47 -17
- package/examples/BarValues.svelte +2 -2
- package/examples/Box.svelte +7 -0
- package/examples/Chrome.svelte +17 -0
- package/examples/ChromeOrder.svelte +18 -0
- package/examples/Composer.svelte +23 -0
- package/examples/CustomTooltip.svelte +21 -14
- package/examples/Facets.svelte +3 -3
- package/examples/FacetsCarousel.svelte +14 -0
- package/examples/FacetsRowsCols.svelte +23 -0
- package/examples/FirstPlot.svelte +7 -0
- package/examples/Gaps.svelte +21 -0
- package/examples/GroupedBars.svelte +15 -0
- package/examples/Heatmap.svelte +7 -0
- package/examples/HeatmapSegments.svelte +26 -0
- package/examples/Histogram.svelte +14 -0
- package/examples/HorizontalBars.svelte +15 -0
- package/examples/LegendSections.svelte +27 -0
- package/examples/LegendToggle.svelte +3 -3
- package/examples/LineByRegion.svelte +18 -0
- package/examples/LineDates.svelte +15 -0
- package/examples/Markers.svelte +27 -0
- package/examples/MovingAverage.svelte +15 -0
- package/examples/Pyramid.svelte +7 -0
- package/examples/Regression.svelte +14 -0
- package/examples/ResponsiveLine.svelte +7 -7
- package/examples/Scales.svelte +26 -0
- package/examples/Scatter.svelte +16 -0
- package/examples/SegmentHighlight.svelte +22 -0
- package/examples/Segments.svelte +11 -3
- package/examples/SegmentsBySeries.svelte +25 -0
- package/examples/StackedArea.svelte +16 -0
- package/examples/StackedBars.svelte +15 -0
- package/examples/TimelinePlayer.svelte +8 -7
- package/examples/TimelineRule.svelte +19 -0
- package/examples/Tooltip.svelte +3 -3
- package/examples/ValueLabels.svelte +21 -0
- package/examples/data.ts +320 -8
- package/llms-full.txt +33 -5
- package/llms.txt +30 -2
- package/package.json +3 -2
- package/dist/layout/scales/buildScale.d.ts +0 -8
- package/dist/layout/scales/buildScale.js +0 -67
- package/dist/layout/scales/niceDomain.d.ts +0 -23
- package/dist/layout/scales/niceDomain.js +0 -59
package/docs/theming.md
CHANGED
|
@@ -31,25 +31,26 @@ resetConfiguration(); // back to the shipped defaults
|
|
|
31
31
|
|
|
32
32
|
## Sections
|
|
33
33
|
|
|
34
|
-
| Key
|
|
35
|
-
|
|
|
36
|
-
| `font`, `color`, `background`
|
|
37
|
-
| `palette`
|
|
38
|
-
| `symbols`
|
|
39
|
-
| `continuous`
|
|
40
|
-
| `spacing`, `chrome`
|
|
41
|
-
| `title`, `subtitle`, `caption`
|
|
42
|
-
| `divider`
|
|
43
|
-
| `legend`
|
|
44
|
-
| `axis`
|
|
45
|
-
| `tooltip`
|
|
46
|
-
| `margins`
|
|
47
|
-
| `line`, `area`, `bar`, `pyramid`, `histogram`, `scatter` | Per-kind defaults: stroke width, dot radius, series padding, gap fills, fill opacity, inset
|
|
48
|
-
| `text`
|
|
49
|
-
| `hover`
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
34
|
+
| Key | Controls |
|
|
35
|
+
| --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
36
|
+
| `font`, `color`, `background` | Base text of every figure |
|
|
37
|
+
| `palette` | Categorical series colors, in order |
|
|
38
|
+
| `symbols` | Shape cycle for the `symbol` channel |
|
|
39
|
+
| `continuous` | Default ramp endpoints, label color and opacity range for continuous color and opacity |
|
|
40
|
+
| `spacing`, `chrome` | Padding around header, legend and caption; the chrome `order` and `rowGap` |
|
|
41
|
+
| `title`, `subtitle`, `caption` | Text blocks: `font`, `size`, `weight`, `color`, `leading`, `spacing` |
|
|
42
|
+
| `divider` | The line a `'divider'` in the chrome `order` draws |
|
|
43
|
+
| `legend` | Text, gaps, swatches, `disabledOpacity`, paginated nav buttons, the continuous bar, its handles, ticks and labels, and the `seriesTitle` and `sizeScale` options |
|
|
44
|
+
| `axis` | Axis color, font and tick sizes, `grid`, and the number locale (below) |
|
|
45
|
+
| `tooltip` | Tooltip background, color, font size, padding, radius, border |
|
|
46
|
+
| `margins` | Default margin per side (`'auto'` or a number) |
|
|
47
|
+
| `line`, `area`, `bar`, `pyramid`, `histogram`, `box`, `scatter` | Per-kind defaults: stroke width, dot radius, series padding, gap fills, fill opacity, inset, box padding |
|
|
48
|
+
| `text` | `declutter` geometry of value labels and connectors |
|
|
49
|
+
| `hover` | Look of the hover marker: `rule`, `dot`, `font`, `area` |
|
|
50
|
+
| `delta` | The `delta` marker's label, per axis the delta is taken on: `text.x` (beside a vertical delta: `dx: 12`, `textAnchor: 'start'`) and `text.y` (above a horizontal one: `dy: -10`, `textAnchor: 'middle'`). `lineAnchor` picks where along the delta the label sits and how it aligns there |
|
|
51
|
+
| `timeline` | The rule (`rule`) and the player bar (`player`: controls, speeds, `stepDuration`, button, track, thumb, toggle) |
|
|
52
|
+
| `facet` | The position badge and prev/next buttons |
|
|
53
|
+
| `frameClip` | Tolerance for clipping marks to the plot frame |
|
|
53
54
|
|
|
54
55
|
## Locale
|
|
55
56
|
|
|
@@ -61,6 +62,16 @@ setConfiguration({ axis: { locale: 'en-US', compactDisplay: 'long' } });
|
|
|
61
62
|
|
|
62
63
|
`axis.locale` updates plots already on screen. `axis.compactDisplay` is read when a plot mounts, so a later change shows on the next mount.
|
|
63
64
|
|
|
65
|
+
## Edge ticks
|
|
66
|
+
|
|
67
|
+
`axis.edgeTicks.x` and `axis.edgeTicks.y` (`{ enabled, collision }`, on for x and off for y, both `'drop-nice'`) add a tick at the data's first and last values beside the nice ones, on a continuous axis whose other axis is continuous too, so a reader sees where the data starts and ends. When one lands too close to a nice tick for both labels, `collision` picks what gives way: `'drop-nice'` keeps the data's tick, `'drop-edge'` keeps the nice one, `'extend'` widens the axis to the next nice tick past the data.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
setConfiguration({ axis: { edgeTicks: { x: { enabled: true, collision: 'extend' } } } });
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
A plot overrides it with `scales.x.edgeTicks` or `scales.y.edgeTicks` (see [Scales](scales.md)).
|
|
74
|
+
|
|
64
75
|
## CSS variables
|
|
65
76
|
|
|
66
77
|
Some fields reach the DOM as CSS custom properties, which every figure sets on its root element and the components read with a fallback. Those can also be overridden with plain CSS on a wrapping element for a one-off, non-reactive tweak:
|
package/docs/timeline.md
CHANGED
|
@@ -2,33 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
`timeline` steps a plot through its data by a field - usually a year or a date. Each step shows the rows of one value of that field. It draws as a **player** by default - a control bar with play, pause and a slider - or as a **rule**, a guide beside the plot that the page drives (`type: 'rule'`).
|
|
4
4
|
|
|
5
|
+
<!-- example: examples/TimelinePlayer.svelte -->
|
|
6
|
+
|
|
5
7
|
```svelte
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import { BarPlot } from '@fundar/data-chart-telling';
|
|
10
|
+
import { REGION_VALUES } from './data';
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!--
|
|
14
|
+
`timeline` slices the rows by `accessor`. A timeline is a player by default:
|
|
15
|
+
play/pause, the current step and a slider in the chrome. `progress` sets where
|
|
16
|
+
it starts. `type: 'rule'` draws a guide beside the plot with no controls
|
|
17
|
+
instead (see TimelineRule). To build your own widget, read
|
|
18
|
+
`useFigure().timeline` (seek, play, pause, next, ...).
|
|
19
|
+
-->
|
|
6
20
|
<BarPlot
|
|
7
|
-
{
|
|
8
|
-
{
|
|
9
|
-
data={
|
|
21
|
+
width={720}
|
|
22
|
+
height={400}
|
|
23
|
+
data={REGION_VALUES}
|
|
10
24
|
x="region"
|
|
11
25
|
y="value"
|
|
12
|
-
scales={{ y: { domain: [0,
|
|
13
|
-
timeline={{ accessor: '
|
|
26
|
+
scales={{ y: { domain: [0, 30] } }}
|
|
27
|
+
timeline={{ accessor: 'date', progress: 0.25, player: { autoplay: false, loop: true } }}
|
|
14
28
|
/>
|
|
15
29
|
```
|
|
16
30
|
|
|
31
|
+
<!-- /example -->
|
|
32
|
+
|
|
17
33
|

|
|
18
34
|
|
|
19
35
|
## Options
|
|
20
36
|
|
|
21
|
-
| Option | Meaning
|
|
22
|
-
| ---------------------------------- |
|
|
23
|
-
| `accessor` | Field (or function) giving each row's step - required
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
37
|
+
| Option | Meaning |
|
|
38
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| `accessor` | Field (or function) giving each row's step - required. A number (a year, a count), a `Date`, or a date string: ISO (`'2023'`, `'2023-05'`, `'2023-05-17'`, with or without a time), or any other read through `dateFormat`. A row whose value reads as none shows at every step |
|
|
40
|
+
| `dateFormat` | How a date string that is not ISO reads: the tokens `YYYY`, `MM`, `DD`, `HH`, `mm`, `ss`, anything else literal (`'DD/MM/YYYY'`, `'MM-YYYY'`). A part it leaves out is the first: January, the 1st, midnight |
|
|
41
|
+
| `type` | `'player'` (default) draws a control bar in the chrome; `'rule'` draws a guide with the steps written along it |
|
|
42
|
+
| `progress` | The position, `0`-`1`. A player keeps its own position from there on, until `progress` changes |
|
|
43
|
+
| `values` | The steps, when not every distinct value of `accessor` - read like `accessor`'s values |
|
|
44
|
+
| `filterMode` | `'exact'` shows the rows of the current step; `'upTo'` shows every row up to it (a cumulative reveal). `LinePlot` defaults to `'upTo'` |
|
|
45
|
+
| `interpolate` | Tween values between steps so a scrub is smooth: `true`, or `{ key, value, create, progressEasing, segmentEasing }`. Line and bar plots default to interpolating their value channel |
|
|
46
|
+
| `scales` | `'shared'` (default): axes span every step, so they hold still while scrubbing; `'free'` refits them to each step |
|
|
47
|
+
| `onprogress`, `onvalue` | Called with the new position (`0`-`1`) and with the step it lands on - a `Date` on a timeline of dates, else the number |
|
|
48
|
+
| `orientation`, `show`, `thickness` | A rule's direction (`'vertical'` default, beside the plot; `'horizontal'`), visibility and size |
|
|
32
49
|
|
|
33
50
|
## Player
|
|
34
51
|
|
|
@@ -52,15 +69,15 @@ The player is a bar in the chrome, below the plot by default, placed like any ot
|
|
|
52
69
|
/>
|
|
53
70
|
```
|
|
54
71
|
|
|
55
|
-
| `player` option | Meaning
|
|
56
|
-
| ----------------------------- |
|
|
57
|
-
| `controls` | The controls drawn, in this order: `'play'`, `'value'`, `'slider'`, `'speed'`, `'loop'`
|
|
58
|
-
| `autoplay` | Start playing as soon as there are steps
|
|
59
|
-
| `loop`, `speed` | Where the player starts; it keeps them from there and tells `onloop` / `onspeed` on change
|
|
60
|
-
| `speeds` | Speeds the speed control cycles through
|
|
61
|
-
| `stepDuration` | Milliseconds per step at speed `1`
|
|
62
|
-
| `format` | How
|
|
63
|
-
| `onplay`, `onspeed`, `onloop` | Change callbacks
|
|
72
|
+
| `player` option | Meaning |
|
|
73
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
74
|
+
| `controls` | The controls drawn, in this order: `'play'`, `'value'`, `'slider'`, `'speed'`, `'loop'` |
|
|
75
|
+
| `autoplay` | Start playing as soon as there are steps |
|
|
76
|
+
| `loop`, `speed` | Where the player starts; it keeps them from there and tells `onloop` / `onspeed` on change |
|
|
77
|
+
| `speeds` | Speeds the speed control cycles through |
|
|
78
|
+
| `stepDuration` | Milliseconds per step at speed `1` |
|
|
79
|
+
| `format` | How a step reads, in the `'value'` control and along a rule. It gets a `Date` on a timeline of dates, else the number. Defaults to the step itself; dates read as dates, as precise as the steps need (`2023`, `ene 2023`, `17 ene 2023`) in `axis.locale` |
|
|
80
|
+
| `onplay`, `onspeed`, `onloop` | Change callbacks |
|
|
64
81
|
|
|
65
82
|
Defaults for `controls`, `speeds` and `stepDuration` come from `timeline.player` in the [configuration](theming.md), together with the bar's colors and sizes.
|
|
66
83
|
|
|
@@ -68,22 +85,39 @@ Defaults for `controls`, `speeds` and `stepDuration` come from `timeline.player`
|
|
|
68
85
|
|
|
69
86
|
`type: 'rule'` draws a line with its steps written along it, beside the plot. `progress` picks the step, and the page supplies the control (a slider, a button, scroll position):
|
|
70
87
|
|
|
88
|
+
<!-- example: examples/TimelineRule.svelte -->
|
|
89
|
+
|
|
71
90
|
```svelte
|
|
72
91
|
<script lang="ts">
|
|
73
|
-
|
|
92
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
93
|
+
import { REGION_VALUES } from './data';
|
|
94
|
+
|
|
95
|
+
// A rule has no controls of its own: the page moves it through `progress` (0 to 1).
|
|
96
|
+
// One step per year; a line plot shows every row up to the current step.
|
|
97
|
+
let progress = $state(0.5);
|
|
74
98
|
</script>
|
|
75
99
|
|
|
76
100
|
<input type="range" min="0" max="1" step="0.001" bind:value={progress} />
|
|
77
|
-
<LinePlot
|
|
101
|
+
<LinePlot
|
|
102
|
+
width={720}
|
|
103
|
+
height={400}
|
|
104
|
+
data={REGION_VALUES}
|
|
105
|
+
x="date"
|
|
106
|
+
y="value"
|
|
107
|
+
color="region"
|
|
108
|
+
timeline={{ accessor: (row) => row.date.getUTCFullYear(), type: 'rule', progress }}
|
|
109
|
+
/>
|
|
78
110
|
```
|
|
79
111
|
|
|
112
|
+
<!-- /example -->
|
|
113
|
+
|
|
80
114
|

|
|
81
115
|
|
|
82
116
|
A rule's look comes from `timeline.rule` in the [configuration](theming.md) (`fontSize`, `activeFontSize`, `axisWidth`, ...) and `--dct-timeline-*` variables.
|
|
83
117
|
|
|
84
118
|
## Custom controls
|
|
85
119
|
|
|
86
|
-
`useFigure().timeline` exposes the timeline's state and actions, to build a widget of your own in place of the player: `steps`, `value`, `index`, `progress`, `playing`, `loop`, `speed`, `speeds`, and `seek`, `seekIndex`, `seekValue`, `next`, `previous`, `play`, `pause`, `toggle`, `setLoop`, `setSpeed`, `cycleSpeed`. See [Reading plot state](state.md).
|
|
120
|
+
`useFigure().timeline` exposes the timeline's state and actions, to build a widget of your own in place of the player: `steps`, `value`, `index`, `progress`, `playing`, `loop`, `speed`, `speeds`, and `seek`, `seekIndex`, `seekValue`, `next`, `previous`, `play`, `pause`, `toggle`, `setLoop`, `setSpeed`, `cycleSpeed`. On a timeline of dates, `steps` and `value` are `Date`s and `seekValue` takes a `Date` or a date string. See [Reading plot state](state.md).
|
|
87
121
|
|
|
88
122
|
## One timeline for several plots
|
|
89
123
|
|
|
@@ -4,51 +4,99 @@ A plot becomes interactive when it is given a `tooltip`, a `{ type: 'hover' }` m
|
|
|
4
4
|
|
|
5
5
|
## Tooltip
|
|
6
6
|
|
|
7
|
+
<!-- example: examples/Tooltip.svelte -->
|
|
8
|
+
|
|
7
9
|
```svelte
|
|
8
|
-
<
|
|
10
|
+
<script lang="ts">
|
|
11
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
12
|
+
import { REGION_VALUES } from './data';
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<!--
|
|
16
|
+
`tooltip` turns the floating box on (`true` for the defaults, or an object
|
|
17
|
+
to tune it); a `hover` marker draws the in-plot crosshair, dot and label.
|
|
18
|
+
-->
|
|
19
|
+
<LinePlot
|
|
20
|
+
width={720}
|
|
21
|
+
height={400}
|
|
22
|
+
data={REGION_VALUES}
|
|
23
|
+
x="date"
|
|
24
|
+
y="value"
|
|
25
|
+
color="region"
|
|
26
|
+
tooltip={{ strategy: 'x', format: (row) => `${row.region}: ${row.value}` }}
|
|
27
|
+
markers={[{ type: 'hover' }]}
|
|
28
|
+
/>
|
|
9
29
|
```
|
|
10
30
|
|
|
31
|
+
<!-- /example -->
|
|
32
|
+
|
|
11
33
|

|
|
12
34
|
|
|
13
35
|
`tooltip` is `true` for the defaults, or an options object:
|
|
14
36
|
|
|
15
|
-
| Option | Meaning
|
|
16
|
-
| -------------------- |
|
|
17
|
-
| `strategy` | How related points are found: `'x'`, `'y'`, `'punctual'` (the exact point) or `'series'` (all points of the hovered series). Defaults per plot kind
|
|
18
|
-
| `sync` | Show the highlight in every synced plot too (default `false`)
|
|
19
|
-
| `format` | `(row) => string` - the tooltip text for the hovered row (`\n` breaks lines)
|
|
20
|
-
| `content` | A snippet `{#snippet content({ rows })}` replacing the text with custom markup. It is drawn in a plain card, so the markup brings its own background, colors and spacing
|
|
21
|
-
| `series` | Only these series appear in the tooltip
|
|
22
|
-
| `anchorX`, `anchorY` | Preferred side of the cursor: `'left' \| 'middle' \| 'right'` (default `'right'`) and `'top' \| 'middle' \| 'bottom'` (default `'bottom'`). It moves to the other side when it would overflow
|
|
37
|
+
| Option | Meaning |
|
|
38
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| `strategy` | How related points are found: `'x'`, `'y'`, `'punctual'` (the exact point) or `'series'` (all points of the hovered series). Defaults per plot kind |
|
|
40
|
+
| `sync` | Show the highlight in every synced plot too (default `false`) |
|
|
41
|
+
| `format` | `(row) => string` - the tooltip text for the hovered row (`\n` breaks lines). With several rows, they read from the highest value to the lowest (a stacked row by its own value) |
|
|
42
|
+
| `content` | A snippet `{#snippet content({ rows })}` replacing the text with custom markup. It gets the rows as the hover matched them, unsorted, and is drawn in a plain card, so the markup brings its own order, background, colors and spacing |
|
|
43
|
+
| `series` | Only these series appear in the tooltip |
|
|
44
|
+
| `anchorX`, `anchorY` | Preferred side of the cursor: `'left' \| 'middle' \| 'right'` (default `'right'`) and `'top' \| 'middle' \| 'bottom'` (default `'bottom'`). It moves to the other side when it would overflow |
|
|
45
|
+
|
|
46
|
+
<!-- example: examples/CustomTooltip.svelte -->
|
|
23
47
|
|
|
24
48
|
```svelte
|
|
25
|
-
|
|
49
|
+
<script lang="ts">
|
|
50
|
+
import { LinePlot, getConfiguration, paletteColor } from '@fundar/data-chart-telling';
|
|
51
|
+
import TooltipCard from './TooltipCard.svelte';
|
|
52
|
+
import { REGION_VALUES, type RegionRow } from './data';
|
|
53
|
+
|
|
54
|
+
const { palette } = getConfiguration();
|
|
55
|
+
const regions = [...new Set(REGION_VALUES.map((row) => row.region))];
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<!--
|
|
59
|
+
`content` replaces the tooltip text with your own markup, drawn in a plain
|
|
60
|
+
card: TooltipCard brings its own background, colors and spacing. It is given
|
|
61
|
+
every row the hover matched, in no particular order, so it sorts them itself;
|
|
62
|
+
series colors come from the configuration's palette.
|
|
63
|
+
-->
|
|
64
|
+
{#snippet content({ rows }: { rows: RegionRow[] })}
|
|
26
65
|
<TooltipCard
|
|
27
|
-
heading={
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
66
|
+
heading={rows[0].date.toLocaleDateString('en-US', {
|
|
67
|
+
month: 'long',
|
|
68
|
+
year: 'numeric',
|
|
69
|
+
timeZone: 'UTC'
|
|
70
|
+
})}
|
|
71
|
+
footer="Monthly inflation (%)"
|
|
72
|
+
entries={[...rows]
|
|
73
|
+
.sort((a, b) => b.value - a.value)
|
|
74
|
+
.map((row) => ({
|
|
75
|
+
label: row.region,
|
|
76
|
+
color: paletteColor(regions.indexOf(row.region), palette),
|
|
77
|
+
value: row.value,
|
|
78
|
+
display: String(row.value)
|
|
79
|
+
}))}
|
|
35
80
|
/>
|
|
36
81
|
{/snippet}
|
|
37
82
|
|
|
38
83
|
<LinePlot
|
|
39
|
-
{
|
|
40
|
-
{
|
|
41
|
-
data={
|
|
42
|
-
x="
|
|
84
|
+
width={720}
|
|
85
|
+
height={400}
|
|
86
|
+
data={REGION_VALUES}
|
|
87
|
+
x="date"
|
|
43
88
|
y="value"
|
|
44
89
|
color="region"
|
|
45
90
|
tooltip={{ strategy: 'x', content }}
|
|
91
|
+
markers={[{ type: 'hover' }]}
|
|
46
92
|
/>
|
|
47
93
|
```
|
|
48
94
|
|
|
49
|
-
|
|
95
|
+
<!-- /example -->
|
|
96
|
+
|
|
97
|
+

|
|
50
98
|
|
|
51
|
-
[examples/CustomTooltip.svelte](../examples/CustomTooltip.svelte)
|
|
99
|
+
This is [examples/CustomTooltip.svelte](../examples/CustomTooltip.svelte); the card is [examples/TooltipCard.svelte](../examples/TooltipCard.svelte).
|
|
52
100
|
|
|
53
101
|
The default strategy follows the plot's axes: it matches along the category (or index) axis - points sharing the hovered `x` when the value axis is vertical, sharing `y` when it is horizontal - and `punctual` (the exact point) on heatmaps and scatter plots.
|
|
54
102
|
|
|
@@ -6,33 +6,53 @@ Both derive rows from the data before drawing. A **transform** reshapes the rows
|
|
|
6
6
|
|
|
7
7
|
`transforms` is an array of flat objects: `type` picks the transform and the other fields are its channels and options, named as in [svelteplot's transforms](https://svelteplot.dev). It exists on a plot (it then runs once over all the plot's series) and on each [marker](markers.md) (over the marker's rows).
|
|
8
8
|
|
|
9
|
+
<!-- example: examples/StackedBars.svelte -->
|
|
10
|
+
|
|
9
11
|
```svelte
|
|
10
|
-
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { BarPlot } from '@fundar/data-chart-telling';
|
|
14
|
+
import { SEX_SHARES } from './data';
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<!-- Each sex's share of the population per census, stacked with `stackY` so a bar adds up to 100%. -->
|
|
11
18
|
<BarPlot
|
|
12
|
-
{
|
|
13
|
-
{
|
|
14
|
-
data={
|
|
15
|
-
x="
|
|
16
|
-
y="
|
|
19
|
+
width={720}
|
|
20
|
+
height={400}
|
|
21
|
+
data={SEX_SHARES}
|
|
22
|
+
x="year"
|
|
23
|
+
y="share"
|
|
17
24
|
color="sex"
|
|
18
25
|
transforms={[{ type: 'stackY' }]}
|
|
19
26
|
/>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
<!-- /example -->
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
<!-- example: examples/MovingAverage.svelte -->
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
```svelte
|
|
36
|
+
<script lang="ts">
|
|
37
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
38
|
+
import { PRICES } from './data';
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- A 6-month moving average, run on the plot's rows. -->
|
|
22
42
|
<LinePlot
|
|
23
|
-
{
|
|
24
|
-
{
|
|
25
|
-
data={
|
|
43
|
+
width={720}
|
|
44
|
+
height={400}
|
|
45
|
+
data={PRICES}
|
|
26
46
|
x="date"
|
|
27
47
|
y="index"
|
|
28
|
-
color="
|
|
48
|
+
color="commodity"
|
|
29
49
|
transforms={[{ type: 'windowY', k: 6, reduce: 'mean' }]}
|
|
30
50
|
/>
|
|
31
51
|
```
|
|
32
52
|
|
|
33
|
-
|
|
53
|
+
<!-- /example -->
|
|
34
54
|
|
|
35
|
-

|
|
36
56
|
|
|
37
57
|
| Family | `type` | Does |
|
|
38
58
|
| --------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -57,18 +77,28 @@ Bar stacking is always `stackY`, also for horizontal bars. A transform on a `His
|
|
|
57
77
|
|
|
58
78
|
`statistics` is an array of derived summaries drawn as extra marks. On a plot it computes one per series by default; on a marker it applies to that marker's own rows.
|
|
59
79
|
|
|
80
|
+
<!-- example: examples/Regression.svelte -->
|
|
81
|
+
|
|
60
82
|
```svelte
|
|
83
|
+
<script lang="ts">
|
|
84
|
+
import { ScatterPlot } from '@fundar/data-chart-telling';
|
|
85
|
+
import { COUNTRIES } from './data';
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<!-- A linear regression with its 95% confidence band. -->
|
|
61
89
|
<ScatterPlot
|
|
62
|
-
{
|
|
63
|
-
{
|
|
64
|
-
data={
|
|
90
|
+
width={720}
|
|
91
|
+
height={400}
|
|
92
|
+
data={COUNTRIES}
|
|
65
93
|
x="gdp"
|
|
66
94
|
y="life"
|
|
67
95
|
statistics={[{ type: 'regression', regressionType: 'linear', confidence: 0.95 }]}
|
|
68
96
|
/>
|
|
69
97
|
```
|
|
70
98
|
|
|
71
|
-
|
|
99
|
+
<!-- /example -->
|
|
100
|
+
|
|
101
|
+

|
|
72
102
|
|
|
73
103
|
| `type` | Draws | Options |
|
|
74
104
|
| --------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { BarPlot } from '@fundar/data-chart-telling';
|
|
3
|
-
import {
|
|
3
|
+
import { REGION_VALUES, MONTHS } from './data';
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<!-- Categories on x, values on y. Swap `x` and `y` for horizontal bars. -->
|
|
7
7
|
<BarPlot
|
|
8
8
|
width={720}
|
|
9
9
|
height={400}
|
|
10
|
-
data={
|
|
10
|
+
data={REGION_VALUES.filter((row) => row.date === MONTHS.at(-1))}
|
|
11
11
|
x="region"
|
|
12
12
|
y="value"
|
|
13
13
|
styles={{ values: { show: true, anchor: 'outside' } }}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { BoxPlot } from '@fundar/data-chart-telling';
|
|
3
|
+
import { HEIGHTS } from './data';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<!-- One box per group: quartiles, median, whiskers and outliers of each height distribution. -->
|
|
7
|
+
<BoxPlot width={720} height={400} data={HEIGHTS} x="group" y="height" color="group" />
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
3
|
+
import { PRICES } from './data';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<!-- A plot carries its own chrome: title, subtitle, legend and caption. -->
|
|
7
|
+
<LinePlot
|
|
8
|
+
width={720}
|
|
9
|
+
height={440}
|
|
10
|
+
title="Commodity prices"
|
|
11
|
+
subtitle="Price index, January 2021 = 100"
|
|
12
|
+
caption="Source: IMF, Primary Commodity Prices"
|
|
13
|
+
data={PRICES}
|
|
14
|
+
x="date"
|
|
15
|
+
y="index"
|
|
16
|
+
color="commodity"
|
|
17
|
+
/>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
3
|
+
import { PRICES } from './data';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<!-- `order` places the chrome blocks; `divider` draws a rule between them. -->
|
|
7
|
+
<LinePlot
|
|
8
|
+
width={720}
|
|
9
|
+
height={460}
|
|
10
|
+
title="Commodity prices"
|
|
11
|
+
subtitle="Price index"
|
|
12
|
+
caption="Source: IMF, Primary Commodity Prices"
|
|
13
|
+
data={PRICES}
|
|
14
|
+
x="date"
|
|
15
|
+
y="index"
|
|
16
|
+
color="commodity"
|
|
17
|
+
order={['title', 'subtitle', 'divider', 'legend', 'plot', 'divider', 'caption']}
|
|
18
|
+
/>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PlotComposer, LinePlot, BarPlot, ScatterPlot } from '@fundar/data-chart-telling';
|
|
3
|
+
import { REGION_VALUES, PROVINCE_VALUES, COUNTRIES } from './data';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<!-- Several plots in one figure, placed on named areas of a grid. -->
|
|
7
|
+
<PlotComposer
|
|
8
|
+
width={900}
|
|
9
|
+
height={560}
|
|
10
|
+
title="Three views, one figure"
|
|
11
|
+
legend={false}
|
|
12
|
+
tags="A"
|
|
13
|
+
layout={{ areas: ['a a b', 'a a c'] }}
|
|
14
|
+
>
|
|
15
|
+
<LinePlot area="a" data={REGION_VALUES} x="date" y="value" color="region" tooltip />
|
|
16
|
+
<BarPlot
|
|
17
|
+
area="b"
|
|
18
|
+
data={PROVINCE_VALUES.filter((row) => row.sex === 'female').slice(0, 3)}
|
|
19
|
+
x="province"
|
|
20
|
+
y="value"
|
|
21
|
+
/>
|
|
22
|
+
<ScatterPlot area="c" data={COUNTRIES} x="gdp" y="life" />
|
|
23
|
+
</PlotComposer>
|
|
@@ -1,35 +1,42 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { LinePlot, getConfiguration, paletteColor } from '@fundar/data-chart-telling';
|
|
3
3
|
import TooltipCard from './TooltipCard.svelte';
|
|
4
|
-
import {
|
|
4
|
+
import { REGION_VALUES, type RegionRow } from './data';
|
|
5
5
|
|
|
6
6
|
const { palette } = getConfiguration();
|
|
7
|
-
const regions = [...new Set(
|
|
7
|
+
const regions = [...new Set(REGION_VALUES.map((row) => row.region))];
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<!--
|
|
11
11
|
`content` replaces the tooltip text with your own markup, drawn in a plain
|
|
12
12
|
card: TooltipCard brings its own background, colors and spacing. It is given
|
|
13
|
-
every row the hover matched
|
|
13
|
+
every row the hover matched, in no particular order, so it sorts them itself;
|
|
14
|
+
series colors come from the configuration's palette.
|
|
14
15
|
-->
|
|
15
|
-
{#snippet content({ rows }: { rows:
|
|
16
|
+
{#snippet content({ rows }: { rows: RegionRow[] })}
|
|
16
17
|
<TooltipCard
|
|
17
|
-
heading={
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
heading={rows[0].date.toLocaleDateString('en-US', {
|
|
19
|
+
month: 'long',
|
|
20
|
+
year: 'numeric',
|
|
21
|
+
timeZone: 'UTC'
|
|
22
|
+
})}
|
|
23
|
+
footer="Monthly inflation (%)"
|
|
24
|
+
entries={[...rows]
|
|
25
|
+
.sort((a, b) => b.value - a.value)
|
|
26
|
+
.map((row) => ({
|
|
27
|
+
label: row.region,
|
|
28
|
+
color: paletteColor(regions.indexOf(row.region), palette),
|
|
29
|
+
value: row.value,
|
|
30
|
+
display: String(row.value)
|
|
31
|
+
}))}
|
|
25
32
|
/>
|
|
26
33
|
{/snippet}
|
|
27
34
|
|
|
28
35
|
<LinePlot
|
|
29
36
|
width={720}
|
|
30
37
|
height={400}
|
|
31
|
-
data={
|
|
32
|
-
x="
|
|
38
|
+
data={REGION_VALUES}
|
|
39
|
+
x="date"
|
|
33
40
|
y="value"
|
|
34
41
|
color="region"
|
|
35
42
|
tooltip={{ strategy: 'x', content }}
|
package/examples/Facets.svelte
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { LinePlot } from '@fundar/data-chart-telling';
|
|
3
|
-
import {
|
|
3
|
+
import { REGION_VALUES } from './data';
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<!-- One panel per region, three columns, sharing scales. A tooltip with `sync` shows in every panel on purpose. -->
|
|
7
7
|
<LinePlot
|
|
8
8
|
width={900}
|
|
9
9
|
height={360}
|
|
10
|
-
data={
|
|
11
|
-
x="
|
|
10
|
+
data={REGION_VALUES}
|
|
11
|
+
x="date"
|
|
12
12
|
y="value"
|
|
13
13
|
facet={{ by: 'region', columns: 3, gap: 12, scales: 'shared' }}
|
|
14
14
|
tooltip={{ sync: true }}
|