@circutor/charts 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundler/itic-chart.js +1 -1
- package/dist/charts/charts.esm.js +1 -1
- package/dist/charts/p-7d11d611.entry.js +25 -0
- package/dist/cjs/charts.cjs.js +1 -1
- package/dist/cjs/itic-chart.cjs.entry.js +450 -100
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/itic-chart/index.js +56 -55
- package/dist/collection/components/itic-chart/itic-chart.i18n.js +26 -0
- package/dist/collection/components/itic-chart/itic-chart.options.js +99 -42
- package/dist/collection/components/itic-chart/itic-chart.phases.js +55 -0
- package/dist/components/itic-chart.js +2 -2
- package/dist/esm/charts.js +1 -1
- package/dist/esm/itic-chart.entry.js +450 -100
- package/dist/esm/loader.js +1 -1
- package/dist/types/components/itic-chart/index.d.ts +18 -14
- package/dist/types/components/itic-chart/itic-chart.i18n.d.ts +13 -0
- package/dist/types/components/itic-chart/itic-chart.options.d.ts +32 -17
- package/dist/types/components/itic-chart/itic-chart.phases.d.ts +17 -0
- package/dist/types/components.d.ts +18 -28
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -5
- package/readme.md +138 -73
- package/dist/charts/p-943aa343.entry.js +0 -25
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -6,7 +6,7 @@ var appGlobals = require('./app-globals-V2Kpy_OQ.js');
|
|
|
6
6
|
const defineCustomElements = async (win, options) => {
|
|
7
7
|
if (typeof window === 'undefined') return undefined;
|
|
8
8
|
await appGlobals.globalScripts();
|
|
9
|
-
return index.bootstrapLazy([["itic-chart.cjs",[[1,"itic-chart",{"groups":[1],"
|
|
9
|
+
return index.bootstrapLazy([["itic-chart.cjs",[[1,"itic-chart",{"groups":[1],"locale":[1],"timeZone":[1,"time-zone"]},null,{"groups":[{"onGroupsChange":0}],"locale":[{"onLocaleChange":0}],"timeZone":[{"onTimeZoneChange":0}]}]]]], options);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
exports.setNonce = index.setNonce;
|
|
@@ -3,22 +3,28 @@ import * as echarts from "echarts/core";
|
|
|
3
3
|
import { LineChart, ScatterChart } from "echarts/charts";
|
|
4
4
|
import { GridComponent, LegendComponent, TooltipComponent } from "echarts/components";
|
|
5
5
|
import { CanvasRenderer } from "echarts/renderers";
|
|
6
|
-
import {
|
|
6
|
+
import { getMessages, normalizeLocale } from "./itic-chart.i18n";
|
|
7
|
+
import { buildChartOptions, findClickedPoint, isValidTimeZone, parseGroups, } from "./itic-chart.options";
|
|
7
8
|
// Register only what this chart uses, so bundles don't ship all of ECharts
|
|
8
9
|
echarts.use([LineChart, ScatterChart, GridComponent, LegendComponent, TooltipComponent, CanvasRenderer]);
|
|
9
10
|
export class IticChart {
|
|
10
11
|
constructor() {
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* Language of the texts, dates and numbers: `ca`, `de`, `en`, `es`, `fr` or `pt`. Only the language
|
|
14
|
+
* is used (`es-ES` → `es`); any other value falls back to `en`.
|
|
13
15
|
*/
|
|
14
|
-
this.
|
|
15
|
-
/**
|
|
16
|
-
* Name of the voltage (Y) axis.
|
|
17
|
-
*/
|
|
18
|
-
this.yAxisName = DEFAULT_SETTINGS.yAxisName;
|
|
16
|
+
this.locale = 'en';
|
|
19
17
|
this.parsedGroups = [];
|
|
20
18
|
}
|
|
21
|
-
|
|
19
|
+
onGroupsChange() {
|
|
20
|
+
this.updateChart();
|
|
21
|
+
}
|
|
22
|
+
onLocaleChange() {
|
|
23
|
+
this.updateAriaLabel();
|
|
24
|
+
this.updateChart();
|
|
25
|
+
}
|
|
26
|
+
onTimeZoneChange() {
|
|
27
|
+
this.validateTimeZone();
|
|
22
28
|
this.updateChart();
|
|
23
29
|
}
|
|
24
30
|
connectedCallback() {
|
|
@@ -26,9 +32,13 @@ export class IticChart {
|
|
|
26
32
|
if (!this.el.hasAttribute('role')) {
|
|
27
33
|
this.el.setAttribute('role', 'img');
|
|
28
34
|
}
|
|
35
|
+
this.updateAriaLabel();
|
|
29
36
|
// componentDidLoad only fires once, so re-create the chart when the element is re-attached
|
|
30
37
|
this.initChart();
|
|
31
38
|
}
|
|
39
|
+
componentWillLoad() {
|
|
40
|
+
this.validateTimeZone();
|
|
41
|
+
}
|
|
32
42
|
componentDidLoad() {
|
|
33
43
|
this.initChart();
|
|
34
44
|
}
|
|
@@ -39,6 +49,27 @@ export class IticChart {
|
|
|
39
49
|
(_b = this.chart) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
40
50
|
this.chart = undefined;
|
|
41
51
|
}
|
|
52
|
+
updateAriaLabel() {
|
|
53
|
+
const current = this.el.getAttribute('aria-label');
|
|
54
|
+
if (current !== null && current !== this.defaultAriaLabel) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.defaultAriaLabel = getMessages(normalizeLocale(this.locale)).ariaLabel;
|
|
58
|
+
this.el.setAttribute('aria-label', this.defaultAriaLabel);
|
|
59
|
+
}
|
|
60
|
+
// Validated when it changes, not on every redraw, so an invalid value is only reported once
|
|
61
|
+
validateTimeZone() {
|
|
62
|
+
this.validTimeZone = undefined;
|
|
63
|
+
if (!this.timeZone) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (isValidTimeZone(this.timeZone)) {
|
|
67
|
+
this.validTimeZone = this.timeZone;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
console.error(`[itic-chart] Invalid "timeZone" prop: "${this.timeZone}". Using the browser's time zone.`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
42
73
|
initChart() {
|
|
43
74
|
if (!this.container || this.chart) {
|
|
44
75
|
return;
|
|
@@ -57,7 +88,6 @@ export class IticChart {
|
|
|
57
88
|
this.updateChart();
|
|
58
89
|
}
|
|
59
90
|
updateChart() {
|
|
60
|
-
var _a;
|
|
61
91
|
if (!this.chart) {
|
|
62
92
|
return;
|
|
63
93
|
}
|
|
@@ -69,14 +99,13 @@ export class IticChart {
|
|
|
69
99
|
console.error('[itic-chart] Invalid "groups" prop:', error);
|
|
70
100
|
}
|
|
71
101
|
const options = buildChartOptions(this.parsedGroups, {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
tooltipFormatter: (_a = this.tooltipFormatter) !== null && _a !== void 0 ? _a : DEFAULT_SETTINGS.tooltipFormatter,
|
|
102
|
+
locale: normalizeLocale(this.locale),
|
|
103
|
+
timeZone: this.validTimeZone,
|
|
75
104
|
});
|
|
76
105
|
this.chart.setOption(options, { notMerge: true });
|
|
77
106
|
}
|
|
78
107
|
render() {
|
|
79
|
-
return h("div", { key: '
|
|
108
|
+
return h("div", { key: '2bb964d590a36c9c9501761c3f848ad364a29030', class: "chart", ref: el => (this.container = el) });
|
|
80
109
|
}
|
|
81
110
|
static get is() { return "itic-chart"; }
|
|
82
111
|
static get encapsulation() { return "shadow"; }
|
|
@@ -111,14 +140,14 @@ export class IticChart {
|
|
|
111
140
|
"optional": false,
|
|
112
141
|
"docs": {
|
|
113
142
|
"tags": [],
|
|
114
|
-
"text": "Point groups, as an array or a JSON string.
|
|
143
|
+
"text": "Point groups, as an array or a JSON string. Each group's `phase` code sets its name, color and order.\nExtra fields in groups and points are kept and passed back in `pointClick`."
|
|
115
144
|
},
|
|
116
145
|
"getter": false,
|
|
117
146
|
"setter": false,
|
|
118
147
|
"reflect": false,
|
|
119
148
|
"attribute": "groups"
|
|
120
149
|
},
|
|
121
|
-
"
|
|
150
|
+
"locale": {
|
|
122
151
|
"type": "string",
|
|
123
152
|
"mutable": false,
|
|
124
153
|
"complexType": {
|
|
@@ -130,15 +159,15 @@ export class IticChart {
|
|
|
130
159
|
"optional": false,
|
|
131
160
|
"docs": {
|
|
132
161
|
"tags": [],
|
|
133
|
-
"text": "
|
|
162
|
+
"text": "Language of the texts, dates and numbers: `ca`, `de`, `en`, `es`, `fr` or `pt`. Only the language\nis used (`es-ES` \u2192 `es`); any other value falls back to `en`."
|
|
134
163
|
},
|
|
135
164
|
"getter": false,
|
|
136
165
|
"setter": false,
|
|
137
166
|
"reflect": false,
|
|
138
|
-
"attribute": "
|
|
139
|
-
"defaultValue": "'
|
|
167
|
+
"attribute": "locale",
|
|
168
|
+
"defaultValue": "'en'"
|
|
140
169
|
},
|
|
141
|
-
"
|
|
170
|
+
"timeZone": {
|
|
142
171
|
"type": "string",
|
|
143
172
|
"mutable": false,
|
|
144
173
|
"complexType": {
|
|
@@ -147,40 +176,15 @@ export class IticChart {
|
|
|
147
176
|
"references": {}
|
|
148
177
|
},
|
|
149
178
|
"required": false,
|
|
150
|
-
"optional":
|
|
179
|
+
"optional": true,
|
|
151
180
|
"docs": {
|
|
152
181
|
"tags": [],
|
|
153
|
-
"text": "
|
|
182
|
+
"text": "IANA time zone of the dates in the tooltip (e.g. `Europe/Madrid`). Defaults to the browser's,\nwhich is also used, with a console error, when the value isn't valid."
|
|
154
183
|
},
|
|
155
184
|
"getter": false,
|
|
156
185
|
"setter": false,
|
|
157
186
|
"reflect": false,
|
|
158
|
-
"attribute": "
|
|
159
|
-
"defaultValue": "'Voltage (% of nominal voltage)'"
|
|
160
|
-
},
|
|
161
|
-
"tooltipFormatter": {
|
|
162
|
-
"type": "unknown",
|
|
163
|
-
"mutable": false,
|
|
164
|
-
"complexType": {
|
|
165
|
-
"original": "ITICTooltipFormatter",
|
|
166
|
-
"resolved": "(point: ITICPoint, group: ITICChartMarks) => string",
|
|
167
|
-
"references": {
|
|
168
|
-
"ITICTooltipFormatter": {
|
|
169
|
-
"location": "import",
|
|
170
|
-
"path": "./itic-chart.options",
|
|
171
|
-
"id": "src/components/itic-chart/itic-chart.options.ts::ITICTooltipFormatter",
|
|
172
|
-
"referenceLocation": "ITICTooltipFormatter"
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
"required": false,
|
|
177
|
-
"optional": true,
|
|
178
|
-
"docs": {
|
|
179
|
-
"tags": [],
|
|
180
|
-
"text": "Returns the HTML of a point's tooltip. JS/React property only (not an HTML attribute).\nThe HTML is inserted as is: escaping the values is up to the formatter.\nDefaults to an English tooltip with phase, duration, voltage and timestamp."
|
|
181
|
-
},
|
|
182
|
-
"getter": false,
|
|
183
|
-
"setter": false
|
|
187
|
+
"attribute": "time-zone"
|
|
184
188
|
}
|
|
185
189
|
};
|
|
186
190
|
}
|
|
@@ -213,16 +217,13 @@ export class IticChart {
|
|
|
213
217
|
static get watchers() {
|
|
214
218
|
return [{
|
|
215
219
|
"propName": "groups",
|
|
216
|
-
"methodName": "
|
|
217
|
-
}, {
|
|
218
|
-
"propName": "xAxisName",
|
|
219
|
-
"methodName": "onOptionsChange"
|
|
220
|
+
"methodName": "onGroupsChange"
|
|
220
221
|
}, {
|
|
221
|
-
"propName": "
|
|
222
|
-
"methodName": "
|
|
222
|
+
"propName": "locale",
|
|
223
|
+
"methodName": "onLocaleChange"
|
|
223
224
|
}, {
|
|
224
|
-
"propName": "
|
|
225
|
-
"methodName": "
|
|
225
|
+
"propName": "timeZone",
|
|
226
|
+
"methodName": "onTimeZoneChange"
|
|
226
227
|
}];
|
|
227
228
|
}
|
|
228
229
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import ca from "./i18n/ca.json";
|
|
2
|
+
import de from "./i18n/de.json";
|
|
3
|
+
import en from "./i18n/en.json";
|
|
4
|
+
import es from "./i18n/es.json";
|
|
5
|
+
import fr from "./i18n/fr.json";
|
|
6
|
+
import pt from "./i18n/pt.json";
|
|
7
|
+
export const LOCALES = ['ca', 'de', 'en', 'es', 'fr', 'pt'];
|
|
8
|
+
export const DEFAULT_LOCALE = 'en';
|
|
9
|
+
const MESSAGES = { ca, de, en, es, fr, pt };
|
|
10
|
+
/** Keeps the language of a locale (`es-ES` → `es`), falling back to `en` when it isn't translated. */
|
|
11
|
+
export function normalizeLocale(locale) {
|
|
12
|
+
const language = String(locale !== null && locale !== void 0 ? locale : '')
|
|
13
|
+
.split(/[-_]/)[0]
|
|
14
|
+
.toLowerCase();
|
|
15
|
+
return LOCALES.includes(language) ? language : DEFAULT_LOCALE;
|
|
16
|
+
}
|
|
17
|
+
export const getMessages = (locale) => MESSAGES[locale];
|
|
18
|
+
const hasOwn = (object, key) => Object.prototype.hasOwnProperty.call(object, key);
|
|
19
|
+
/** Translated event type, or the code as is when it isn't in the catalog. */
|
|
20
|
+
export function translateEventType(messages, code) {
|
|
21
|
+
return hasOwn(messages.eventTypes, code) ? messages.eventTypes[code] : code;
|
|
22
|
+
}
|
|
23
|
+
/** Translated name of a phase code that has one (`ALL`, `NONE`), or `undefined`. */
|
|
24
|
+
export function translatePhase(messages, code) {
|
|
25
|
+
return hasOwn(messages.phases, code) ? messages.phases[code] : undefined;
|
|
26
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { DEFAULT_LOCALE, getMessages, translateEventType } from "./itic-chart.i18n";
|
|
2
|
+
import { getPhase, sortGroups } from "./itic-chart.phases";
|
|
3
|
+
export const DEFAULT_SETTINGS = { locale: DEFAULT_LOCALE };
|
|
2
4
|
/**
|
|
3
5
|
* Normalizes the `groups` prop, which arrives as an array from JS/React
|
|
4
6
|
* or as a JSON string when set as an HTML attribute.
|
|
@@ -13,6 +15,15 @@ export function parseGroups(groups) {
|
|
|
13
15
|
}
|
|
14
16
|
return parsed;
|
|
15
17
|
}
|
|
18
|
+
export function isValidTimeZone(timeZone) {
|
|
19
|
+
try {
|
|
20
|
+
new Intl.DateTimeFormat('en', { timeZone });
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch (_a) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
16
27
|
export function escapeHtml(value) {
|
|
17
28
|
return value
|
|
18
29
|
.replace(/&/g, '&')
|
|
@@ -21,57 +32,95 @@ export function escapeHtml(value) {
|
|
|
21
32
|
.replace(/"/g, '"')
|
|
22
33
|
.replace(/'/g, ''');
|
|
23
34
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
const isBlank = (value) => value == null || value === '';
|
|
36
|
+
/**
|
|
37
|
+
* Returns the tooltip HTML of a point: one row per field, in the chart's language. Rows without a value
|
|
38
|
+
* are left out, and every value is escaped, since it comes from the consumer's data.
|
|
39
|
+
*/
|
|
40
|
+
export function createTooltipFormatter({ locale, timeZone }) {
|
|
41
|
+
const messages = getMessages(locale);
|
|
42
|
+
const dateFormat = new Intl.DateTimeFormat(locale, {
|
|
43
|
+
day: '2-digit',
|
|
44
|
+
month: 'short',
|
|
45
|
+
hour: '2-digit',
|
|
46
|
+
minute: '2-digit',
|
|
47
|
+
second: '2-digit',
|
|
48
|
+
// Short events are milliseconds apart
|
|
49
|
+
fractionalSecondDigits: 3,
|
|
50
|
+
hourCycle: 'h23',
|
|
51
|
+
timeZone,
|
|
52
|
+
});
|
|
53
|
+
const durationFormat = new Intl.NumberFormat(locale, { style: 'unit', unit: 'millisecond', maximumFractionDigits: 3 });
|
|
54
|
+
const voltageFormat = new Intl.NumberFormat(locale, { style: 'percent', maximumFractionDigits: 1 });
|
|
55
|
+
// `volt` isn't a unit supported by Intl
|
|
56
|
+
const voltsFormat = new Intl.NumberFormat(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
57
|
+
const formatDate = (ts) => {
|
|
58
|
+
const date = new Date(ts);
|
|
59
|
+
return Number.isNaN(date.getTime()) ? String(ts !== null && ts !== void 0 ? ts : '') : dateFormat.format(date);
|
|
31
60
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
const formatVolts = (value) => (Number(value) ? `${voltsFormat.format(Number(value))} V` : undefined);
|
|
62
|
+
return (point, group) => {
|
|
63
|
+
const rows = [
|
|
64
|
+
['asset', isBlank(group.assetName) ? undefined : String(group.assetName)],
|
|
65
|
+
['date', formatDate(point.ts)],
|
|
66
|
+
['eventType', isBlank(point.eventType) ? undefined : translateEventType(messages, String(point.eventType))],
|
|
67
|
+
['duration', durationFormat.format(Number(point.duration))],
|
|
68
|
+
// The value is already in %
|
|
69
|
+
['voltage', voltageFormat.format(Number(point.voltage) / 100)],
|
|
70
|
+
['status', isBlank(point.status) ? undefined : String(point.status)],
|
|
71
|
+
['phase', getPhase(group.phase, messages).name || '-'],
|
|
72
|
+
['min', formatVolts(point.min)],
|
|
73
|
+
['max', formatVolts(point.max)],
|
|
74
|
+
];
|
|
75
|
+
return rows
|
|
76
|
+
.filter((row) => row[1] !== undefined)
|
|
77
|
+
.map(([key, value]) => ` <strong>${messages.tooltip[key]}</strong>: ${escapeHtml(value)}`)
|
|
78
|
+
.join('<br/>');
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Formats the axis labels in the chart's language; ECharts always uses English separators. */
|
|
82
|
+
export function createAxisLabelFormatter(locale) {
|
|
83
|
+
const numberFormat = new Intl.NumberFormat(locale);
|
|
84
|
+
return value => numberFormat.format(value);
|
|
85
|
+
}
|
|
41
86
|
export const isClickable = (point) => point.clickable !== false;
|
|
42
87
|
export function buildChartOptions(groups, settings = DEFAULT_SETTINGS) {
|
|
43
|
-
|
|
88
|
+
const messages = getMessages(settings.locale);
|
|
89
|
+
const formatTooltip = createTooltipFormatter(settings);
|
|
90
|
+
const axisLabel = { formatter: createAxisLabelFormatter(settings.locale) };
|
|
91
|
+
return Object.assign(Object.assign({}, BASE_OPTIONS), { xAxis: Object.assign(Object.assign({}, BASE_OPTIONS.xAxis), { name: messages.xAxisName, axisLabel }), yAxis: Object.assign(Object.assign({}, BASE_OPTIONS.yAxis), { name: messages.yAxisName, axisLabel }), series: [
|
|
44
92
|
...CURVE_SERIES,
|
|
45
|
-
...groups.map((group) =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
93
|
+
...sortGroups(groups).map((group) => {
|
|
94
|
+
const { name, color } = getPhase(group.phase, messages);
|
|
95
|
+
return {
|
|
96
|
+
type: 'scatter',
|
|
97
|
+
name,
|
|
98
|
+
// ECharts 6 reads `cursor` per data item, although its types only declare it per series
|
|
99
|
+
data: group.points.map(point => ({
|
|
100
|
+
value: [point.duration, point.voltage],
|
|
101
|
+
cursor: isClickable(point) ? 'pointer' : 'default',
|
|
102
|
+
})),
|
|
103
|
+
symbolSize: 12,
|
|
104
|
+
z: 4,
|
|
105
|
+
// Phases without a color take the next one of the ECharts palette
|
|
106
|
+
itemStyle: color ? { color, opacity: 1 } : { opacity: 1 },
|
|
107
|
+
tooltip: {
|
|
108
|
+
formatter: params => formatTooltip(group.points[params.dataIndex], group),
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}),
|
|
63
112
|
] });
|
|
64
113
|
}
|
|
65
114
|
/**
|
|
66
|
-
* Maps an ECharts click back to the original point and group
|
|
67
|
-
* scatter series after the ITIC curve series,
|
|
115
|
+
* Maps an ECharts click back to the original point and group. `buildChartOptions` draws the groups as
|
|
116
|
+
* scatter series after the ITIC curve series, sorted with `sortGroups`.
|
|
68
117
|
* Returns `undefined` for clicks outside the points and on points that aren't clickable.
|
|
69
118
|
*/
|
|
70
119
|
export function findClickedPoint(groups, { componentType, seriesIndex, dataIndex }) {
|
|
71
120
|
if (componentType !== 'series' || seriesIndex == null || dataIndex == null) {
|
|
72
121
|
return undefined;
|
|
73
122
|
}
|
|
74
|
-
const group = groups[seriesIndex - CURVE_SERIES.length];
|
|
123
|
+
const group = sortGroups(groups)[seriesIndex - CURVE_SERIES.length];
|
|
75
124
|
const point = group === null || group === void 0 ? void 0 : group.points[dataIndex];
|
|
76
125
|
if (!point || !isClickable(point)) {
|
|
77
126
|
return undefined;
|
|
@@ -96,10 +145,11 @@ const ITIC_CURVE_NODAMAGE_REGION = [
|
|
|
96
145
|
[10000, 90],
|
|
97
146
|
[100000, 90],
|
|
98
147
|
];
|
|
148
|
+
// Fixed ranges, as in Scout: ECharts clips points outside them (duration < 1 ms or voltage > 200%)
|
|
99
149
|
const BASE_OPTIONS = {
|
|
100
150
|
animation: false,
|
|
101
151
|
grid: {
|
|
102
|
-
right: '
|
|
152
|
+
right: '20px',
|
|
103
153
|
left: '60px',
|
|
104
154
|
},
|
|
105
155
|
// ECharts 6 moved the default legend to the bottom; keep it on top as in previous versions
|
|
@@ -111,7 +161,7 @@ const BASE_OPTIONS = {
|
|
|
111
161
|
},
|
|
112
162
|
xAxis: {
|
|
113
163
|
type: 'log',
|
|
114
|
-
min:
|
|
164
|
+
min: 1,
|
|
115
165
|
max: 100000,
|
|
116
166
|
nameGap: 30,
|
|
117
167
|
nameLocation: 'middle',
|
|
@@ -123,7 +173,7 @@ const BASE_OPTIONS = {
|
|
|
123
173
|
yAxis: {
|
|
124
174
|
type: 'value',
|
|
125
175
|
min: 0,
|
|
126
|
-
max:
|
|
176
|
+
max: 200,
|
|
127
177
|
nameTextStyle: {
|
|
128
178
|
fontSize: 16,
|
|
129
179
|
fontWeight: 'bold',
|
|
@@ -133,6 +183,7 @@ const BASE_OPTIONS = {
|
|
|
133
183
|
nameLocation: 'middle',
|
|
134
184
|
},
|
|
135
185
|
};
|
|
186
|
+
// `silent`: the curve doesn't react to the mouse (no tooltip, cursor or click)
|
|
136
187
|
const CURVE_SERIES = [
|
|
137
188
|
{
|
|
138
189
|
type: 'line',
|
|
@@ -144,6 +195,7 @@ const CURVE_SERIES = [
|
|
|
144
195
|
lineStyle: {
|
|
145
196
|
color: '#000',
|
|
146
197
|
},
|
|
198
|
+
silent: true,
|
|
147
199
|
showSymbol: false,
|
|
148
200
|
emphasis: {
|
|
149
201
|
disabled: true,
|
|
@@ -156,6 +208,7 @@ const CURVE_SERIES = [
|
|
|
156
208
|
origin: 'start',
|
|
157
209
|
color: '#FFF5DF',
|
|
158
210
|
},
|
|
211
|
+
silent: true,
|
|
159
212
|
showSymbol: false,
|
|
160
213
|
lineStyle: {
|
|
161
214
|
color: '#000',
|
|
@@ -171,6 +224,7 @@ const CURVE_SERIES = [
|
|
|
171
224
|
origin: 100,
|
|
172
225
|
color: '#DDFAF1',
|
|
173
226
|
},
|
|
227
|
+
silent: true,
|
|
174
228
|
showSymbol: false,
|
|
175
229
|
lineStyle: {
|
|
176
230
|
color: '#000',
|
|
@@ -186,6 +240,7 @@ const CURVE_SERIES = [
|
|
|
186
240
|
origin: 100,
|
|
187
241
|
color: '#DDFAF1',
|
|
188
242
|
},
|
|
243
|
+
silent: true,
|
|
189
244
|
showSymbol: false,
|
|
190
245
|
lineStyle: {
|
|
191
246
|
color: '#000',
|
|
@@ -204,6 +259,7 @@ const CURVE_SERIES = [
|
|
|
204
259
|
origin: 100,
|
|
205
260
|
color: '#DDFAF1',
|
|
206
261
|
},
|
|
262
|
+
silent: true,
|
|
207
263
|
showSymbol: false,
|
|
208
264
|
lineStyle: {
|
|
209
265
|
color: 'transparent',
|
|
@@ -222,6 +278,7 @@ const CURVE_SERIES = [
|
|
|
222
278
|
origin: 100,
|
|
223
279
|
color: '#DDFAF1',
|
|
224
280
|
},
|
|
281
|
+
silent: true,
|
|
225
282
|
showSymbol: false,
|
|
226
283
|
lineStyle: {
|
|
227
284
|
color: 'transparent',
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { translatePhase } from "./itic-chart.i18n";
|
|
2
|
+
const L1 = '#a67c52';
|
|
3
|
+
const L2 = '#20262C';
|
|
4
|
+
const L3 = '#B9BDC0';
|
|
5
|
+
const THREE_PHASE = '#00B388';
|
|
6
|
+
// Same catalog as Scout. Names that change with the language (`ALL`, `NONE`) are in the i18n JSON files.
|
|
7
|
+
const PHASES = {
|
|
8
|
+
AN: { name: 'L1', color: L1 },
|
|
9
|
+
BN: { name: 'L2', color: L2 },
|
|
10
|
+
CN: { name: 'L3', color: L3 },
|
|
11
|
+
AB: { name: 'L1', color: L1 },
|
|
12
|
+
BC: { name: 'L2', color: L2 },
|
|
13
|
+
CA: { name: 'L3', color: L3 },
|
|
14
|
+
'AN,BN,CN': { name: 'L1,L2,L3', color: THREE_PHASE },
|
|
15
|
+
'AB,BC,CA': { name: 'L1,L2,L3', color: THREE_PHASE },
|
|
16
|
+
ALL: { name: '', color: '#4C5CC5' },
|
|
17
|
+
A: { name: 'L1' },
|
|
18
|
+
B: { name: 'L2' },
|
|
19
|
+
C: { name: 'L3' },
|
|
20
|
+
'AN,BN': { name: 'L1,L2' },
|
|
21
|
+
'AN,CN': { name: 'L1,L3' },
|
|
22
|
+
'BN,CN': { name: 'L2,L3' },
|
|
23
|
+
'AB,BC': { name: 'L1,L2' },
|
|
24
|
+
'AB,CA': { name: 'L1,L3' },
|
|
25
|
+
'BC,CA': { name: 'L2,L3' },
|
|
26
|
+
NONE: { name: '' },
|
|
27
|
+
};
|
|
28
|
+
const phaseCode = (phase) => (phase == null ? '' : String(phase));
|
|
29
|
+
// Unknown codes keep the code as name and have no color
|
|
30
|
+
const catalogPhase = (code) => Object.prototype.hasOwnProperty.call(PHASES, code) ? PHASES[code] : { name: code };
|
|
31
|
+
/** Name, in the given language, and color of a phase code. */
|
|
32
|
+
export function getPhase(phase, messages) {
|
|
33
|
+
var _a;
|
|
34
|
+
const code = phaseCode(phase);
|
|
35
|
+
const known = catalogPhase(code);
|
|
36
|
+
return Object.assign(Object.assign({}, known), { name: (_a = translatePhase(messages, code)) !== null && _a !== void 0 ? _a : known.name });
|
|
37
|
+
}
|
|
38
|
+
// `NONE` (no name) goes after the named phases and `ALL` always last. Only these two names are translated,
|
|
39
|
+
// so ranking them by code keeps the order the same in every language.
|
|
40
|
+
const rank = (code) => (code === 'ALL' ? 2 : code === 'NONE' ? 1 : 0);
|
|
41
|
+
/**
|
|
42
|
+
* Sorts groups by phase name, then by code (e.g. `AN` and `AB` are both "L1"), with `NONE` and `ALL` last.
|
|
43
|
+
* Compares characters, not with a locale's rules, so the legend is the same in every language.
|
|
44
|
+
* Returns a new array with the same group objects; groups with the same code keep their order.
|
|
45
|
+
*/
|
|
46
|
+
export function sortGroups(groups) {
|
|
47
|
+
const keyed = groups.map(group => {
|
|
48
|
+
const code = phaseCode(group.phase);
|
|
49
|
+
return { group, code, rank: rank(code), name: catalogPhase(code).name };
|
|
50
|
+
});
|
|
51
|
+
return keyed
|
|
52
|
+
.sort((a, b) => a.rank - b.rank || compare(a.name, b.name) || compare(a.code, b.code))
|
|
53
|
+
.map(({ group }) => group);
|
|
54
|
+
}
|
|
55
|
+
const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|