@fusion.dev/helix-headless 0.40.0 → 0.41.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/custom-elements.json +262 -25
- package/dist/area-chart/root/area-chart-root.d.ts +25 -5
- package/dist/area-chart/root/area-chart-root.js +2 -3
- package/dist/bar-chart/root/bar-chart-root.d.ts +29 -19
- package/dist/bar-chart/root/bar-chart-root.js +4 -10
- package/dist/donut-chart/root/donut-chart-root.d.ts +9 -1
- package/dist/donut-chart/root/donut-chart-root.js +2 -2
- package/dist/legend/root/legend-root.d.ts +16 -2
- package/dist/legend/root/legend-root.js +4 -3
- package/dist/line-chart/root/line-chart-root.d.ts +17 -3
- package/dist/line-chart/root/line-chart-root.js +1 -1
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +6 -3
- package/package.json +5 -5
- package/types/jsx.d.ts +617 -109
- package/types/vue.d.ts +79 -33
|
@@ -28,7 +28,7 @@ declare const HelixHeadlessBarChart_base: typeof HelixElement & (new (...args: a
|
|
|
28
28
|
* computed and CSS cannot.
|
|
29
29
|
*
|
|
30
30
|
* @since 0.1.0
|
|
31
|
-
* @status
|
|
31
|
+
* @status stable
|
|
32
32
|
* @category charts
|
|
33
33
|
* @aliases Column Chart, Categorical Chart
|
|
34
34
|
* @documentation https://fusion.dev/helix/components/bar-chart
|
|
@@ -65,7 +65,7 @@ declare const HelixHeadlessBarChart_base: typeof HelixElement & (new (...args: a
|
|
|
65
65
|
* @csspart tooltip-top - The bubble while it is above the reading, beside `tooltip`.
|
|
66
66
|
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
67
67
|
*
|
|
68
|
-
* @cssproperty --bar-chart-axis -
|
|
68
|
+
* @cssproperty --bar-chart-axis - How wide an axis column is drawn, in `ch`, from the widest number on it. Written on the axis itself, and only where the categories run along the bottom: turned sideways an axis is a row and takes a line's height instead.
|
|
69
69
|
* @cssproperty --bar-chart-secondary - The color of the secondary axis when one series owns it. It resolves a `--helix-color-series-*` token, so on the headless tier alone it names something that is not there. #138.
|
|
70
70
|
* @cssproperty --chart-bar-wash - The gradient a bar would take, named per bar so the
|
|
71
71
|
* styled tier can point `fill` at it. Drawn whatever the treatment and used only where
|
|
@@ -105,30 +105,40 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
|
|
|
105
105
|
/**
|
|
106
106
|
* Which series are drawn as a line instead of as columns, by name.
|
|
107
107
|
*
|
|
108
|
-
*
|
|
109
|
-
* chart says `lines="Margin"` rather than counting
|
|
110
|
-
* they are what the table already carries and what the
|
|
111
|
-
* an index is a fourth place the column order is
|
|
112
|
-
* one to go stale when somebody moves a column.
|
|
108
|
+
* Separated by whitespace or commas and matched against the column headings
|
|
109
|
+
* the table gives, so a chart says `lines="Margin"` rather than counting
|
|
110
|
+
* columns. Names because they are what the table already carries and what the
|
|
111
|
+
* legend already shows: an index is a fourth place the column order is
|
|
112
|
+
* written down and the first one to go stale when somebody moves a column.
|
|
113
113
|
*
|
|
114
|
-
* **
|
|
115
|
-
*
|
|
116
|
-
* something comparable to the columns beside it.
|
|
117
|
-
* for a combination chart is the other thing, a count against a percentage on
|
|
118
|
-
* a second axis, and that is deliberately not this: two scales on one frame
|
|
119
|
-
* let the author put any two shapes in any relation by choosing the ranges,
|
|
120
|
-
* and the reader has no way to see it happening.
|
|
114
|
+
* **This says which mark a series takes and nothing about which scale it is
|
|
115
|
+
* measured on.** Named here alone, a line shares the columns' domain, so it
|
|
116
|
+
* says something comparable to the columns beside it.
|
|
121
117
|
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
118
|
+
* The other half of a combination chart, a count against a percentage on a
|
|
119
|
+
* scale of its own, is `secondary`, which is a separate property because it
|
|
120
|
+
* is a separate question and because the two compose: `with-a-second-axis`
|
|
121
|
+
* ships naming one series in both. The argument for why a second scale is opt
|
|
122
|
+
* in, and why setting it labels both axes, is written there.
|
|
123
|
+
*
|
|
124
|
+
* A line among columns measures from zero, because the columns do and they
|
|
125
|
+
* share the axis. So does a line on the second scale, which is that scale's
|
|
126
|
+
* own rule rather than this one's.
|
|
124
127
|
*/
|
|
125
128
|
lines?: string;
|
|
126
129
|
/**
|
|
127
130
|
* Which series are measured against a scale of their own, by name.
|
|
128
131
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
+
* Separated and matched the way `lines` is, against the column headings the
|
|
133
|
+
* table gives. Opt in: absent, every series shares one domain, which is what
|
|
134
|
+
* makes a chart comparable and is the right default.
|
|
135
|
+
*
|
|
136
|
+
* **The scale, and `lines` is the mark.** The two are separate properties
|
|
137
|
+
* because they answer separate questions and a series usually wants both:
|
|
138
|
+
* a percentage beside a count is drawn as a line *and* measured on its own
|
|
139
|
+
* axis, which is what `with-a-second-axis` writes out. Neither implies the
|
|
140
|
+
* other, so a series can be a line on the shared scale and a column can have
|
|
141
|
+
* a scale to itself.
|
|
132
142
|
*
|
|
133
143
|
* **Two scales on one frame let an author put any two shapes in any relation
|
|
134
144
|
* by choosing the ranges, and a reader cannot see it happening.** That is not
|
|
@@ -4,23 +4,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { CHART_PLOT, customElement, drawTooltip, extent, HelixElement, linear, linePath, MixinChartSource, seriesIndex, ticks, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { CHART_PLOT, customElement, drawTooltip, extent, HelixElement, linear, linePath, MixinChartSource, seriesIndex, seriesNames, ticks, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import '../../tooltip/index.js';
|
|
11
11
|
const HEIGHT = 100;
|
|
12
12
|
let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource(HelixElement) {
|
|
13
13
|
get scaled() {
|
|
14
|
-
return new Set((this.secondary
|
|
15
|
-
.split(/\s+/)
|
|
16
|
-
.map((name) => name.trim().toLowerCase())
|
|
17
|
-
.filter(Boolean));
|
|
14
|
+
return new Set(seriesNames(this.secondary));
|
|
18
15
|
}
|
|
19
16
|
get lined() {
|
|
20
|
-
return new Set((this.lines
|
|
21
|
-
.split(/\s+/)
|
|
22
|
-
.map((name) => name.trim().toLowerCase())
|
|
23
|
-
.filter(Boolean));
|
|
17
|
+
return new Set(seriesNames(this.lines));
|
|
24
18
|
}
|
|
25
19
|
get rulesValue() {
|
|
26
20
|
return this.gridlines !== undefined && this.gridlines !== 'category';
|
|
@@ -223,7 +217,7 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
223
217
|
placement: sideways ? (this.pointer.mirrored ? 'left' : 'right') : 'top',
|
|
224
218
|
x: sideways ? `${far}%` : `${across}%`,
|
|
225
219
|
y: sideways ? `${across}%` : `${far}%`,
|
|
226
|
-
});
|
|
220
|
+
}, (cell) => this.seriesOf(cell));
|
|
227
221
|
}
|
|
228
222
|
};
|
|
229
223
|
__decorate([
|
|
@@ -17,7 +17,7 @@ declare const HelixHeadlessDonutChart_base: typeof HelixElement & (new (...args:
|
|
|
17
17
|
* dropped. Those rows are skipped and the total is of what is left.
|
|
18
18
|
*
|
|
19
19
|
* @since 0.1.0
|
|
20
|
-
* @status
|
|
20
|
+
* @status stable
|
|
21
21
|
* @category charts
|
|
22
22
|
* @aliases Pie Chart, Ring Chart, Share Chart
|
|
23
23
|
* @documentation https://fusion.dev/helix/components/donut-chart
|
|
@@ -84,6 +84,14 @@ export declare class HelixHeadlessDonutChart extends HelixHeadlessDonutChart_bas
|
|
|
84
84
|
* `getComputedStyle`, which is client-only: a server would draw a different
|
|
85
85
|
* ring than the client. A plot's proportions are markup for the same reason
|
|
86
86
|
* `curve` is.
|
|
87
|
+
*
|
|
88
|
+
* **And so it does not reflect**, which is the same argument read forward. No
|
|
89
|
+
* selector on either tier asks about it and none can want to: everything the
|
|
90
|
+
* thickness decides is arithmetic done here and published as
|
|
91
|
+
* `--donut-chart-stroke`, which is a number a rule can do sums with where the
|
|
92
|
+
* word is not. Reflected, it wrote a value onto every host a script had set
|
|
93
|
+
* it on for nothing to read. `sweep` beside it is the converse and reflects,
|
|
94
|
+
* because three rules select on it.
|
|
87
95
|
*/
|
|
88
96
|
hole?: 'large' | 'none' | 'small';
|
|
89
97
|
/**
|
|
@@ -165,11 +165,11 @@ let HelixHeadlessDonutChart = class HelixHeadlessDonutChart extends MixinChartSo
|
|
|
165
165
|
: 'top',
|
|
166
166
|
x: `${x}%`,
|
|
167
167
|
y: `${y}%`,
|
|
168
|
-
});
|
|
168
|
+
}, () => seriesIndex(at));
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
171
|
__decorate([
|
|
172
|
-
property(
|
|
172
|
+
property()
|
|
173
173
|
], HelixHeadlessDonutChart.prototype, "hole", void 0);
|
|
174
174
|
__decorate([
|
|
175
175
|
property({ reflect: true })
|
|
@@ -11,7 +11,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
11
11
|
* `entries` picks which way to read that table. `series` is one entry per data
|
|
12
12
|
* column, named by the header row, which is a line or a bar chart.
|
|
13
13
|
* `categories` is one entry per body row, which is a donut: its slices are the
|
|
14
|
-
* rows and it has no axis to write their names along.
|
|
14
|
+
* rows and it has no axis to write their names along. `measures` drops the
|
|
15
|
+
* first data column, which is a scatter.
|
|
15
16
|
*
|
|
16
17
|
* **The table is resolved on the client and there is no server pass.**
|
|
17
18
|
*
|
|
@@ -32,8 +33,21 @@ export declare class HelixHeadlessLegend extends HelixElement {
|
|
|
32
33
|
*
|
|
33
34
|
* Absent is `series`, one entry per data column. `categories` reads one entry
|
|
34
35
|
* per body row instead, for a donut, whose slices are the rows.
|
|
36
|
+
*
|
|
37
|
+
* **`measures` is `series` without the first column, and it is for a
|
|
38
|
+
* scatter.** That chart reads its first numeric column as the measure
|
|
39
|
+
* *across*, so its first plotted series is the table's second and everything
|
|
40
|
+
* a legend beside it named was one color out: the across column wearing the
|
|
41
|
+
* color of the first series drawn, and each real series wearing the next
|
|
42
|
+
* one's. The across gets no entry rather than a shifted one, because it is an
|
|
43
|
+
* axis and a scatter already writes its name at the end of the scale under
|
|
44
|
+
* the plot.
|
|
45
|
+
*
|
|
46
|
+
* A legend cannot ask the chart which of these it is, `for` naming the table
|
|
47
|
+
* they share and not each other, so the consumer says it. That is the same
|
|
48
|
+
* shape `categories` already has.
|
|
35
49
|
*/
|
|
36
|
-
entries?: 'categories' | 'series';
|
|
50
|
+
entries?: 'categories' | 'measures' | 'series';
|
|
37
51
|
/**
|
|
38
52
|
* The id of the table to take the names from.
|
|
39
53
|
*
|
|
@@ -20,9 +20,10 @@ let HelixHeadlessLegend = class HelixHeadlessLegend extends HelixElement {
|
|
|
20
20
|
}
|
|
21
21
|
names() {
|
|
22
22
|
const series = this.source.series;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
if (this.entries === 'categories') {
|
|
24
|
+
return series[0]?.points.map((point) => point.label) ?? [];
|
|
25
|
+
}
|
|
26
|
+
return (this.entries === 'measures' ? series.slice(1) : series).map((one) => one.name);
|
|
26
27
|
}
|
|
27
28
|
render() {
|
|
28
29
|
return html `<ul part="list" role="list">
|
|
@@ -36,7 +36,7 @@ declare const HelixHeadlessLineChart_base: typeof HelixElement & (new (...args:
|
|
|
36
36
|
* A reader who wants the numbers gets the numbers, not a described picture.
|
|
37
37
|
*
|
|
38
38
|
* @since 0.1.0
|
|
39
|
-
* @status
|
|
39
|
+
* @status stable
|
|
40
40
|
* @category charts
|
|
41
41
|
* @aliases Time Series, Trend Chart, Multi-line Chart
|
|
42
42
|
* @documentation https://fusion.dev/helix/components/line-chart
|
|
@@ -68,6 +68,9 @@ declare const HelixHeadlessLineChart_base: typeof HelixElement & (new (...args:
|
|
|
68
68
|
* @csspart tooltip-right - The bubble while it is right of the reading, beside `tooltip`.
|
|
69
69
|
* @csspart tooltip-top - The bubble while it is above the reading, beside `tooltip`.
|
|
70
70
|
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
71
|
+
*
|
|
72
|
+
* @cssproperty --chart-terminus-x - Where a series' last reading sits horizontally, as a percentage. Written by the component.
|
|
73
|
+
* @cssproperty --chart-terminus-y - Where a series' last reading sits vertically, as a percentage. Written by the component.
|
|
71
74
|
*/
|
|
72
75
|
export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base {
|
|
73
76
|
/**
|
|
@@ -141,9 +144,20 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
|
|
|
141
144
|
* the question a sparkline's single mark answers too.
|
|
142
145
|
*
|
|
143
146
|
* `none` lets the lines stop on their own, which suits a chart read for its
|
|
144
|
-
* shape rather than for where it finished.
|
|
147
|
+
* shape rather than for where it finished. `square` is the same mark with its
|
|
148
|
+
* corners, for a drawing whose neighbors are square, the columns of a table
|
|
149
|
+
* beside it for instance. `ring` lets the ground through, for a chart drawn
|
|
150
|
+
* over something busy. `triangle` points along the axis and reads as "and
|
|
151
|
+
* onward" rather than as a second claim about the data.
|
|
152
|
+
*
|
|
153
|
+
* The shapes come from
|
|
145
154
|
* `helix/styled/src/shared/chart/terminus.css`, the same sheet `Sparkline` takes, so
|
|
146
|
-
* the set is identical wherever one appears.
|
|
155
|
+
* the set is identical wherever one appears. **Which is why every value is
|
|
156
|
+
* named here.** `Sparkline` shipped `square` implemented, drawn, asserted and
|
|
157
|
+
* undocumented until the cohort before this one; this family reads the same
|
|
158
|
+
* four out of the same sheet and had left two of them unwritten, so the
|
|
159
|
+
* finding arrived twice. A shared vocabulary wants naming at each door into
|
|
160
|
+
* it, because a reader arrives at one door and not at the set.
|
|
147
161
|
*
|
|
148
162
|
* `ring` is the one that asks something of the drawing. It leaves a hole and a
|
|
149
163
|
* line ends at the reading, which is the hole's center, so the `<svg>` is
|
|
@@ -170,7 +170,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
|
|
|
170
170
|
placement: 'top',
|
|
171
171
|
x: `${at * slot + slot / 2}%`,
|
|
172
172
|
y: `${tops.length > 0 ? Math.min(...tops) : 0}%`,
|
|
173
|
-
});
|
|
173
|
+
}, (cell) => this.seriesOf(cell));
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
176
|
__decorate([
|
|
@@ -58,7 +58,7 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
|
|
|
58
58
|
* and the bubble is told the page's direction, both being words.
|
|
59
59
|
*
|
|
60
60
|
* @since 0.1.0
|
|
61
|
-
* @status
|
|
61
|
+
* @status stable
|
|
62
62
|
* @category charts
|
|
63
63
|
* @aliases Scatter Plot, XY Chart, Correlation Chart, Dot Plot
|
|
64
64
|
* @documentation https://fusion.dev/helix/components/scatter-chart
|
|
@@ -121,6 +121,22 @@ export declare class HelixHeadlessScatterChart extends HelixHeadlessScatterChart
|
|
|
121
121
|
private nearest;
|
|
122
122
|
connectedCallback(): void;
|
|
123
123
|
disconnectedCallback(): void;
|
|
124
|
+
/**
|
|
125
|
+
* The palette slot a cell of a row is drawn in, which here is shifted by one.
|
|
126
|
+
*
|
|
127
|
+
* **A scatter's first plotted series is the table's *second* numeric
|
|
128
|
+
* column**, the first having been split off as the measure across. So the
|
|
129
|
+
* mixin's answer, which is right for a chart whose columns are its series in
|
|
130
|
+
* order, is one too high on every column here and names a color for the
|
|
131
|
+
* across, which is drawn in none. Left at that, the bubble painted the across
|
|
132
|
+
* column in series one, the color the points themselves are drawn in, and
|
|
133
|
+
* gave the series actually plotted series two.
|
|
134
|
+
*
|
|
135
|
+
* The across gets no dot at all rather than a shifted one. It is an axis and
|
|
136
|
+
* not a series: it has a scale under the plot with its name at the end of it,
|
|
137
|
+
* which is where a reader is told what it is.
|
|
138
|
+
*/
|
|
139
|
+
seriesOf(cell: number): number | undefined;
|
|
124
140
|
/** Whether the levels across are ruled. */
|
|
125
141
|
protected get rulesX(): boolean;
|
|
126
142
|
/** Whether the levels up are ruled. */
|
|
@@ -89,6 +89,10 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
|
|
|
89
89
|
this.removeEventListener('pointermove', this.handleMove);
|
|
90
90
|
this.removeEventListener('pointerleave', this.handleLeave);
|
|
91
91
|
}
|
|
92
|
+
seriesOf(cell) {
|
|
93
|
+
const depth = this.plottedColumns.indexOf(cell);
|
|
94
|
+
return depth < 1 ? undefined : seriesIndex(depth - 1);
|
|
95
|
+
}
|
|
92
96
|
get rulesX() {
|
|
93
97
|
return this.gridlines !== undefined && this.gridlines !== 'y';
|
|
94
98
|
}
|
|
@@ -97,8 +101,7 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
|
|
|
97
101
|
}
|
|
98
102
|
get field() {
|
|
99
103
|
const rows = this.sourceRows;
|
|
100
|
-
const
|
|
101
|
-
const columns = Array.from({ length: width }, (_, column) => column).filter((column) => rows.some((row) => row.cells[column]?.value !== undefined));
|
|
104
|
+
const columns = this.plottedColumns;
|
|
102
105
|
const [across, ...ups] = columns;
|
|
103
106
|
const name = (column) => column === undefined ? '' : (rows.find((row) => row.cells[column])?.cells[column]?.name ?? '');
|
|
104
107
|
const pairs = ups.map((column) => rows.flatMap((row, index) => {
|
|
@@ -193,7 +196,7 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
|
|
|
193
196
|
placement: 'top',
|
|
194
197
|
x: `${point.x}%`,
|
|
195
198
|
y: `${point.y}%`,
|
|
196
|
-
});
|
|
199
|
+
}, (cell) => this.seriesOf(cell));
|
|
197
200
|
}
|
|
198
201
|
};
|
|
199
202
|
__decorate([
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-headless",
|
|
3
3
|
"description": "Headless component tier. Structure, accessibility, state, and form participation. No styling.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.41.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
},
|
|
47
47
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@fusion.dev/helix-core": "0.
|
|
50
|
-
"@fusion.dev/helix-icons": "0.
|
|
49
|
+
"@fusion.dev/helix-core": "0.41.0",
|
|
50
|
+
"@fusion.dev/helix-icons": "0.41.0",
|
|
51
51
|
"uqr": "^0.1.3"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
|
55
|
-
"@fusion.dev/helix-cem": "0.
|
|
56
|
-
"@fusion.dev/helix-testing": "0.
|
|
55
|
+
"@fusion.dev/helix-cem": "0.41.0",
|
|
56
|
+
"@fusion.dev/helix-testing": "0.41.0",
|
|
57
57
|
"@fusion.dev/scripts": "0.0.0-dev",
|
|
58
58
|
"@happy-dom/global-registrator": "^20.0.0",
|
|
59
59
|
"@lit-labs/ssr": "^4.1.0",
|