@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.151 → 2.0.0-next.152
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/.storybook/vitest.setup.ts +12 -1
- package/bundle/openbridge-webcomponents.bundle.js +989 -319
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +1514 -77
- package/dist/alert-severity.d.ts +12 -9
- package/dist/alert-severity.d.ts.map +1 -1
- package/dist/alert-severity.js +30 -38
- package/dist/alert-severity.js.map +1 -1
- package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts +6 -0
- package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts.map +1 -1
- package/dist/building-blocks/bar-horizontal/bar-horizontal.js +6 -1
- package/dist/building-blocks/bar-horizontal/bar-horizontal.js.map +1 -1
- package/dist/building-blocks/bar-vertical/bar-vertical.d.ts +6 -0
- package/dist/building-blocks/bar-vertical/bar-vertical.d.ts.map +1 -1
- package/dist/building-blocks/bar-vertical/bar-vertical.js +6 -1
- package/dist/building-blocks/bar-vertical/bar-vertical.js.map +1 -1
- package/dist/building-blocks/chart-line/chart-line-base.d.ts +129 -0
- package/dist/building-blocks/chart-line/chart-line-base.d.ts.map +1 -1
- package/dist/building-blocks/chart-line/chart-line-base.js +464 -79
- package/dist/building-blocks/chart-line/chart-line-base.js.map +1 -1
- package/dist/building-blocks/external-scale/external-scale.d.ts +11 -0
- package/dist/building-blocks/external-scale/external-scale.d.ts.map +1 -1
- package/dist/building-blocks/external-scale/external-scale.js +45 -12
- package/dist/building-blocks/external-scale/external-scale.js.map +1 -1
- package/dist/charthelpers/index.d.ts +1 -0
- package/dist/charthelpers/index.d.ts.map +1 -1
- package/dist/charthelpers/index.js +7 -1
- package/dist/charthelpers/index.js.map +1 -1
- package/dist/charthelpers/range-labels.d.ts +55 -0
- package/dist/charthelpers/range-labels.d.ts.map +1 -0
- package/dist/charthelpers/range-labels.js +36 -0
- package/dist/charthelpers/range-labels.js.map +1 -0
- package/dist/components/alert-button/alert-button.css.js +13 -21
- package/dist/components/alert-button/alert-button.css.js.map +1 -1
- package/dist/components/alert-button/alert-button.d.ts +9 -4
- package/dist/components/alert-button/alert-button.d.ts.map +1 -1
- package/dist/components/alert-button/alert-button.js +24 -15
- package/dist/components/alert-button/alert-button.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.css.js +109 -33
- package/dist/components/alert-frame/alert-frame.css.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.d.ts +34 -7
- package/dist/components/alert-frame/alert-frame.d.ts.map +1 -1
- package/dist/components/alert-frame/alert-frame.js +134 -30
- package/dist/components/alert-frame/alert-frame.js.map +1 -1
- package/dist/components/alert-icon/alert-icon.d.ts +10 -7
- package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
- package/dist/components/alert-icon/alert-icon.js +37 -60
- package/dist/components/alert-icon/alert-icon.js.map +1 -1
- package/dist/components/alert-menu-item/alert-menu-item.css.js +1 -4
- package/dist/components/alert-menu-item/alert-menu-item.css.js.map +1 -1
- package/dist/components/date-item/date-item.css.js +3 -3
- package/dist/components/keyboard-full/keyboard-full.css.js +4 -4
- package/dist/components/message-menu-item/message-menu-item.css.js +2 -6
- package/dist/components/message-menu-item/message-menu-item.css.js.map +1 -1
- package/dist/components/sequence-toolbar/sequence-toolbar.css.js +1 -2
- package/dist/components/sequence-toolbar/sequence-toolbar.css.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts +6 -0
- package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts.map +1 -1
- package/dist/navigation-instruments/gauge-trend/gauge-trend.js +8 -0
- package/dist/navigation-instruments/gauge-trend/gauge-trend.js.map +1 -1
- package/dist/navigation-instruments/instrument-field/instrument-field.css.js +2 -2
- package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout.js +2 -1
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js +2 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/dist/openbridge.css +19 -4
- package/dist/palettes/blinking.d.ts +14 -4
- package/dist/palettes/blinking.d.ts.map +1 -1
- package/dist/palettes/blinking.js +41 -35
- package/dist/palettes/blinking.js.map +1 -1
- package/dist/palettes/flashing-controller.d.ts +21 -0
- package/dist/palettes/flashing-controller.d.ts.map +1 -0
- package/dist/palettes/flashing-controller.js +45 -0
- package/dist/palettes/flashing-controller.js.map +1 -0
- package/dist/svghelpers/index.d.ts +1 -0
- package/dist/svghelpers/index.d.ts.map +1 -1
- package/dist/svghelpers/index.js +2 -0
- package/dist/svghelpers/index.js.map +1 -1
- package/dist/svghelpers/rounded-rect.d.ts +15 -0
- package/dist/svghelpers/rounded-rect.d.ts.map +1 -0
- package/dist/svghelpers/rounded-rect.js +29 -0
- package/dist/svghelpers/rounded-rect.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/script/check-css-variables.ts +2 -15
- package/src/alert-severity.spec.ts +56 -0
- package/src/alert-severity.ts +45 -43
- package/src/bars-graphs/area-graph/area-graph.stories.ts +235 -1
- package/src/bars-graphs/line-graph/line-graph.stories.ts +24 -0
- package/src/building-blocks/bar-horizontal/bar-horizontal.ts +7 -0
- package/src/building-blocks/bar-vertical/bar-vertical.ts +7 -0
- package/src/building-blocks/chart-line/chart-line-base.spec.ts +767 -0
- package/src/building-blocks/chart-line/chart-line-base.stories.ts +124 -0
- package/src/building-blocks/chart-line/chart-line-base.ts +671 -97
- package/src/building-blocks/chart-line/chart-sizing-battleground.stories.ts +17 -0
- package/src/building-blocks/external-scale/external-scale.spec.ts +154 -0
- package/src/building-blocks/external-scale/external-scale.ts +78 -20
- package/src/charthelpers/index.ts +1 -0
- package/src/charthelpers/range-labels.spec.ts +46 -0
- package/src/charthelpers/range-labels.ts +93 -0
- package/src/components/alert-button/alert-button.css +10 -23
- package/src/components/alert-button/alert-button.spec.ts +56 -15
- package/src/components/alert-button/alert-button.stories.ts +5 -1
- package/src/components/alert-button/alert-button.ts +33 -24
- package/src/components/alert-frame/alert-flash-scenario.stories.ts +669 -0
- package/src/components/alert-frame/alert-frame.css +106 -33
- package/src/components/alert-frame/alert-frame.spec.ts +176 -17
- package/src/components/alert-frame/alert-frame.stories.ts +61 -0
- package/src/components/alert-frame/alert-frame.ts +179 -41
- package/src/components/alert-icon/alert-icon.spec.ts +82 -27
- package/src/components/alert-icon/alert-icon.stories.ts +7 -1
- package/src/components/alert-icon/alert-icon.ts +48 -74
- package/src/components/alert-menu-item/alert-menu-item.css +1 -4
- package/src/components/date-item/date-item.css +3 -3
- package/src/components/keyboard-full/keyboard-full.css +4 -4
- package/src/components/message-menu-item/message-menu-item.css +2 -6
- package/src/components/sequence-toolbar/sequence-toolbar.css +1 -2
- package/src/navigation-instruments/gauge-trend/gauge-trend.stories.ts +29 -0
- package/src/navigation-instruments/gauge-trend/gauge-trend.ts +11 -0
- package/src/navigation-instruments/instrument-field/instrument-field.css +2 -2
- package/src/navigation-instruments/readout/readout.ts +2 -1
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +2 -1
- package/src/palettes/blinking.spec.ts +83 -0
- package/src/palettes/blinking.ts +47 -35
- package/src/palettes/flashing-controller.ts +62 -0
- package/src/palettes/manual.css +18 -4
- package/src/svghelpers/index.ts +1 -0
- package/src/svghelpers/rounded-rect.spec.ts +47 -0
- package/src/svghelpers/rounded-rect.ts +42 -0
- package/src/types.ts +20 -0
|
@@ -0,0 +1,767 @@
|
|
|
1
|
+
import {describe, it, expect, afterEach, afterAll, vi} from 'vitest';
|
|
2
|
+
import '../../main.css';
|
|
3
|
+
import '../../bars-graphs/area-graph/area-graph.js';
|
|
4
|
+
import '../bar-vertical/bar-vertical.js';
|
|
5
|
+
import '../bar-horizontal/bar-horizontal.js';
|
|
6
|
+
import '../../navigation-instruments/gauge-trend/gauge-trend.js';
|
|
7
|
+
import type {ObcGaugeTrend} from '../../navigation-instruments/gauge-trend/gauge-trend.js';
|
|
8
|
+
import type {ObcAreaGraph} from '../../bars-graphs/area-graph/area-graph.js';
|
|
9
|
+
import type {ObcBarVertical} from '../bar-vertical/bar-vertical.js';
|
|
10
|
+
import type {ObcBarHorizontal} from '../bar-horizontal/bar-horizontal.js';
|
|
11
|
+
import {ExternalScaleSide} from '../external-scale/external-scale.js';
|
|
12
|
+
import {XAxisType, TimeDisplay, RangeLabels} from './chart-line-base.js';
|
|
13
|
+
|
|
14
|
+
type ChartScales = {
|
|
15
|
+
scales: Record<string, {min: number; max: number}>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const frames = async (n = 12) => {
|
|
19
|
+
for (let i = 0; i < n; i++) {
|
|
20
|
+
await new Promise((r) => requestAnimationFrame(() => r(null)));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const mounted: HTMLElement[] = [];
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
mounted.splice(0).forEach((el) => el.remove());
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterAll(() => {
|
|
31
|
+
document.documentElement.classList.remove('obc-component-size-regular');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Mounts an area graph with a left and a bottom scale slotted, then waits for
|
|
36
|
+
* the slot → dimension → sync round trip to settle.
|
|
37
|
+
*/
|
|
38
|
+
async function mount(
|
|
39
|
+
configure: (chart: ObcAreaGraph) => void,
|
|
40
|
+
{withRight = false} = {}
|
|
41
|
+
) {
|
|
42
|
+
document.documentElement.classList.add('obc-component-size-regular');
|
|
43
|
+
const host = document.createElement('div');
|
|
44
|
+
host.style.cssText = 'width: 600px; height: 300px';
|
|
45
|
+
document.body.appendChild(host);
|
|
46
|
+
mounted.push(host);
|
|
47
|
+
|
|
48
|
+
const chart = document.createElement('obc-area-graph');
|
|
49
|
+
chart.width = 600;
|
|
50
|
+
chart.height = 300;
|
|
51
|
+
configure(chart);
|
|
52
|
+
|
|
53
|
+
const left = document.createElement('obc-bar-vertical');
|
|
54
|
+
left.slot = 'left-scale';
|
|
55
|
+
left.side = ExternalScaleSide.left;
|
|
56
|
+
chart.appendChild(left);
|
|
57
|
+
|
|
58
|
+
const bottom = document.createElement('obc-bar-horizontal');
|
|
59
|
+
bottom.slot = 'bottom-scale';
|
|
60
|
+
bottom.side = ExternalScaleSide.bottom;
|
|
61
|
+
chart.appendChild(bottom);
|
|
62
|
+
|
|
63
|
+
const right = document.createElement('obc-bar-vertical');
|
|
64
|
+
if (withRight) {
|
|
65
|
+
right.slot = 'right-scale';
|
|
66
|
+
right.side = ExternalScaleSide.right;
|
|
67
|
+
chart.appendChild(right);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
host.appendChild(chart);
|
|
71
|
+
await chart.updateComplete;
|
|
72
|
+
await frames();
|
|
73
|
+
return {chart, left, right, bottom};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type ChartGeometry = {
|
|
77
|
+
chartArea: {left: number; right: number; top: number; bottom: number};
|
|
78
|
+
options: {
|
|
79
|
+
layout: {
|
|
80
|
+
padding: {top: number; right: number; bottom: number; left: number};
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const chartPadding = (chart: ObcAreaGraph) =>
|
|
86
|
+
(chart as unknown as {chart: ChartGeometry}).chart.options.layout.padding;
|
|
87
|
+
|
|
88
|
+
const chartAreaOf = (chart: ObcAreaGraph) => {
|
|
89
|
+
const a = (chart as unknown as {chart: ChartGeometry}).chart.chartArea;
|
|
90
|
+
return {
|
|
91
|
+
left: Math.round(a.left),
|
|
92
|
+
right: Math.round(a.right),
|
|
93
|
+
top: Math.round(a.top),
|
|
94
|
+
bottom: Math.round(a.bottom),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const canvasRect = (chart: ObcAreaGraph) =>
|
|
99
|
+
chart.shadowRoot!.querySelector('canvas')!.getBoundingClientRect();
|
|
100
|
+
|
|
101
|
+
type DrawnRangeLabel = {axis: 'x' | 'y'; text: string; x: number; y: number};
|
|
102
|
+
const drawnRangeLabels = (chart: ObcAreaGraph) =>
|
|
103
|
+
(chart as unknown as {lastRangeLabels: DrawnRangeLabel[]}).lastRangeLabels;
|
|
104
|
+
|
|
105
|
+
/** Mounts an area graph with no slotted scales at the given size. */
|
|
106
|
+
async function mountPlain(
|
|
107
|
+
configure: (chart: ObcAreaGraph) => void,
|
|
108
|
+
size: {width: number; height: number}
|
|
109
|
+
) {
|
|
110
|
+
document.documentElement.classList.add('obc-component-size-regular');
|
|
111
|
+
const host = document.createElement('div');
|
|
112
|
+
document.body.appendChild(host);
|
|
113
|
+
mounted.push(host);
|
|
114
|
+
|
|
115
|
+
const chart = document.createElement('obc-area-graph');
|
|
116
|
+
chart.width = size.width;
|
|
117
|
+
chart.height = size.height;
|
|
118
|
+
chart.showTickMarks = true;
|
|
119
|
+
configure(chart);
|
|
120
|
+
host.appendChild(chart);
|
|
121
|
+
await chart.updateComplete;
|
|
122
|
+
await frames();
|
|
123
|
+
return chart;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const datasetAxisId = (chart: ObcAreaGraph, index = 0) =>
|
|
127
|
+
(
|
|
128
|
+
chart as unknown as {
|
|
129
|
+
chart: {getDatasetMeta(i: number): {yAxisID: string}};
|
|
130
|
+
}
|
|
131
|
+
).chart.getDatasetMeta(index).yAxisID;
|
|
132
|
+
|
|
133
|
+
const chartScales = (chart: ObcAreaGraph) =>
|
|
134
|
+
(chart as unknown as {chart: ChartScales}).chart.scales;
|
|
135
|
+
|
|
136
|
+
const chartRange = (chart: ObcAreaGraph, id: string) => ({
|
|
137
|
+
min: chartScales(chart)[id].min,
|
|
138
|
+
max: chartScales(chart)[id].max,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const range = (scale: ObcBarVertical | ObcBarHorizontal) => ({
|
|
142
|
+
min: scale.minValue,
|
|
143
|
+
max: scale.maxValue,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const numberData = (values: number[]) => values.map((value, x) => ({x, value}));
|
|
147
|
+
|
|
148
|
+
describe('slotted scale range resolution (#1217)', () => {
|
|
149
|
+
it('cascades a pinned y range whose yAxes entry has a custom id', async () => {
|
|
150
|
+
const {left} = await mount((chart) => {
|
|
151
|
+
chart.xAxisType = XAxisType.number;
|
|
152
|
+
chart.yAxes = [{id: 'y-depth', position: 'left', min: 0, max: 75}];
|
|
153
|
+
chart.data = numberData([10, 20, 30]);
|
|
154
|
+
});
|
|
155
|
+
expect(range(left)).toEqual({min: 0, max: 75});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('cascades a pinned y range whose yAxes entry has no id', async () => {
|
|
159
|
+
const {left} = await mount((chart) => {
|
|
160
|
+
chart.xAxisType = XAxisType.number;
|
|
161
|
+
chart.yAxes = [{position: 'left', min: 0, max: 75}];
|
|
162
|
+
chart.data = numberData([10, 20, 30]);
|
|
163
|
+
});
|
|
164
|
+
expect(range(left)).toEqual({min: 0, max: 75});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('plots single-series data on the configured axis, not a default one', async () => {
|
|
168
|
+
const {chart} = await mount((c) => {
|
|
169
|
+
c.xAxisType = XAxisType.number;
|
|
170
|
+
c.yAxes = [{id: 'y-depth', position: 'left', min: 0, max: 75}];
|
|
171
|
+
c.data = numberData([10, 20, 30]);
|
|
172
|
+
});
|
|
173
|
+
expect(datasetAxisId(chart)).toBe('y-depth');
|
|
174
|
+
expect(Object.keys(chartScales(chart)).sort()).toEqual(['x', 'y-depth']);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('feeds a right scale from the right-positioned axis', async () => {
|
|
178
|
+
const {left, right} = await mount(
|
|
179
|
+
(c) => {
|
|
180
|
+
c.yAxes = [
|
|
181
|
+
{id: 'y-temp', position: 'left', min: 0, max: 100},
|
|
182
|
+
{id: 'y-pressure', position: 'right', min: 0, max: 10},
|
|
183
|
+
];
|
|
184
|
+
c.datasets = [
|
|
185
|
+
{label: 'T', data: [20, 25], yAxisID: 'y-temp'},
|
|
186
|
+
{label: 'P', data: [2, 3], yAxisID: 'y-pressure'},
|
|
187
|
+
];
|
|
188
|
+
},
|
|
189
|
+
{withRight: true}
|
|
190
|
+
);
|
|
191
|
+
expect(range(left)).toEqual({min: 0, max: 100});
|
|
192
|
+
expect(range(right)).toEqual({min: 0, max: 10});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('follows an auto-ranged axis when the data changes', async () => {
|
|
196
|
+
const {chart, left} = await mount((c) => {
|
|
197
|
+
c.xAxisType = XAxisType.number;
|
|
198
|
+
c.data = numberData([0, 5, 10]);
|
|
199
|
+
});
|
|
200
|
+
expect(range(left)).toEqual(chartRange(chart, 'y'));
|
|
201
|
+
|
|
202
|
+
chart.data = numberData([0, 500, 1000]);
|
|
203
|
+
await chart.updateComplete;
|
|
204
|
+
await frames();
|
|
205
|
+
expect(chartRange(chart, 'y').max).toBeGreaterThanOrEqual(1000);
|
|
206
|
+
expect(range(left)).toEqual(chartRange(chart, 'y'));
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
type ChartTickCallback = {
|
|
211
|
+
options: {scales: {x: {ticks: {callback(value: number): string}}}};
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const xTickLabel = (chart: ObcAreaGraph, value: number) =>
|
|
215
|
+
(
|
|
216
|
+
chart as unknown as {chart: ChartTickCallback}
|
|
217
|
+
).chart.options.scales.x.ticks.callback(value);
|
|
218
|
+
|
|
219
|
+
describe('pinned x range (#1218)', () => {
|
|
220
|
+
it('pins the x scale and the bottom scale beyond the data extent', async () => {
|
|
221
|
+
const {chart, bottom} = await mount((c) => {
|
|
222
|
+
c.xAxisType = XAxisType.number;
|
|
223
|
+
c.xAxis = {min: -12, max: 0};
|
|
224
|
+
c.data = [-5, -4, -3, -2, -1, 0].map((x) => ({x, value: 1}));
|
|
225
|
+
});
|
|
226
|
+
expect(chartRange(chart, 'x')).toEqual({min: -12, max: 0});
|
|
227
|
+
expect(range(bottom)).toEqual({min: -12, max: 0});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('is ignored on a category axis', async () => {
|
|
231
|
+
const {chart} = await mount((c) => {
|
|
232
|
+
c.xAxis = {min: -12, max: 0};
|
|
233
|
+
c.data = [
|
|
234
|
+
{label: 'a', value: 1},
|
|
235
|
+
{label: 'b', value: 2},
|
|
236
|
+
{label: 'c', value: 3},
|
|
237
|
+
];
|
|
238
|
+
});
|
|
239
|
+
expect(chartRange(chart, 'x')).toEqual({min: 0, max: 2});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('makes xAxis.max the 0min reference for relative time labels', async () => {
|
|
243
|
+
const minute = 60_000;
|
|
244
|
+
const now = 1_757_430_000_000;
|
|
245
|
+
const {chart} = await mount((c) => {
|
|
246
|
+
c.xAxisType = XAxisType.time;
|
|
247
|
+
c.timeDisplay = TimeDisplay.minutes;
|
|
248
|
+
c.xAxis = {min: now - 10 * minute, max: now};
|
|
249
|
+
// Buffer still filling: newest sample is three minutes short of `max`.
|
|
250
|
+
c.data = [7, 6, 5, 4, 3].map((ago) => ({
|
|
251
|
+
x: now - ago * minute,
|
|
252
|
+
value: 1,
|
|
253
|
+
}));
|
|
254
|
+
});
|
|
255
|
+
expect(xTickLabel(chart, now)).toBe('0min');
|
|
256
|
+
expect(xTickLabel(chart, now - 10 * minute)).toBe('-10min');
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe('slotted scales on a time axis (#1219)', () => {
|
|
261
|
+
const minute = 60_000;
|
|
262
|
+
const now = 1_757_430_000_000;
|
|
263
|
+
const twelveMinutes = Array.from({length: 12}, (_, i) => ({
|
|
264
|
+
x: now - (11 - i) * minute,
|
|
265
|
+
value: i,
|
|
266
|
+
}));
|
|
267
|
+
|
|
268
|
+
afterEach(() => {
|
|
269
|
+
vi.restoreAllMocks();
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('cascades minutes relative to the reference, not epoch milliseconds', async () => {
|
|
273
|
+
const {bottom} = await mount((c) => {
|
|
274
|
+
c.xAxisType = XAxisType.time;
|
|
275
|
+
c.timeDisplay = TimeDisplay.minutes;
|
|
276
|
+
c.data = twelveMinutes;
|
|
277
|
+
});
|
|
278
|
+
// A plausible interval for the plotted axis must stay plausible here.
|
|
279
|
+
bottom.primaryTickmarkInterval = 2;
|
|
280
|
+
await bottom.updateComplete;
|
|
281
|
+
expect(range(bottom)).toEqual({min: -11, max: 0});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('converts a pinned x range to minutes as well', async () => {
|
|
285
|
+
const {bottom} = await mount((c) => {
|
|
286
|
+
c.xAxisType = XAxisType.time;
|
|
287
|
+
c.timeDisplay = TimeDisplay.minutes;
|
|
288
|
+
c.xAxis = {min: now - 10 * minute, max: now};
|
|
289
|
+
c.data = twelveMinutes.slice(7);
|
|
290
|
+
});
|
|
291
|
+
expect(range(bottom)).toEqual({min: -10, max: 0});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("leaves the scale alone in 'date' display and says why", async () => {
|
|
295
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
296
|
+
const {bottom} = await mount((c) => {
|
|
297
|
+
c.xAxisType = XAxisType.time;
|
|
298
|
+
c.timeDisplay = TimeDisplay.date;
|
|
299
|
+
c.data = twelveMinutes;
|
|
300
|
+
});
|
|
301
|
+
expect(range(bottom)).toEqual({min: 0, max: 100});
|
|
302
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining('date'));
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
describe('range labels below the threshold (#1191)', () => {
|
|
307
|
+
const small = {width: 120, height: 72};
|
|
308
|
+
|
|
309
|
+
it('reserves a measured side gutter and a one-line bottom gutter', async () => {
|
|
310
|
+
const chart = await mountPlain((c) => {
|
|
311
|
+
c.rangeLabels = RangeLabels.xy;
|
|
312
|
+
c.data = [3.5, 7, 4].map((value, i) => ({label: `L${i}`, value}));
|
|
313
|
+
}, small);
|
|
314
|
+
const padding = chartPadding(chart);
|
|
315
|
+
expect(padding.left).toBeGreaterThan(8);
|
|
316
|
+
expect(padding.right).toBe(0);
|
|
317
|
+
expect(padding.bottom).toBeGreaterThan(4);
|
|
318
|
+
expect(padding.top).toBe(0);
|
|
319
|
+
expect(
|
|
320
|
+
drawnRangeLabels(chart)
|
|
321
|
+
.map((l) => l.text)
|
|
322
|
+
.sort()
|
|
323
|
+
).toEqual(['3.5', '7.0', 'L0', 'L2'].sort());
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('clamps min and max to the plot edges and adds 0 inside a bipolar range', async () => {
|
|
327
|
+
const chart = await mountPlain((c) => {
|
|
328
|
+
c.rangeLabels = RangeLabels.y;
|
|
329
|
+
c.yAxes = [{id: 'y', position: 'left', min: -100, max: 100}];
|
|
330
|
+
c.data = [-50, 50].map((value, i) => ({label: String(i), value}));
|
|
331
|
+
}, small);
|
|
332
|
+
const labels = drawnRangeLabels(chart);
|
|
333
|
+
const area = chartAreaOf(chart);
|
|
334
|
+
expect(labels.map((l) => l.text)).toEqual(['100', '0', '-100']);
|
|
335
|
+
expect(Math.round(labels[0].y)).toBe(area.top);
|
|
336
|
+
expect(Math.round(labels[2].y)).toBe(area.bottom);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('does nothing above the threshold or when hasLabelPadding is false', async () => {
|
|
340
|
+
const big = await mountPlain(
|
|
341
|
+
(c) => {
|
|
342
|
+
c.rangeLabels = RangeLabels.xy;
|
|
343
|
+
c.data = numberData([1, 2]);
|
|
344
|
+
},
|
|
345
|
+
{width: 300, height: 200}
|
|
346
|
+
);
|
|
347
|
+
expect(drawnRangeLabels(big)).toEqual([]);
|
|
348
|
+
const edge = await mountPlain((c) => {
|
|
349
|
+
c.rangeLabels = RangeLabels.xy;
|
|
350
|
+
c.hasLabelPadding = false;
|
|
351
|
+
c.data = numberData([1, 2]);
|
|
352
|
+
}, small);
|
|
353
|
+
expect(chartPadding(edge)).toEqual({top: 0, right: 0, bottom: 0, left: 0});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('pads a slotted side by its reported thickness below the threshold', async () => {
|
|
357
|
+
const {chart, left} = await mount((c) => {
|
|
358
|
+
c.width = 160;
|
|
359
|
+
c.height = 120;
|
|
360
|
+
c.data = numberData([1, 2, 3]);
|
|
361
|
+
});
|
|
362
|
+
const reported = (
|
|
363
|
+
chart as unknown as {externalScaleDimensions: Map<string, number>}
|
|
364
|
+
).externalScaleDimensions.get('left');
|
|
365
|
+
expect(reported).toBeGreaterThan(0);
|
|
366
|
+
expect(chartAreaOf(chart).left).toBeGreaterThanOrEqual(reported!);
|
|
367
|
+
expect(left.getBoundingClientRect().right).toBeLessThanOrEqual(
|
|
368
|
+
canvasRect(chart).left + chartAreaOf(chart).left + 1
|
|
369
|
+
);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
describe('compact labels cascade to slotted scales (#1191)', () => {
|
|
374
|
+
it('switches slotted scales to main-tickmark labels below the threshold', async () => {
|
|
375
|
+
const {left, bottom} = await mount((c) => {
|
|
376
|
+
c.rangeLabels = RangeLabels.xy;
|
|
377
|
+
c.width = 160;
|
|
378
|
+
c.height = 120;
|
|
379
|
+
c.data = numberData([1, 2, 3]);
|
|
380
|
+
});
|
|
381
|
+
expect(left.showLabels).toBe(true);
|
|
382
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
383
|
+
expect(bottom.showLabels).toBe(true);
|
|
384
|
+
expect(bottom.showMainTickmarkLabels).toBe(true);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it('covers only the requested axis', async () => {
|
|
388
|
+
const {left, bottom} = await mount((c) => {
|
|
389
|
+
c.rangeLabels = RangeLabels.y;
|
|
390
|
+
c.width = 160;
|
|
391
|
+
c.height = 120;
|
|
392
|
+
c.data = numberData([1, 2, 3]);
|
|
393
|
+
});
|
|
394
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
395
|
+
expect(bottom.showLabels).toBe(false);
|
|
396
|
+
expect(bottom.showMainTickmarkLabels).toBe(false);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it('leaves slotted scale labels off below the threshold without rangeLabels', async () => {
|
|
400
|
+
const {left} = await mount((c) => {
|
|
401
|
+
c.width = 160;
|
|
402
|
+
c.height = 120;
|
|
403
|
+
c.data = numberData([1, 2, 3]);
|
|
404
|
+
});
|
|
405
|
+
expect(left.showLabels).toBe(false);
|
|
406
|
+
expect(left.showMainTickmarkLabels).toBe(false);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('never sets main-tickmark labels above the threshold', async () => {
|
|
410
|
+
const {left} = await mount((c) => {
|
|
411
|
+
c.rangeLabels = RangeLabels.xy;
|
|
412
|
+
c.data = numberData([1, 2, 3]);
|
|
413
|
+
});
|
|
414
|
+
expect(left.showLabels).toBe(true);
|
|
415
|
+
expect(left.showMainTickmarkLabels).toBe(false);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('follows a rangeLabels change on a mounted chart', async () => {
|
|
419
|
+
const {chart, left} = await mount((c) => {
|
|
420
|
+
c.width = 160;
|
|
421
|
+
c.height = 120;
|
|
422
|
+
c.data = numberData([1, 2, 3]);
|
|
423
|
+
});
|
|
424
|
+
chart.rangeLabels = RangeLabels.y;
|
|
425
|
+
await chart.updateComplete;
|
|
426
|
+
await frames();
|
|
427
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
describe('compact label band on slotted scales (#1191)', () => {
|
|
432
|
+
it('narrows the label band to the labels while compact, and restores it after', async () => {
|
|
433
|
+
const {chart, left, bottom} = await mount((c) => {
|
|
434
|
+
c.rangeLabels = RangeLabels.xy;
|
|
435
|
+
c.width = 160;
|
|
436
|
+
c.height = 120;
|
|
437
|
+
c.data = numberData([1, 2, 3]);
|
|
438
|
+
});
|
|
439
|
+
expect(left.labelThickness).toBeGreaterThan(8);
|
|
440
|
+
expect(left.labelThickness).toBeLessThan(60);
|
|
441
|
+
expect(bottom.labelThickness).toBeGreaterThan(8);
|
|
442
|
+
expect(bottom.labelThickness).toBeLessThan(60);
|
|
443
|
+
|
|
444
|
+
chart.rangeLabels = RangeLabels.none;
|
|
445
|
+
await chart.updateComplete;
|
|
446
|
+
await frames();
|
|
447
|
+
expect(left.labelThickness).toBe(60);
|
|
448
|
+
expect(bottom.labelThickness).toBe(60);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
it('keeps a consumer band untouched when nothing is compact', async () => {
|
|
452
|
+
const {left} = await mount((c) => {
|
|
453
|
+
c.width = 160;
|
|
454
|
+
c.height = 120;
|
|
455
|
+
c.data = numberData([1, 2, 3]);
|
|
456
|
+
});
|
|
457
|
+
expect(left.labelThickness).toBe(60);
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
describe('slotted scale padding matches the chart padding (#1191)', () => {
|
|
462
|
+
it('gives a slotted scale the padding the chart lays out with, below the threshold', async () => {
|
|
463
|
+
const {chart, left} = await mount((c) => {
|
|
464
|
+
c.rangeLabels = RangeLabels.xy;
|
|
465
|
+
c.width = 160;
|
|
466
|
+
c.height = 120;
|
|
467
|
+
c.data = numberData([1, 2, 3]);
|
|
468
|
+
});
|
|
469
|
+
const padding = chartPadding(chart);
|
|
470
|
+
expect(left.paddingTop).toBe(padding.top);
|
|
471
|
+
expect(left.paddingBottom).toBe(padding.bottom);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('keeps a gauge-trend scale level with its chart area in a compact container', async () => {
|
|
475
|
+
const host = document.createElement('div');
|
|
476
|
+
host.style.cssText = 'width: 160px';
|
|
477
|
+
document.body.appendChild(host);
|
|
478
|
+
mounted.push(host);
|
|
479
|
+
const gauge = document.createElement('obc-gauge-trend') as ObcGaugeTrend;
|
|
480
|
+
gauge.width = 160;
|
|
481
|
+
gauge.height = 160;
|
|
482
|
+
gauge.rangeLabels = RangeLabels.xy;
|
|
483
|
+
gauge.hasBar = true;
|
|
484
|
+
gauge.hasScale = true;
|
|
485
|
+
gauge.data = [45, 52, 48, 55].map((value, i) => ({
|
|
486
|
+
label: String(i),
|
|
487
|
+
value,
|
|
488
|
+
}));
|
|
489
|
+
host.appendChild(gauge);
|
|
490
|
+
await gauge.updateComplete;
|
|
491
|
+
await frames(30);
|
|
492
|
+
|
|
493
|
+
const bar = gauge.querySelector('obc-bar-vertical') as ObcBarVertical;
|
|
494
|
+
const padding = chartPadding(gauge as unknown as ObcAreaGraph);
|
|
495
|
+
const toViewBox = (px: number) =>
|
|
496
|
+
Math.round((px * gauge.scaleReferenceSize) / gauge.height);
|
|
497
|
+
expect(bar.paddingTop).toBe(toViewBox(padding.top));
|
|
498
|
+
expect(bar.paddingBottom).toBe(toViewBox(padding.bottom));
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
describe('range labels follow the data (#1191)', () => {
|
|
503
|
+
it('redraws the labels from the new extent after a data change', async () => {
|
|
504
|
+
const chart = await mountPlain(
|
|
505
|
+
(c) => {
|
|
506
|
+
c.rangeLabels = RangeLabels.y;
|
|
507
|
+
c.data = numberData([3, 7]);
|
|
508
|
+
},
|
|
509
|
+
{width: 120, height: 72}
|
|
510
|
+
);
|
|
511
|
+
expect(drawnRangeLabels(chart).map((l) => l.text)).toEqual(['7', '3']);
|
|
512
|
+
|
|
513
|
+
chart.data = numberData([10, 90]);
|
|
514
|
+
await chart.updateComplete;
|
|
515
|
+
await frames();
|
|
516
|
+
expect(drawnRangeLabels(chart).map((l) => l.text)).toEqual(['90', '10']);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
describe('scale stays level with the chart area at any container width (#1191)', () => {
|
|
521
|
+
/** The bar's drawing area on screen: its box minus its padding, scaled from viewBox units. */
|
|
522
|
+
const barDrawingArea = (bar: ObcBarVertical) => {
|
|
523
|
+
const rect = bar.getBoundingClientRect();
|
|
524
|
+
const unit = rect.height / bar.scaleReferenceSize;
|
|
525
|
+
return {
|
|
526
|
+
top: rect.top + bar.paddingTop * unit,
|
|
527
|
+
bottom: rect.bottom - bar.paddingBottom * unit,
|
|
528
|
+
};
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
for (const containerWidth of [160, 236, 300]) {
|
|
532
|
+
it(`gauge-trend at ${containerWidth}px wide, 160×128 ratio, range labels`, async () => {
|
|
533
|
+
const host = document.createElement('div');
|
|
534
|
+
host.style.cssText = `width: ${containerWidth}px`;
|
|
535
|
+
document.body.appendChild(host);
|
|
536
|
+
mounted.push(host);
|
|
537
|
+
const gauge = document.createElement('obc-gauge-trend') as ObcGaugeTrend;
|
|
538
|
+
gauge.width = 160;
|
|
539
|
+
gauge.height = 128;
|
|
540
|
+
gauge.rangeLabels = RangeLabels.xy;
|
|
541
|
+
gauge.hasBar = true;
|
|
542
|
+
gauge.hasScale = true;
|
|
543
|
+
gauge.data = [45, 52, 48, 55].map((value, i) => ({
|
|
544
|
+
label: String(i),
|
|
545
|
+
value,
|
|
546
|
+
}));
|
|
547
|
+
host.appendChild(gauge);
|
|
548
|
+
await gauge.updateComplete;
|
|
549
|
+
await frames(30);
|
|
550
|
+
|
|
551
|
+
const bar = gauge.querySelector('obc-bar-vertical') as ObcBarVertical;
|
|
552
|
+
const canvas = canvasRect(gauge as unknown as ObcAreaGraph);
|
|
553
|
+
const area = chartAreaOf(gauge as unknown as ObcAreaGraph);
|
|
554
|
+
const drawing = barDrawingArea(bar);
|
|
555
|
+
expect(
|
|
556
|
+
Math.abs(drawing.top - (canvas.top + area.top))
|
|
557
|
+
).toBeLessThanOrEqual(1);
|
|
558
|
+
expect(
|
|
559
|
+
Math.abs(drawing.bottom - (canvas.top + area.bottom))
|
|
560
|
+
).toBeLessThanOrEqual(1);
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
describe('range labels on a multi-axis chart (#1191)', () => {
|
|
566
|
+
it('labels the y side from its own datasets, not the other axis', async () => {
|
|
567
|
+
const chart = await mountPlain(
|
|
568
|
+
(c) => {
|
|
569
|
+
c.rangeLabels = RangeLabels.y;
|
|
570
|
+
c.yAxes = [
|
|
571
|
+
{id: 'y-temp', position: 'left'},
|
|
572
|
+
{id: 'y-pressure', position: 'right', min: 0, max: 10},
|
|
573
|
+
];
|
|
574
|
+
c.datasets = [
|
|
575
|
+
{label: 'T', data: [20, 30], yAxisID: 'y-temp'},
|
|
576
|
+
{label: 'P', data: [2, 3], yAxisID: 'y-pressure'},
|
|
577
|
+
];
|
|
578
|
+
},
|
|
579
|
+
{width: 120, height: 72}
|
|
580
|
+
);
|
|
581
|
+
expect(drawnRangeLabels(chart).map((l) => l.text)).toEqual(['30', '20']);
|
|
582
|
+
expect(chartRange(chart, 'y-temp')).toEqual({min: 20, max: 30});
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
describe('gauge-trend keeps its own scale range (#1214)', () => {
|
|
587
|
+
/**
|
|
588
|
+
* `chartMinValue` / `chartMaxValue` exist so the plotted range can differ from
|
|
589
|
+
* the range the bar and its ladder describe. The base pushes the chart's axis
|
|
590
|
+
* range to every slotted scale after each build, and the gauge's bar sits in
|
|
591
|
+
* `right-scale` while its only axis is left-positioned — so without an opt-out
|
|
592
|
+
* the bar is handed the chart range on the next data tick.
|
|
593
|
+
*/
|
|
594
|
+
const mountGauge = async () => {
|
|
595
|
+
const host = document.createElement('div');
|
|
596
|
+
host.style.cssText = 'width: 384px';
|
|
597
|
+
document.body.appendChild(host);
|
|
598
|
+
mounted.push(host);
|
|
599
|
+
const gauge = document.createElement('obc-gauge-trend') as ObcGaugeTrend;
|
|
600
|
+
gauge.width = 384;
|
|
601
|
+
gauge.height = 384;
|
|
602
|
+
gauge.hasBar = true;
|
|
603
|
+
gauge.hasScale = true;
|
|
604
|
+
gauge.minValue = 0;
|
|
605
|
+
gauge.maxValue = 100;
|
|
606
|
+
gauge.chartMinValue = 20;
|
|
607
|
+
gauge.chartMaxValue = 80;
|
|
608
|
+
gauge.value = 50;
|
|
609
|
+
gauge.data = [45, 52, 48, 55].map((value, i) => ({
|
|
610
|
+
label: String(i),
|
|
611
|
+
value,
|
|
612
|
+
}));
|
|
613
|
+
host.appendChild(gauge);
|
|
614
|
+
await gauge.updateComplete;
|
|
615
|
+
await frames(30);
|
|
616
|
+
return gauge;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
it('holds minValue/maxValue on the bar when the chart range differs', async () => {
|
|
620
|
+
const gauge = await mountGauge();
|
|
621
|
+
const bar = gauge.querySelector('obc-bar-vertical') as ObcBarVertical;
|
|
622
|
+
expect([bar.minValue, bar.maxValue]).toEqual([0, 100]);
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('holds them through a data change', async () => {
|
|
626
|
+
const gauge = await mountGauge();
|
|
627
|
+
const bar = gauge.querySelector('obc-bar-vertical') as ObcBarVertical;
|
|
628
|
+
|
|
629
|
+
gauge.data = [10, 70, 30, 65].map((value, i) => ({
|
|
630
|
+
label: String(i),
|
|
631
|
+
value,
|
|
632
|
+
}));
|
|
633
|
+
await gauge.updateComplete;
|
|
634
|
+
await frames(30);
|
|
635
|
+
|
|
636
|
+
expect([bar.minValue, bar.maxValue]).toEqual([0, 100]);
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
it('still plots on the chart range', async () => {
|
|
640
|
+
const gauge = await mountGauge();
|
|
641
|
+
expect(chartRange(gauge as unknown as ObcAreaGraph, 'y')).toEqual({
|
|
642
|
+
min: 20,
|
|
643
|
+
max: 80,
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
describe('slotted scale keeps its own main-tickmark labels (#1191)', () => {
|
|
649
|
+
/**
|
|
650
|
+
* Compact mode borrows the flag to label a short scale; a scale the chart
|
|
651
|
+
* never compacted must keep the value its consumer set.
|
|
652
|
+
*/
|
|
653
|
+
const mountWithLeft = async (
|
|
654
|
+
size: {width: number; height: number},
|
|
655
|
+
configureBar: (bar: ObcBarVertical) => void
|
|
656
|
+
) => {
|
|
657
|
+
document.documentElement.classList.add('obc-component-size-regular');
|
|
658
|
+
const host = document.createElement('div');
|
|
659
|
+
host.style.cssText = `width: ${size.width}px`;
|
|
660
|
+
document.body.appendChild(host);
|
|
661
|
+
mounted.push(host);
|
|
662
|
+
|
|
663
|
+
const chart = document.createElement('obc-area-graph');
|
|
664
|
+
chart.width = size.width;
|
|
665
|
+
chart.height = size.height;
|
|
666
|
+
chart.data = numberData([3, 7]);
|
|
667
|
+
|
|
668
|
+
const left = document.createElement('obc-bar-vertical') as ObcBarVertical;
|
|
669
|
+
left.slot = 'left-scale';
|
|
670
|
+
left.side = ExternalScaleSide.left;
|
|
671
|
+
configureBar(left);
|
|
672
|
+
chart.appendChild(left);
|
|
673
|
+
|
|
674
|
+
host.appendChild(chart);
|
|
675
|
+
await chart.updateComplete;
|
|
676
|
+
await frames(20);
|
|
677
|
+
return {chart, left};
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
it('leaves an opted-in scale alone above the threshold', async () => {
|
|
681
|
+
const {left} = await mountWithLeft({width: 600, height: 300}, (bar) => {
|
|
682
|
+
bar.showMainTickmarkLabels = true;
|
|
683
|
+
});
|
|
684
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('restores the consumer value after a compact spell', async () => {
|
|
688
|
+
const {chart, left} = await mountWithLeft(
|
|
689
|
+
{width: 600, height: 300},
|
|
690
|
+
(bar) => {
|
|
691
|
+
bar.showMainTickmarkLabels = true;
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
chart.rangeLabels = RangeLabels.y;
|
|
696
|
+
chart.height = 120;
|
|
697
|
+
await chart.updateComplete;
|
|
698
|
+
await frames(20);
|
|
699
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
700
|
+
|
|
701
|
+
chart.height = 300;
|
|
702
|
+
await chart.updateComplete;
|
|
703
|
+
await frames(20);
|
|
704
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
it('returns a scale that never opted in to false after compacting', async () => {
|
|
708
|
+
const {chart, left} = await mountWithLeft(
|
|
709
|
+
{width: 600, height: 300},
|
|
710
|
+
() => {}
|
|
711
|
+
);
|
|
712
|
+
|
|
713
|
+
chart.rangeLabels = RangeLabels.y;
|
|
714
|
+
chart.height = 120;
|
|
715
|
+
await chart.updateComplete;
|
|
716
|
+
await frames(20);
|
|
717
|
+
expect(left.showMainTickmarkLabels).toBe(true);
|
|
718
|
+
|
|
719
|
+
chart.height = 300;
|
|
720
|
+
await chart.updateComplete;
|
|
721
|
+
await frames(20);
|
|
722
|
+
expect(left.showMainTickmarkLabels).toBe(false);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* In pixel mode a size change does not go through `updateComputedDimensions()`,
|
|
727
|
+
* so before the threshold-crossing branch the cascade never re-ran and the
|
|
728
|
+
* scale kept its compact band after the chart grew back.
|
|
729
|
+
*/
|
|
730
|
+
it('gives the band back when the chart grows past the threshold', async () => {
|
|
731
|
+
const {chart, left} = await mountWithLeft(
|
|
732
|
+
{width: 600, height: 120},
|
|
733
|
+
() => {}
|
|
734
|
+
);
|
|
735
|
+
chart.rangeLabels = RangeLabels.y;
|
|
736
|
+
await chart.updateComplete;
|
|
737
|
+
await frames(20);
|
|
738
|
+
expect(left.labelThickness).toBeLessThan(60);
|
|
739
|
+
|
|
740
|
+
chart.height = 300;
|
|
741
|
+
await chart.updateComplete;
|
|
742
|
+
await frames(30);
|
|
743
|
+
expect(left.labelThickness).toBe(60);
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
describe('range labels on a stacked chart (#1191)', () => {
|
|
748
|
+
it('labels the accumulated range, not the widest series', async () => {
|
|
749
|
+
const chart = await mountPlain(
|
|
750
|
+
(c) => {
|
|
751
|
+
c.rangeLabels = RangeLabels.y;
|
|
752
|
+
(c as ObcAreaGraph & {stacked: boolean}).stacked = true;
|
|
753
|
+
c.datasets = [
|
|
754
|
+
{label: 'A', data: [10, 20, 15]},
|
|
755
|
+
{label: 'B', data: [30, 40, 35]},
|
|
756
|
+
];
|
|
757
|
+
},
|
|
758
|
+
{width: 120, height: 72}
|
|
759
|
+
);
|
|
760
|
+
|
|
761
|
+
const {min, max} = chartRange(chart, 'y');
|
|
762
|
+
expect(drawnRangeLabels(chart).map((l) => l.text)).toEqual([
|
|
763
|
+
String(max),
|
|
764
|
+
String(min),
|
|
765
|
+
]);
|
|
766
|
+
});
|
|
767
|
+
});
|