@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/plots.md
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
# Plots
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
| Plot | Draws
|
|
6
|
-
| --------------------------------- |
|
|
7
|
-
| [`LinePlot`](#lineplot) | A line per series
|
|
8
|
-
| [`AreaPlot`](#areaplot) | A filled area per series
|
|
9
|
-
| [`BarPlot`](#barplot) | Bars, grouped, stacked or horizontal
|
|
10
|
-
| [`HistogramPlot`](#histogramplot) | Counts of a numeric field in bins
|
|
11
|
-
| [`
|
|
12
|
-
| [`
|
|
13
|
-
| [`
|
|
14
|
-
| [`
|
|
3
|
+
Nine plot kinds share one set of props (see [Concepts](concepts.md)). They differ in what they draw, which channels they need and how they hover.
|
|
4
|
+
|
|
5
|
+
| Plot | Draws | Needs |
|
|
6
|
+
| --------------------------------- | --------------------------------------- | ----------------------------------------------- |
|
|
7
|
+
| [`LinePlot`](#lineplot) | A line per series | `x`, `y` |
|
|
8
|
+
| [`AreaPlot`](#areaplot) | A filled area per series | `x`, `y` |
|
|
9
|
+
| [`BarPlot`](#barplot) | Bars, grouped, stacked or horizontal | a category channel and a value channel |
|
|
10
|
+
| [`HistogramPlot`](#histogramplot) | Counts of a numeric field in bins | `x` or `y` |
|
|
11
|
+
| [`BoxPlot`](#boxplot) | The distribution of values per category | a category channel and a value channel |
|
|
12
|
+
| [`HeatmapPlot`](#heatmapplot) | A grid of colored cells | `x`, `y`, `color` |
|
|
13
|
+
| [`PyramidPlot`](#pyramidplot) | Two series mirrored around zero | a category channel, a value channel, two series |
|
|
14
|
+
| [`ScatterPlot`](#scatterplot) | A point per row | `x`, `y` |
|
|
15
|
+
| [`GeoPlot`](#geoplot) | A map from GeoJSON or TopoJSON | `data` (see [Maps](geo.md)) |
|
|
15
16
|
|
|
16
17
|
All of them accept `data` with `grouping`/`color`, or pre-built `series`.
|
|
17
18
|
|
|
@@ -19,19 +20,29 @@ All of them accept `data` with `grouping`/`color`, or pre-built `series`.
|
|
|
19
20
|
|
|
20
21
|
One line per series. Rows with a missing value (`null`, `undefined`, `NaN`) break the line; `styles.gaps` can [bridge the break](styles-and-segments.md#gaps).
|
|
21
22
|
|
|
23
|
+
<!-- example: examples/LineDates.svelte -->
|
|
24
|
+
|
|
22
25
|
```svelte
|
|
26
|
+
<script lang="ts">
|
|
27
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
28
|
+
import { PRICES } from './data';
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<!-- A line per commodity over a date axis, with end-of-line labels. -->
|
|
23
32
|
<LinePlot
|
|
24
|
-
{
|
|
25
|
-
{
|
|
26
|
-
data={
|
|
33
|
+
width={720}
|
|
34
|
+
height={400}
|
|
35
|
+
data={PRICES}
|
|
27
36
|
x="date"
|
|
28
37
|
y="index"
|
|
29
|
-
color="
|
|
38
|
+
color="commodity"
|
|
30
39
|
styles={{ values: { show: true, format: (v, name) => `${name}: ${v}` } }}
|
|
31
40
|
/>
|
|
32
41
|
```
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
<!-- /example -->
|
|
44
|
+
|
|
45
|
+

|
|
35
46
|
|
|
36
47
|
- `styles.values.show` writes a label at the end of each series, with the series name and value. Overlapping labels spread apart automatically and the margin grows to fit them.
|
|
37
48
|
- Hover finds the points sharing the hovered `x`.
|
|
@@ -42,19 +53,30 @@ One line per series. Rows with a missing value (`null`, `undefined`, `NaN`) brea
|
|
|
42
53
|
|
|
43
54
|
One filled area per series, under the line from `y` to the baseline. Default fill opacity comes from `area.fillOpacity` in the configuration.
|
|
44
55
|
|
|
56
|
+
<!-- example: examples/StackedArea.svelte -->
|
|
57
|
+
|
|
45
58
|
```svelte
|
|
59
|
+
<script lang="ts">
|
|
60
|
+
import { AreaPlot } from '@fundar/data-chart-telling';
|
|
61
|
+
import { AGE_SHARES } from './data';
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<!-- Each age group's share of the population, stacked with `stackY` so the bands add up to 100%. -->
|
|
46
65
|
<AreaPlot
|
|
47
|
-
{
|
|
48
|
-
{
|
|
49
|
-
data={
|
|
66
|
+
width={720}
|
|
67
|
+
height={400}
|
|
68
|
+
data={AGE_SHARES}
|
|
50
69
|
x="year"
|
|
51
|
-
y="
|
|
52
|
-
color="
|
|
70
|
+
y="share"
|
|
71
|
+
color="ageGroup"
|
|
72
|
+
scales={{ x: { ticks: [1991, 2001, 2010, 2022] } }}
|
|
53
73
|
transforms={[{ type: 'stackY' }]}
|
|
54
74
|
/>
|
|
55
75
|
```
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
<!-- /example -->
|
|
78
|
+
|
|
79
|
+

|
|
58
80
|
|
|
59
81
|
`transforms={[{ type: 'stackY' }]}` stacks the series.
|
|
60
82
|
|
|
@@ -62,16 +84,53 @@ One filled area per series, under the line from `y` to the baseline. Default fil
|
|
|
62
84
|
|
|
63
85
|
Bars where one axis holds the categories and the other the values. Categories on `x` give vertical bars; categories on `y` give horizontal bars.
|
|
64
86
|
|
|
87
|
+
<!-- example: examples/GroupedBars.svelte -->
|
|
88
|
+
|
|
89
|
+
```svelte
|
|
90
|
+
<script lang="ts">
|
|
91
|
+
import { BarPlot } from '@fundar/data-chart-telling';
|
|
92
|
+
import { PROVINCE_VALUES } from './data';
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<!-- Vertical bars, grouped by `color`. -->
|
|
96
|
+
<BarPlot
|
|
97
|
+
width={720}
|
|
98
|
+
height={400}
|
|
99
|
+
data={PROVINCE_VALUES}
|
|
100
|
+
x="province"
|
|
101
|
+
y="value"
|
|
102
|
+
color="sex"
|
|
103
|
+
scales={{ y: { domain: [70, 85] } }}
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
<!-- /example -->
|
|
108
|
+
|
|
109
|
+

|
|
110
|
+
|
|
111
|
+
<!-- example: examples/HorizontalBars.svelte -->
|
|
112
|
+
|
|
65
113
|
```svelte
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
114
|
+
<script lang="ts">
|
|
115
|
+
import { BarPlot } from '@fundar/data-chart-telling';
|
|
116
|
+
import { PROVINCE_VALUES } from './data';
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
<!-- Horizontal bars: the categories go on `y`, the values on `x`. -->
|
|
120
|
+
<BarPlot
|
|
121
|
+
width={720}
|
|
122
|
+
height={400}
|
|
123
|
+
data={PROVINCE_VALUES}
|
|
124
|
+
x="value"
|
|
125
|
+
y="province"
|
|
126
|
+
color="sex"
|
|
127
|
+
scales={{ x: { domain: [70, 85] } }}
|
|
128
|
+
/>
|
|
70
129
|
```
|
|
71
130
|
|
|
72
|
-
|
|
131
|
+
<!-- /example -->
|
|
73
132
|
|
|
74
|
-

|
|
75
134
|
|
|
76
135
|
- Several series sharing a category sit side by side, each in its slice of the category band. The gap between them is `bar.seriesPadding` in the configuration.
|
|
77
136
|
- `transforms={[{ type: 'stackY' }]}` stacks the series instead. Stacking is always `stackY`, also for horizontal bars, because the value channel is the one stacked.
|
|
@@ -83,33 +142,80 @@ Bars where one axis holds the categories and the other the values. Categories on
|
|
|
83
142
|
|
|
84
143
|
Bins the rows of each series along one axis and draws the count per bin. Give `x` alone for vertical bars or `y` alone for horizontal bars.
|
|
85
144
|
|
|
145
|
+
<!-- example: examples/Histogram.svelte -->
|
|
146
|
+
|
|
86
147
|
```svelte
|
|
148
|
+
<script lang="ts">
|
|
149
|
+
import { HistogramPlot } from '@fundar/data-chart-telling';
|
|
150
|
+
import { HEIGHTS } from './data';
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<!-- Two overlapping distributions, one per `grouping` value. -->
|
|
87
154
|
<HistogramPlot
|
|
88
|
-
{
|
|
89
|
-
{
|
|
90
|
-
data={
|
|
91
|
-
x="
|
|
155
|
+
width={720}
|
|
156
|
+
height={400}
|
|
157
|
+
data={HEIGHTS}
|
|
158
|
+
x="height"
|
|
92
159
|
grouping="group"
|
|
93
160
|
segments={{ default: [{ styles: { fillOpacity: 0.7 } }] }}
|
|
94
161
|
/>
|
|
95
162
|
```
|
|
96
163
|
|
|
97
|
-
|
|
164
|
+
<!-- /example -->
|
|
165
|
+
|
|
166
|
+

|
|
98
167
|
|
|
99
168
|
- `grouping` (or `color`) draws one histogram per group.
|
|
100
169
|
- Override the default binning with a `binX` (or `binY`) transform: `transforms={[{ type: 'binX', thresholds: 20 }]}`. A transform given here is merged over the default one.
|
|
101
170
|
- `transforms={[{ type: 'stackY' }]}` stacks groups in each bin.
|
|
102
171
|
- `segments={{ default: [{ styles: { fillOpacity: 0.7 } }] }}` makes overlapping groups translucent.
|
|
103
172
|
|
|
173
|
+
## BoxPlot
|
|
174
|
+
|
|
175
|
+
Summarizes the values of each series per category as a box: it spans the middle half of the values (25th to 75th percentile), the line across it is the median, the whiskers reach the farthest values within 1.5 times the box's height, and dots mark the values past them. String values on `x` stand the boxes upright; on `y` they lie sideways.
|
|
176
|
+
|
|
177
|
+
<!-- example: examples/Box.svelte -->
|
|
178
|
+
|
|
179
|
+
```svelte
|
|
180
|
+
<script lang="ts">
|
|
181
|
+
import { BoxPlot } from '@fundar/data-chart-telling';
|
|
182
|
+
import { HEIGHTS } from './data';
|
|
183
|
+
</script>
|
|
184
|
+
|
|
185
|
+
<!-- One box per group: quartiles, median, whiskers and outliers of each height distribution. -->
|
|
186
|
+
<BoxPlot width={720} height={400} data={HEIGHTS} x="group" y="height" color="group" />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
<!-- /example -->
|
|
190
|
+
|
|
191
|
+

|
|
192
|
+
|
|
193
|
+
- `grouping` (or `color`) draws one box per group and category. Groups that share categories draw their boxes on top of each other, so split them with `facet` instead, or color by the category field itself.
|
|
194
|
+
- Categories keep the order the data gives them; `scales.x.domain` (or `y`) orders them.
|
|
195
|
+
- The value axis fits the values without reaching for zero; pin `scales.y.domain` to start it at zero.
|
|
196
|
+
- `scales.x.paddingInner` / `paddingOuter` set how wide the boxes are; the defaults come from `box` in the [configuration](theming.md).
|
|
197
|
+
- The tooltip reads one box at a time, not every value inside it: the hovered row carries `category`, `min`, `p25`, `median`, `p75`, `max`, `count` and `outliers`.
|
|
198
|
+
- `segments` restyle whole categories (`areas: [{ x: { from: 'Bus', to: 'Bus' } }]`). A segment that splits one category's values draws two boxes.
|
|
199
|
+
|
|
104
200
|
## HeatmapPlot
|
|
105
201
|
|
|
106
202
|
A grid of cells, `x` and `y` being the categories of the columns and rows and `color` the value that colors each cell.
|
|
107
203
|
|
|
204
|
+
<!-- example: examples/Heatmap.svelte -->
|
|
205
|
+
|
|
108
206
|
```svelte
|
|
109
|
-
<
|
|
207
|
+
<script lang="ts">
|
|
208
|
+
import { HeatmapPlot } from '@fundar/data-chart-telling';
|
|
209
|
+
import { HOUSEHOLDS } from './data';
|
|
210
|
+
</script>
|
|
211
|
+
|
|
212
|
+
<!-- One cell per number of rooms and of people, colored by the share of households. -->
|
|
213
|
+
<HeatmapPlot width={560} height={360} data={HOUSEHOLDS} x="rooms" y="people" color="share" />
|
|
110
214
|
```
|
|
111
215
|
|
|
112
|
-
|
|
216
|
+
<!-- /example -->
|
|
217
|
+
|
|
218
|
+

|
|
113
219
|
|
|
114
220
|
- The color domain spans the whole dataset, so it stays comparable across [facets](facets.md).
|
|
115
221
|
- Cell value labels are on by default (`styles.values.show` turns them off).
|
|
@@ -120,11 +226,21 @@ A grid of cells, `x` and `y` being the categories of the columns and rows and `c
|
|
|
120
226
|
|
|
121
227
|
Two series mirrored around a shared zero baseline, such as a population pyramid. Categories on `y` give horizontal bars; categories on `x` give vertical ones.
|
|
122
228
|
|
|
229
|
+
<!-- example: examples/Pyramid.svelte -->
|
|
230
|
+
|
|
123
231
|
```svelte
|
|
124
|
-
<
|
|
232
|
+
<script lang="ts">
|
|
233
|
+
import { PyramidPlot } from '@fundar/data-chart-telling';
|
|
234
|
+
import { AGES } from './data';
|
|
235
|
+
</script>
|
|
236
|
+
|
|
237
|
+
<!-- A population pyramid: one side per `color` value. -->
|
|
238
|
+
<PyramidPlot width={720} height={400} data={AGES} x="share" y="ageGroup" color="sex" />
|
|
125
239
|
```
|
|
126
240
|
|
|
127
|
-
|
|
241
|
+
<!-- /example -->
|
|
242
|
+
|
|
243
|
+

|
|
128
244
|
|
|
129
245
|
- `scales.grouping.reverse` swaps which series sits on which side.
|
|
130
246
|
- Hover finds the points sharing the hovered category.
|
|
@@ -133,11 +249,19 @@ Two series mirrored around a shared zero baseline, such as a population pyramid.
|
|
|
133
249
|
|
|
134
250
|
A dot per row.
|
|
135
251
|
|
|
252
|
+
<!-- example: examples/Scatter.svelte -->
|
|
253
|
+
|
|
136
254
|
```svelte
|
|
255
|
+
<script lang="ts">
|
|
256
|
+
import { ScatterPlot } from '@fundar/data-chart-telling';
|
|
257
|
+
import { COUNTRIES } from './data';
|
|
258
|
+
</script>
|
|
259
|
+
|
|
260
|
+
<!-- Points sized by `r`, colored by `color` and shaped by `symbol`. -->
|
|
137
261
|
<ScatterPlot
|
|
138
|
-
{
|
|
139
|
-
{
|
|
140
|
-
data={
|
|
262
|
+
width={720}
|
|
263
|
+
height={420}
|
|
264
|
+
data={COUNTRIES}
|
|
141
265
|
x="gdp"
|
|
142
266
|
y="life"
|
|
143
267
|
r="population"
|
|
@@ -146,7 +270,9 @@ A dot per row.
|
|
|
146
270
|
/>
|
|
147
271
|
```
|
|
148
272
|
|
|
149
|
-
|
|
273
|
+
<!-- /example -->
|
|
274
|
+
|
|
275
|
+

|
|
150
276
|
|
|
151
277
|
- `r` sizes the dots (area follows the value; configure with `scales.r`). The legend gets a size section.
|
|
152
278
|
- `symbol` varies the dot shape by category (`scales.symbol`), `opacity` varies transparency, `color` colors by category or by a continuous ramp.
|
package/docs/scales.md
CHANGED
|
@@ -2,43 +2,60 @@
|
|
|
2
2
|
|
|
3
3
|
`scales` configures how data values become positions and visual properties. It has one entry per channel.
|
|
4
4
|
|
|
5
|
+
<!-- example: examples/Scales.svelte -->
|
|
6
|
+
|
|
5
7
|
```svelte
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
10
|
+
import { PRICES } from './data';
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!-- Axis labels, a fixed domain with gridlines and a color per series. -->
|
|
6
14
|
<LinePlot
|
|
7
|
-
{
|
|
8
|
-
{
|
|
9
|
-
data={
|
|
15
|
+
width={720}
|
|
16
|
+
height={400}
|
|
17
|
+
data={PRICES}
|
|
10
18
|
x="date"
|
|
11
19
|
y="index"
|
|
12
|
-
color="
|
|
20
|
+
color="commodity"
|
|
13
21
|
scales={{
|
|
14
22
|
x: { label: 'Month' },
|
|
15
|
-
y: { label: 'Index (Jan 2021 = 100)', domain: [
|
|
23
|
+
y: { label: 'Index (Jan 2021 = 100)', domain: [0, 600], grid: true },
|
|
16
24
|
color: {
|
|
17
|
-
scheme: {
|
|
25
|
+
scheme: {
|
|
26
|
+
'Brent oil': '#1b9e77',
|
|
27
|
+
'Natural gas': '#d95f02',
|
|
28
|
+
Coal: '#7570b3',
|
|
29
|
+
Wheat: '#e7298a'
|
|
30
|
+
}
|
|
18
31
|
}
|
|
19
32
|
}}
|
|
20
33
|
/>
|
|
21
34
|
```
|
|
22
35
|
|
|
36
|
+
<!-- /example -->
|
|
37
|
+
|
|
23
38
|

|
|
24
39
|
|
|
25
40
|
## Axes: `x` and `y`
|
|
26
41
|
|
|
27
42
|
Each axis takes an `AxisScale`.
|
|
28
43
|
|
|
29
|
-
| Field | Meaning
|
|
30
|
-
| ---------------------------------------------------------------------------- |
|
|
31
|
-
| `type` | `'auto'` (default), `'linear'`, `'pow'`, `'sqrt'`, `'log'`, `'symlog'`, `'time'`, `'utc'`, `'band'`, `'point'`, `'ordinal'`, `'categorical'` and the color-oriented types (`'sequential'`, `'diverging'`, `'threshold'`, ...)
|
|
32
|
-
| `domain`, `range` | Explicit input and output extent
|
|
33
|
-
| `reverse`, `nice`, `zero`, `clamp`, `round`, `percent` | Direction, rounding and baseline behaviour
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
44
|
+
| Field | Meaning |
|
|
45
|
+
| ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
46
|
+
| `type` | `'auto'` (default), `'linear'`, `'pow'`, `'sqrt'`, `'log'`, `'symlog'`, `'time'`, `'utc'`, `'band'`, `'point'`, `'ordinal'`, `'categorical'` and the color-oriented types (`'sequential'`, `'diverging'`, `'threshold'`, ...) |
|
|
47
|
+
| `domain`, `range` | Explicit input and output extent |
|
|
48
|
+
| `reverse`, `nice`, `zero`, `clamp`, `round`, `percent` | Direction, rounding and baseline behaviour |
|
|
49
|
+
| `niceTolerance` | How far past a tick, as a share of the step, a domain the plot nices itself still ends on it (default `0.05`), so parts adding up to `100.2` stay at `100`. Applies to stacked and ranged axes, axes grown to cover markers or a transform's output, a bar plot's value axis and shared facet/timeline domains; `0` rounds like d3 |
|
|
50
|
+
| `edgeTicks` | Ticks at the data's first and last values beside the nice ones. `false` turns them off, `true` on, `{ collision: 'drop-nice' \| 'drop-edge' \| 'extend' }` picks what happens when one crowds a nice tick. Defaults to `axis.edgeTicks.x` / `.y` in the [configuration](theming.md#edge-ticks) (on for x, off for y); ignored when the axis sets `ticks`, `tickSpacing`, `interval` or `domain` |
|
|
51
|
+
| `label`, `labelAnchor`, `labelOrientation`, `labelPosition`, `titleFontSize` | The axis title (`label: false` hides it) |
|
|
52
|
+
| `ticks`, `tickSpacing`, `tickSize`, `tickPadding`, `tickRotate` | Tick placement and size |
|
|
53
|
+
| `tickFormat` | `false`, an `Intl.NumberFormatOptions` / `Intl.DateTimeFormatOptions` object, or `(d, index, ticks) => string` |
|
|
54
|
+
| `grid` | `true` or a stroke style for gridlines |
|
|
55
|
+
| `axisDisplay` | `'visible'` (default), `'hidden'` (keeps the space, so aligned panels stay aligned) or `'none'` |
|
|
56
|
+
| `padding`, `paddingInner`, `paddingOuter`, `align` | Band and point spacing |
|
|
57
|
+
| `insetLeft`, `insetRight`, `insetTop`, `insetBottom` | Pixels kept free at each end |
|
|
58
|
+
| `interval`, `base`, `constant`, `sort` | Time/discrete intervals, log base, symlog constant, category order |
|
|
42
59
|
|
|
43
60
|
Number and date text defaults follow `axis.locale` and `axis.compactDisplay` in the [configuration](theming.md#locale).
|
|
44
61
|
|
package/docs/state.md
CHANGED
|
@@ -8,7 +8,7 @@ Works anywhere inside a figure, including the `header`, `footer` and `content` s
|
|
|
8
8
|
|
|
9
9
|
- `hover` - `activeX`, `activeY`, `activeSeries`, `strategy`, `sync`, `source` (the id of the plot owning the hover).
|
|
10
10
|
- `legend` (or `null`) - `entries`, `range`, `off` (names of hidden series), `isOff(name)`, `turnOff(name, action)`, `turnOn(name)`, `toggle(name, action)`. `action` is `{ mode: 'dim' | 'hide' | 'omit' }`; `'omit'` removes the series and refits the axes.
|
|
11
|
-
- `timeline` (or `null`) - `enabled`, `steps`, `value`, `index`, `progress`, `playing`, `loop`, `speed`, `speeds`, `controls`, and `seek`, `seekIndex`, `seekValue`, `next`, `previous`, `play`, `pause`, `toggle`, `setLoop`, `setSpeed`, `cycleSpeed`.
|
|
11
|
+
- `timeline` (or `null`) - `enabled`, `steps`, `value`, `index`, `progress`, `playing`, `loop`, `speed`, `speeds`, `controls`, 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.
|
|
12
12
|
|
|
13
13
|
A footer that toggles series through the legend:
|
|
14
14
|
|
|
@@ -16,14 +16,22 @@
|
|
|
16
16
|
|
|
17
17
|
### Value labels
|
|
18
18
|
|
|
19
|
+
<!-- example: examples/ValueLabels.svelte -->
|
|
20
|
+
|
|
19
21
|
```svelte
|
|
22
|
+
<script lang="ts">
|
|
23
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
24
|
+
import { PRICES } from './data';
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<!-- End-of-line value labels with a custom format and font size. -->
|
|
20
28
|
<LinePlot
|
|
21
|
-
{
|
|
22
|
-
{
|
|
23
|
-
data={
|
|
29
|
+
width={720}
|
|
30
|
+
height={400}
|
|
31
|
+
data={PRICES}
|
|
24
32
|
x="date"
|
|
25
33
|
y="index"
|
|
26
|
-
color="
|
|
34
|
+
color="commodity"
|
|
27
35
|
styles={{
|
|
28
36
|
values: {
|
|
29
37
|
show: true,
|
|
@@ -34,7 +42,9 @@
|
|
|
34
42
|
/>
|
|
35
43
|
```
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
<!-- /example -->
|
|
46
|
+
|
|
47
|
+

|
|
38
48
|
|
|
39
49
|
| Field | Meaning |
|
|
40
50
|
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -55,24 +65,35 @@ Where the labels go depends on the plot: the end of each series on a line or are
|
|
|
55
65
|
|
|
56
66
|
A row whose value is `null`, `undefined` or `NaN` breaks a line. `styles.gaps` bridges the break with a distinct, interpolated stretch. It is keyed by series name, or `'default'` for the series with no entry of their own, and has three zones: `start` (before the first real point), `middle` and `end` (after the last).
|
|
57
67
|
|
|
68
|
+
<!-- example: examples/Gaps.svelte -->
|
|
69
|
+
|
|
58
70
|
```svelte
|
|
71
|
+
<script lang="ts">
|
|
72
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
73
|
+
import { LIFE_GAPS } from './data';
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<!-- Missing values bridged: dashed in the middle, faded at the start, extended to the 2025 projection at the end. -->
|
|
59
77
|
<LinePlot
|
|
60
|
-
{
|
|
61
|
-
{
|
|
62
|
-
series={[{ name: 'female', x: 'year', y: 'value', data:
|
|
78
|
+
width={720}
|
|
79
|
+
height={400}
|
|
80
|
+
series={[{ name: 'female', x: 'year', y: 'value', data: LIFE_GAPS }]}
|
|
81
|
+
scales={{ x: { edgeTicks: true }, y: { domain: [55, 85] } }}
|
|
63
82
|
styles={{
|
|
64
83
|
gaps: {
|
|
65
84
|
default: {
|
|
66
85
|
middle: { interpolate: 'linear', style: { stroke: { strokeDasharray: '4 4' } } },
|
|
67
|
-
start: { x:
|
|
68
|
-
end: { x:
|
|
86
|
+
start: { x: 1940, style: { stroke: { strokeOpacity: 0.4 } } },
|
|
87
|
+
end: { x: 2025, y: 81.1 }
|
|
69
88
|
}
|
|
70
89
|
}
|
|
71
90
|
}}
|
|
72
91
|
/>
|
|
73
92
|
```
|
|
74
93
|
|
|
75
|
-
|
|
94
|
+
<!-- /example -->
|
|
95
|
+
|
|
96
|
+

|
|
76
97
|
|
|
77
98
|
- `middle` bridges holes between real points, `interpolate` is an easing name (default `'linear'`).
|
|
78
99
|
- `start` and `end` reach out to the given `x` (required to fill the zone), landing on `y` there (default: the nearest real value).
|
|
@@ -111,16 +132,26 @@ The style shape depends on the plot:
|
|
|
111
132
|
|
|
112
133
|
A baseline color with a highlighted range:
|
|
113
134
|
|
|
135
|
+
<!-- example: examples/SegmentHighlight.svelte -->
|
|
136
|
+
|
|
114
137
|
```svelte
|
|
138
|
+
<script lang="ts">
|
|
139
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
140
|
+
import { REGION_VALUES } from './data';
|
|
141
|
+
|
|
142
|
+
const gba = REGION_VALUES.filter((row) => row.region === 'GBA');
|
|
143
|
+
</script>
|
|
144
|
+
|
|
145
|
+
<!-- A grey line with the 2023-2024 surge drawn in red. -->
|
|
115
146
|
<LinePlot
|
|
116
|
-
{
|
|
117
|
-
{
|
|
118
|
-
series={[{ name: '
|
|
147
|
+
width={720}
|
|
148
|
+
height={380}
|
|
149
|
+
series={[{ name: 'GBA', x: 'date', y: 'value', data: gba }]}
|
|
119
150
|
segments={{
|
|
120
|
-
|
|
151
|
+
GBA: [
|
|
121
152
|
{ styles: { stroke: { stroke: '#94a3b8', strokeWidth: 1 } } },
|
|
122
153
|
{
|
|
123
|
-
areas: [{ x: { from:
|
|
154
|
+
areas: [{ x: { from: new Date('2023-07-01'), to: new Date('2024-03-01') } }],
|
|
124
155
|
styles: { stroke: { stroke: '#ef4444', strokeWidth: 3 } }
|
|
125
156
|
}
|
|
126
157
|
]
|
|
@@ -128,24 +159,35 @@ A baseline color with a highlighted range:
|
|
|
128
159
|
/>
|
|
129
160
|
```
|
|
130
161
|
|
|
131
|
-
|
|
162
|
+
<!-- /example -->
|
|
163
|
+
|
|
164
|
+

|
|
132
165
|
|
|
133
166
|
Per-series colors, plus dots over a range shared by every series:
|
|
134
167
|
|
|
168
|
+
<!-- example: examples/SegmentsBySeries.svelte -->
|
|
169
|
+
|
|
135
170
|
```svelte
|
|
171
|
+
<script lang="ts">
|
|
172
|
+
import { LinePlot } from '@fundar/data-chart-telling';
|
|
173
|
+
import { LIFE } from './data';
|
|
174
|
+
</script>
|
|
175
|
+
|
|
176
|
+
<!-- Segments per series name, plus `default` for rules shared by every series. -->
|
|
136
177
|
<LinePlot
|
|
137
|
-
{
|
|
138
|
-
{
|
|
139
|
-
data={
|
|
178
|
+
width={720}
|
|
179
|
+
height={380}
|
|
180
|
+
data={LIFE}
|
|
140
181
|
x="year"
|
|
141
182
|
y="value"
|
|
142
183
|
color="sex"
|
|
184
|
+
scales={{ x: { edgeTicks: true } }}
|
|
143
185
|
segments={{
|
|
144
186
|
female: [{ styles: { stroke: { stroke: 'steelblue' } } }],
|
|
145
187
|
male: [{ styles: { stroke: { stroke: 'tomato' } } }],
|
|
146
188
|
default: [
|
|
147
189
|
{
|
|
148
|
-
areas: [{ x: { from:
|
|
190
|
+
areas: [{ x: { from: 1965, to: 1980 } }],
|
|
149
191
|
styles: { dots: { dotRadius: 5, dotSymbol: 'circle' } }
|
|
150
192
|
}
|
|
151
193
|
]
|
|
@@ -153,7 +195,9 @@ Per-series colors, plus dots over a range shared by every series:
|
|
|
153
195
|
/>
|
|
154
196
|
```
|
|
155
197
|
|
|
156
|
-
|
|
198
|
+
<!-- /example -->
|
|
199
|
+
|
|
200
|
+

|
|
157
201
|
|
|
158
202
|
Two areas in one segment, the second with a `y` limit:
|
|
159
203
|
|
|
@@ -169,22 +213,30 @@ Two areas in one segment, the second with a `y` limit:
|
|
|
169
213
|
|
|
170
214
|
Heatmap columns and cells:
|
|
171
215
|
|
|
216
|
+
<!-- example: examples/HeatmapSegments.svelte -->
|
|
217
|
+
|
|
172
218
|
```svelte
|
|
219
|
+
<script lang="ts">
|
|
220
|
+
import { HeatmapPlot } from '@fundar/data-chart-telling';
|
|
221
|
+
import { HOUSEHOLDS } from './data';
|
|
222
|
+
</script>
|
|
223
|
+
|
|
224
|
+
<!-- Segments on a heatmap: an outlined column and a filled block of overcrowded households. -->
|
|
173
225
|
<HeatmapPlot
|
|
174
|
-
{
|
|
175
|
-
{
|
|
176
|
-
{
|
|
177
|
-
x="
|
|
178
|
-
y="
|
|
179
|
-
color="
|
|
226
|
+
width={560}
|
|
227
|
+
height={360}
|
|
228
|
+
data={HOUSEHOLDS}
|
|
229
|
+
x="rooms"
|
|
230
|
+
y="people"
|
|
231
|
+
color="share"
|
|
180
232
|
segments={{
|
|
181
233
|
default: [
|
|
182
234
|
{
|
|
183
|
-
areas: [{ x: { from: '
|
|
235
|
+
areas: [{ x: { from: '1', to: '1' } }],
|
|
184
236
|
styles: { stroke: '#f59e0b', strokeWidth: 2 }
|
|
185
237
|
},
|
|
186
238
|
{
|
|
187
|
-
areas: [{ x: { from: '
|
|
239
|
+
areas: [{ x: { from: '1', to: '2' }, y: { from: '4', to: '5+' } }],
|
|
188
240
|
styles: { fill: '#ef4444', fillOpacity: 0.8 }
|
|
189
241
|
}
|
|
190
242
|
]
|
|
@@ -192,7 +244,9 @@ Heatmap columns and cells:
|
|
|
192
244
|
/>
|
|
193
245
|
```
|
|
194
246
|
|
|
195
|
-
|
|
247
|
+
<!-- /example -->
|
|
248
|
+
|
|
249
|
+

|
|
196
250
|
|
|
197
251
|
Map features, keyed by feature id:
|
|
198
252
|
|