@senx/discovery-widgets
Version:
Discovery Widgets Elements
981 lines • 74.2 kB
JavaScript
/*
* Copyright 2022-2025 SenX S.A.S.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { h } from "@stencil/core";
import { init } from "echarts";
import { GTSLib } from "../../utils/gts.lib";
import { ColorLib } from "../../utils/color-lib";
import { Utils } from "../../utils/utils";
import { Param } from "../../model/param";
import { Logger } from "../../utils/logger";
import { DataModel } from "../../model/types";
import "moment/min/locales.js";
import { throttle, uniq } from "lodash";
import { v4 } from "uuid";
export class DiscoveryLineComponent {
constructor() {
this.options = Object.assign(Object.assign({}, new Param()), { timeMode: 'date' });
this.debug = false;
this.unit = '';
this.language = 'warpscript';
this.vars = '{}';
this.parsing = false;
this.rendering = false;
this.defOptions = Object.assign(Object.assign({}, new Param()), { timeMode: 'date', xCursor: true, yCursor: false });
this.divider = 1000;
this.leftMargin = 0;
this.hasFocus = false;
this.pois = [];
this.innerWidth = 0;
this.innerHeight = 0;
this.zoomXInfo = {};
this.zoomYInfo = {};
this.innerVars = {};
}
updateType(newValue, oldValue) {
var _a;
if (newValue !== oldValue) {
this.type = newValue;
this.chartOpts = this.convert((_a = this.result) !== null && _a !== void 0 ? _a : new DataModel());
this.setOpts();
}
}
updateRes(newValue, oldValue) {
var _a;
if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
this.result = GTSLib.getData(this.result);
const options = Utils.mergeDeep(this.innerOptions, (_a = this.result.globalParams) !== null && _a !== void 0 ? _a : {});
this.innerOptions = Object.assign(Object.assign({}, this.defOptions), options);
this.chartOpts = this.convert(this.result || new DataModel());
this.setOpts(true);
}
}
optionsUpdate(newValue, oldValue) {
var _a, _b;
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['optionsUpdate'], newValue, oldValue);
let opts = newValue;
if (!!newValue && typeof newValue === 'string') {
opts = JSON.parse(newValue);
}
if (!Utils.deepEqual(opts, this.innerOptions)) {
this.innerOptions = Object.assign(Object.assign({}, this.defOptions), opts);
if (this.myChart) {
this.chartOpts = this.convert(this.result || new DataModel());
this.setOpts(true);
}
(_b = this.LOG) === null || _b === void 0 ? void 0 : _b.debug(['optionsUpdate 2'], { options: this.innerOptions, newValue, oldValue }, this.chartOpts);
}
}
varsUpdate(newValue, oldValue) {
var _a;
let vars = this.vars;
if (!!this.vars && typeof this.vars === 'string') {
vars = JSON.parse(this.vars);
}
if (!Utils.deepEqual(vars, this.innerVars)) {
this.innerVars = Utils.clone(vars);
}
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['varsUpdate'], { vars: this.vars, newValue, oldValue });
}
// noinspection JSUnusedGlobalSymbols
componentWillLoad() {
var _a, _b;
this.parsing = true;
this.LOG = new Logger(DiscoveryLineComponent, this.debug);
this.result = GTSLib.getData(this.result);
if (typeof this.options === 'string') {
this.innerOptions = Object.assign(Object.assign({}, this.defOptions), JSON.parse(this.options));
}
else {
this.innerOptions = Object.assign(Object.assign({}, this.defOptions), this.options);
}
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['componentWillLoad'], { type: this.type, options: this.innerOptions });
this.chartOpts = this.convert((_b = this.result) !== null && _b !== void 0 ? _b : new DataModel());
this.setOpts();
}
setOpts(notMerge = false) {
var _a, _b;
if (!!this.vars && typeof this.vars === 'string') {
this.innerVars = JSON.parse(this.vars);
}
else if (this.vars) {
this.innerVars = this.vars;
}
if (this.chartOpts.series.length === 0) {
this.chartOpts.title = {
show: true,
textStyle: { color: Utils.getLabelColor(this.el), fontSize: 20 },
text: (_a = this.innerOptions.noDataLabel) !== null && _a !== void 0 ? _a : '',
left: 'center',
top: 'center',
};
this.chartOpts.xAxis = { show: false };
this.chartOpts.yAxis = { show: false };
this.chartOpts.dataZoom = { show: false };
this.chartOpts.tooltip = { show: false };
}
else {
this.chartOpts.title = Object.assign(Object.assign({}, (_b = this.chartOpts.title) !== null && _b !== void 0 ? _b : {}), { show: false });
}
if (this.myChart) {
setTimeout(() => {
var _a;
this.myChart.setOption((_a = this.chartOpts) !== null && _a !== void 0 ? _a : {}, notMerge, true);
const batch = [];
if (this.zoomXInfo.start !== undefined) {
batch.push({
start: this.zoomXInfo.start,
end: this.zoomXInfo.end,
dataZoomIndex: 0,
});
}
if (this.zoomYInfo.start !== undefined) {
batch.push({
start: this.zoomYInfo.start,
end: this.zoomYInfo.end,
dataZoomIndex: 1,
});
}
if (batch.length > 0) {
this.myChart.dispatchAction({ type: 'dataZoom', batch });
}
});
}
}
convert(data) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22;
this.innerOptions.timeMode = (_a = this.innerOptions.timeMode) !== null && _a !== void 0 ? _a : 'date';
this.divider = GTSLib.getDivider((_b = this.innerOptions.timeUnit) !== null && _b !== void 0 ? _b : 'us');
const gtsList = [
...GTSLib.flattenGtsIdArray(GTSLib.flatDeep([data.data]), 0).res,
...GTSLib.flatDeep([data.data]).filter(g => !!g && g.values && g.label),
];
const gtsCount = gtsList.length;
const opts = Object.assign({ animation: false, grid: {
left: (!!this.innerOptions.leftMargin && this.innerOptions.leftMargin > this.leftMargin)
? this.innerOptions.leftMargin - this.leftMargin + 10
: 10,
top: 30,
bottom: (this.innerOptions.showLegend ? 30 : 10) + (this.innerOptions.showRangeSelector ? 40 : 0),
right: 10 + (this.innerOptions.showYRangeSelector ? 40 : 0),
containLabel: true,
}, responsive: true, throttle: 40, tooltip: {
transitionDuration: 0,
trigger: 'axis',
animation: false,
snap: false,
position: (pos, _params, _dom, _rect, size) => {
const obj = { top: 10 };
obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 5;
return obj;
},
formatter: (params) => `<div style="font-size:14px;color:#666;font-weight:400;line-height:1;">${this.innerOptions.timeMode !== 'date'
? params[0].value[0]
: (GTSLib.toISOString(GTSLib.zonedTimeToUtc(params[0].value[0], 1, this.innerOptions.timeZone), 1, this.innerOptions.timeZone, this.innerOptions.fullDateDisplay ? this.innerOptions.timeFormat : undefined) || '')
.replace('T', ' ').replace(/\+[0-9]{2}:[0-9]{2}$/gi, '')}</div>
${params.map(s => `${s.marker} <span style="font-size:14px;color:#666;font-weight:400;margin-left:2px">${GTSLib.getName(s.seriesName)}</span>
<span style="float:right;margin-left:20px;font-size:14px;color:#666;font-weight:900">${s.value[1]}</span>`).join('<br>')}`,
axisPointer: {
type: !!this.innerOptions.yCursor && !!this.innerOptions.xCursor
? 'cross'
: !!this.innerOptions.yCursor || !!this.innerOptions.xCursor
? 'line'
: 'none',
axis: this.innerOptions.yAxisFocus ? 'y' : 'x',
animation: false,
lineStyle: !this.innerOptions.yCursor && !this.innerOptions.xCursor
? undefined
: {
color: Utils.getCSSColor(this.el, '--warp-view-bar-color', 'red'),
},
crossStyle: this.innerOptions.yCursor
? {
color: Utils.getCSSColor(this.el, '--warp-view-bar-color', 'red'),
}
: undefined,
},
backgroundColor: Utils.getCSSColor(this.el, '--warp-view-tooltip-bg-color', 'white'),
hideDelay: (_c = this.innerOptions.tooltipDelay) !== null && _c !== void 0 ? _c : 100,
}, toolbox: {
show: this.innerOptions.showControls,
feature: {
saveAsImage: { type: 'png', excludeComponents: ['toolbox'] },
restore: { show: true },
dataZoom: {},
},
}, legend: {
bottom: 0, left: 'center', show: !!this.innerOptions.showLegend, height: 30, type: 'scroll',
textStyle: { color: Utils.getLabelColor(this.el) },
formatter: n => GTSLib.getName(n),
}, dataZoom: [
{
type: 'inside',
realtime: true,
filterMode: 'none',
orient: 'horizontal',
zoomOnMouseWheel: true,
},
{
type: 'inside',
realtime: true,
filterMode: 'none',
orient: 'vertical',
zoomOnMouseWheel: 'ctrl',
},
{
type: 'slider',
height: '20px',
show: !!this.innerOptions.showRangeSelector,
bottom: this.innerOptions.showLegend ? 30 : 20,
xAxisIndex: [0],
filterMode: 'none',
},
{
type: 'slider',
width: '20px',
show: !!this.innerOptions.showYRangeSelector,
yAxisIndex: [0],
filterMode: 'none',
},
], visualMap: new Array(gtsCount), series: [] }, (_f = (_e = (_d = this.innerOptions) === null || _d === void 0 ? void 0 : _d.extra) === null || _e === void 0 ? void 0 : _e.chartOpts) !== null && _f !== void 0 ? _f : {});
let min = Number.MAX_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
let hasTimeBounds = false;
((_g = this.innerOptions.actions) !== null && _g !== void 0 ? _g : []).forEach((action) => {
var _a, _b;
if (action.macro) {
opts.toolbox.feature['my' + v4().replaceAll('-', '')] = {
title: (_a = action.title) !== null && _a !== void 0 ? _a : '',
show: true,
icon: (_b = action.icon) !== null && _b !== void 0 ? _b : Utils.DEFICON,
onclick: () => Utils.execAction(action.macro, this),
};
}
});
const multiY = uniq(((_h = data.params) !== null && _h !== void 0 ? _h : [])
.filter(p => p.yAxis !== null && p.yAxis !== undefined)
.map(p => p.yAxis)).length > 1;
const multiX = uniq(((_j = data.params) !== null && _j !== void 0 ? _j : [])
.filter(p => p.xAxis !== null && p.xAxis !== undefined)
.map(p => p.xAxis)).length > 1;
for (let index = 0; index < gtsCount; index++) {
const gts = gtsList[index];
const datasetNoAlpha = (_m = (_l = ((_k = data.params) !== null && _k !== void 0 ? _k : [])[index]) === null || _l === void 0 ? void 0 : _l.datasetNoAlpha) !== null && _m !== void 0 ? _m : this.innerOptions.datasetNoAlpha;
if (GTSLib.isGtsToPlot(gts)) {
const c = ColorLib.getColor(gts.id, this.innerOptions.scheme);
const color = (_q = (_p = ((_o = data.params) !== null && _o !== void 0 ? _o : [])[gts.id]) === null || _p === void 0 ? void 0 : _p.datasetColor) !== null && _q !== void 0 ? _q : c;
const type = (_t = (_s = ((_r = data.params) !== null && _r !== void 0 ? _r : [])[gts.id]) === null || _s === void 0 ? void 0 : _s.type) !== null && _t !== void 0 ? _t : this.type;
if (!!data.params && !!data.params[gts.id] && ((_u = data.params[gts.id].pieces) !== null && _u !== void 0 ? _u : []).length > 0) {
opts.visualMap[gts.id] = {
show: false,
seriesIndex: gts.id,
dimension: data.params[gts.id].xpieces ? 0 : 1,
pieces: data.params[gts.id].pieces.map(p => {
var _a;
return ({
color: (_a = p.color) !== null && _a !== void 0 ? _a : '#D81B60',
lte: data.params[gts.id].xpieces
? this.innerOptions.timeMode === 'date' ? GTSLib.utcToZonedTime(p.lte, this.divider, this.innerOptions.timeZone) : p.lte
: p.lte,
gte: data.params[gts.id].xpieces
? this.innerOptions.timeMode === 'date' ? GTSLib.utcToZonedTime(p.gte, this.divider, this.innerOptions.timeZone) : p.gte
: p.gte,
});
}),
outOfRange: { color },
};
}
hasTimeBounds = true;
const dataSet = [];
for (let v = 0; v < ((_v = gts.v) !== null && _v !== void 0 ? _v : []).length; v++) {
const tuple = gts.v[v];
const ts = tuple[0];
const val = tuple[tuple.length - 1];
if (ts > max)
max = ts;
if (ts < min)
min = ts;
dataSet.push([
this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(ts, this.divider, this.innerOptions.timeZone)
: ts,
val,
]);
}
const isStacked = ((_x = ((_w = data.params) !== null && _w !== void 0 ? _w : [])[gts.id]) === null || _x === void 0 ? void 0 : _x.stacked) !== undefined
? (_z = ((_y = data.params) !== null && _y !== void 0 ? _y : [])[gts.id]) === null || _z === void 0 ? void 0 : _z.stacked
: (_0 = this.innerOptions) === null || _0 === void 0 ? void 0 : _0.stacked;
const s = {
type: type === 'scatter' || gts.v.length <= 1 ? 'scatter' : ['scatter', 'line', 'bar'].includes(type) ? type : 'line',
name: GTSLib.setName(gts.id, ((_3 = ((_2 = ((_1 = data.params) !== null && _1 !== void 0 ? _1 : [])[gts.id]) !== null && _2 !== void 0 ? _2 : { key: undefined }).key) !== null && _3 !== void 0 ? _3 : GTSLib.serializeGtsMetadata(gts))),
data: dataSet,
id: gts.id,
animation: false,
large: true,
connectNulls: !this.innerOptions.discontinue,
showSymbol: this.type === 'scatter' || this.innerOptions.showDots || this.innerOptions.showValues,
symbolSize: (_4 = this.innerOptions.dotSize) !== null && _4 !== void 0 ? _4 : 10,
smooth: type === 'spline' || type === 'spline-area' ? 0.2 : undefined,
clip: true,
stack: 'scatter' !== type && isStacked ? 'total' : undefined,
stackStrategy: 'scatter' !== type && isStacked ? 'all' : undefined,
step: DiscoveryLineComponent.getStepShape(type),
areaStyle: type === 'area' || type === 'step-area' || type === 'spline-area' ? {
opacity: 0.8,
color: {
type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
colorStops: [
{ offset: 0, color: ColorLib.transparentize(color, datasetNoAlpha ? 1 : 0.7) },
{ offset: 1, color: ColorLib.transparentize(color, datasetNoAlpha ? 1 : 0.1) },
],
global: false, // false by default
},
} : undefined,
showAllSymbol: false,
label: {
show: !!this.innerOptions.showValues,
position: 'top',
textStyle: { color: Utils.getLabelColor(this.el), fontSize: 14 },
},
lineStyle: {
cap: 'round',
join: 'miter',
color: !opts.visualMap[gts.id] ? color : undefined,
width: (_8 = (_7 = (_6 = ((_5 = data.params) !== null && _5 !== void 0 ? _5 : [])[gts.id]) === null || _6 === void 0 ? void 0 : _6.strokeWidth) !== null && _7 !== void 0 ? _7 : this.innerOptions.strokeWidth) !== null && _8 !== void 0 ? _8 : 2,
},
itemStyle: type === 'bar' ? {
opacity: 0.8,
borderColor: color,
color: {
type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
colorStops: [
{ offset: 0, color: ColorLib.transparentize(color, datasetNoAlpha ? 1 : 0.7) },
{ offset: 1, color: ColorLib.transparentize(color, datasetNoAlpha ? 1 : 0.3) },
],
},
} : { color },
};
if (data.params) {
// multi Y
if (((_9 = data.params[gts.id]) === null || _9 === void 0 ? void 0 : _9.yAxis) !== undefined && multiY) {
const y = this.getYAxis(color, data.params[gts.id].unit);
if (data.params[gts.id].yAxis > 0) {
s.yAxisIndex = data.params[gts.id].yAxis;
y.position = 'right';
if (!opts.yAxis)
opts.yAxis = new Array(data.params.length);
opts.yAxis[data.params[gts.id].yAxis] = y;
}
else {
y.position = 'left';
if (!opts.yAxis)
opts.yAxis = new Array(data.params.length);
opts.yAxis[0] = y;
}
}
else if (multiY) {
const y = this.getYAxis(undefined, data.params[gts.id].unit);
y.position = 'left';
if (!opts.yAxis)
opts.yAxis = new Array(data.params.length);
opts.yAxis[0] = y;
}
// multi X
if (((_10 = data.params[gts.id]) === null || _10 === void 0 ? void 0 : _10.xAxis) !== undefined && multiX) {
if (data.params[gts.id].xAxis > 0) {
s.xAxisIndex = data.params[gts.id].xAxis;
const x = this.getXAxis(color);
x.position = 'top';
if (!opts.xAxis)
opts.xAxis = new Array(data.params.length);
opts.xAxis[data.params[gts.id].xAxis] = x;
}
else {
const x = this.getXAxis(color);
x.position = 'bottom';
if (!opts.xAxis)
opts.xAxis = new Array(data.params.length);
opts.xAxis[0] = x;
}
}
else if (multiX) {
const x = this.getXAxis();
x.position = 'bottom';
if (!opts.xAxis)
opts.xAxis = new Array(data.params.length);
opts.xAxis[0] = x;
}
}
opts.series.push(s);
}
else if (['scatter', 'line'].includes(this.type) && gts.label && gts.values) {
// Custom data for scatter
this.innerOptions.timeMode = 'custom';
const id = (_11 = gts === null || gts === void 0 ? void 0 : gts.id) !== null && _11 !== void 0 ? _11 : index;
const color = (_14 = (_13 = ((_12 = data.params) !== null && _12 !== void 0 ? _12 : [])[id]) === null || _13 === void 0 ? void 0 : _13.datasetColor) !== null && _14 !== void 0 ? _14 : ColorLib.getColor(id, this.innerOptions.scheme);
const sMax = Math.max(...gts.values.map((l) => l[2] || 1)) || 1;
const sMin = Math.min(...gts.values.map((l) => l[2] || 0)) || 0;
const isBubble = sMax !== sMin;
const s = {
type: this.type,
name: GTSLib.setName(id, gts.label),
id: gts.id,
data: gts.values[0] && gts.values[0].length === 3
? ((_15 = gts.values) !== null && _15 !== void 0 ? _15 : []).map((v) => ({
value: [GTSLib.utcToZonedTime(v[0], 1, this.innerOptions.timeZone), v[1]],
symbolSize: isBubble ? (50 * v[2] / (sMax - sMin)) || this.innerOptions.dotSize || 10 : this.innerOptions.dotSize || 10,
}))
: gts.values,
animation: false,
large: true,
showSymbol: true,
label: {
show: !!this.innerOptions.showValues,
position: 'top',
textStyle: { color: Utils.getLabelColor(this.el), fontSize: 14 },
},
itemStyle: isBubble || this.innerOptions.dotSize > 10 ? {
opacity: 0.8,
borderColor: color,
borderWidth: (_18 = ((_17 = ((_16 = data.params) !== null && _16 !== void 0 ? _16 : [])[gts.id]) !== null && _17 !== void 0 ? _17 : { strokeWidth: undefined }).strokeWidth) !== null && _18 !== void 0 ? _18 : this.innerOptions.strokeWidth,
color: gts.values[0] && gts.values[0].length === 3
? {
type: 'radial', x: 0.5, y: 0.5, x2: 1, y2: 1,
colorStops: [
{ offset: 0, color: ColorLib.transparentize(color, datasetNoAlpha ? 1 : 0.3) },
{ offset: 1, color: ColorLib.transparentize(color, datasetNoAlpha ? 1 : 0.7) },
],
}
: color,
} : { color },
};
if (data.params) {
// multi Y
if (((_19 = data.params[gts.id]) === null || _19 === void 0 ? void 0 : _19.yAxis) !== undefined && multiY) {
const y = this.getYAxis(color, data.params[gts.id].unit);
if (data.params[gts.id].yAxis > 0) {
s.yAxisIndex = data.params[gts.id].yAxis;
y.position = 'right';
if (!opts.yAxis)
opts.yAxis = new Array(data.params.length);
opts.yAxis[data.params[gts.id].yAxis] = y;
}
else {
y.position = 'left';
if (!opts.yAxis)
opts.yAxis = new Array(data.params.length);
opts.yAxis[0] = y;
}
}
else if (multiY) {
const y = this.getYAxis(undefined, data.params[gts.id].unit);
y.position = 'left';
if (!opts.yAxis)
opts.yAxis = new Array(data.params.length);
opts.yAxis[0] = y;
}
// multi X
if (((_20 = data.params[gts.id]) === null || _20 === void 0 ? void 0 : _20.xAxis) !== undefined && multiX) {
if (data.data[gts.id].length > 0) {
if (data.params[gts.id].xAxis > 0) {
s.xAxisIndex = data.params[gts.id].xAxis;
const x = this.getXAxis(color);
x.position = 'top';
if (!opts.xAxis)
opts.xAxis = new Array(data.params.length);
opts.xAxis[data.params[gts.id].xAxis] = x;
}
else {
const x = this.getXAxis(color);
x.position = 'bottom';
if (!opts.xAxis)
opts.xAxis = new Array(data.params.length);
opts.xAxis[0] = x;
}
}
}
else if (multiX) {
if (data.params[gts.id].xAxis > 0) {
const x = this.getXAxis();
x.position = 'bottom';
if (!opts.xAxis)
opts.xAxis = new Array(data.params.length);
opts.xAxis[0] = x;
}
}
}
opts.series.push(s);
}
}
((_21 = this.innerOptions.polygons) !== null && _21 !== void 0 ? _21 : []).forEach((polygon, i) => {
const s = {
type: 'custom', renderItem: (params, api) => {
if (params.context.rendered) {
return;
}
params.context.rendered = true;
const color = polygon.color || ColorLib.getColor(i, this.innerOptions.scheme);
return {
type: 'polygon',
transition: ['shape'],
shape: {
points: polygon.shape.map(p => api.coord([
this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(p[0], this.divider, this.innerOptions.timeZone)
: p[0], p[1]
])),
},
style: api.style({
fill: polygon.fill ? ColorLib.transparentize(color) : undefined,
stroke: color,
}),
};
},
clip: true,
data: polygon.shape,
};
opts.series.push(s);
});
if (hasTimeBounds) {
this.timeBounds.emit({ min, max });
this.bounds = { min, max };
}
// multi Y
if (!multiY) {
opts.yAxis = this.getYAxis();
}
else {
const yAxis = [...GTSLib.cleanArray(opts.yAxis)];
opts.yAxis = [];
let i = 0;
yAxis.forEach((y) => {
if (y.position === 'right') {
y.offset = 80 * i;
i++;
}
opts.yAxis.push(y);
});
opts.grid.right = 80 * (i - 1);
}
// multi X
if (!multiX) {
opts.xAxis = this.getXAxis();
}
else {
const xAxis = [...GTSLib.cleanArray(opts.xAxis)];
opts.xAxis = [];
let i = 0;
xAxis.forEach((x) => {
if (x.position === 'top') {
x.offset = 30 * (i + 1);
i++;
}
opts.xAxis.push(x);
});
opts.grid.top = Math.max(30, 30 * i);
}
(_22 = this.LOG) === null || _22 === void 0 ? void 0 : _22.debug(['convert', 'opts'], { opts });
const markArea = [...(this.innerOptions.thresholds || [])
.filter(t => !!t.fill)
.map(t => {
return [{
itemStyle: {
color: ColorLib.transparentize(t.color || '#D81B60', t.fill ? 0.5 : 0),
borderType: t.type || 'dashed',
name: t.name || t.value || 0,
},
yAxis: t.value || 0,
}, {
itemStyle: t.from ? {
color: ColorLib.transparentize(t.color || '#D81B60', t.fill ? 0.5 : 0),
borderType: t.type || 'dashed',
name: t.name || t.value || 0,
} : undefined,
yAxis: t.from || 0,
}];
}),
...(this.innerOptions.markers || [])
.filter(t => !!t.fill)
.map(t => {
return [{
itemStyle: {
color: ColorLib.transparentize(t.color || '#D81B60', t.fill ? t.alpha || 0.5 : 0),
borderType: t.type || 'dashed',
},
label: { color: t.color || '#D81B60', position: 'insideTop', distance: 5, show: !!t.name },
name: t.name || t.value || 0,
xAxis: ((t.value / (this.innerOptions.timeMode === 'date' ? this.divider : 1)) || 0),
},
{
itemStyle: {
color: ColorLib.transparentize(t.color || '#D81B60', t.fill ? t.alpha || 0.5 : 0),
borderType: t.type || 'dashed',
},
xAxis: ((t.start / (this.innerOptions.timeMode === 'date' ? this.divider : 1)) || 0),
}];
}),
];
const markLine = [
...(this.innerOptions.thresholds || []).map(t => {
return {
name: t.name || t.value || 0,
label: { color: t.color || '#D81B60', position: 'insideEndTop', formatter: '{b}' },
lineStyle: { color: t.color || '#D81B60', type: t.type || 'dashed' },
yAxis: t.value || 0,
};
}),
...(this.innerOptions.markers || [])
.filter(t => !t.fill)
.map((t, i) => {
return {
name: t.name || t.value || 'mark-' + i,
label: {
color: t.color || '#D81B60',
position: 'insideEndTop',
formatter: '{b}',
show: !!t.name,
},
lineStyle: { color: t.color || '#D81B60', type: t.type || 'dashed' },
xAxis: ((t.value / (this.innerOptions.timeMode === 'date' ? this.divider : 1)) || 0),
};
})
];
if (markArea.length > 0 || markLine.length > 0) {
opts.series.push({
name: '',
type: 'line',
symbolSize: 0,
data: [],
markArea: { data: markArea },
markLine: {
emphasis: { lineStyle: { width: 1 } },
symbol: ['none', 'none'],
data: markLine,
},
});
}
return opts;
}
getYAxis(color, unit) {
var _a, _b, _c, _d, _e, _f, _g;
if (!!(unit || this.unit || this.innerOptions.unit) && !!this.myChart) {
const opts = Object.assign({}, this.chartOpts);
if (opts.grid) {
if ('top' in opts.grid) {
opts.grid.top = 30;
}
setTimeout(() => this.myChart.setOption(opts, true, false));
}
}
return {
type: this.innerOptions.yLabelsMapping ? 'category' : 'value',
name: (_a = unit !== null && unit !== void 0 ? unit : this.unit) !== null && _a !== void 0 ? _a : this.innerOptions.unit,
show: !this.innerOptions.hideYAxis,
nameTextStyle: { color: color !== null && color !== void 0 ? color : Utils.getLabelColor(this.el) },
splitLine: { show: false, lineStyle: { color: Utils.getGridColor(this.el) } },
axisLine: { show: true, lineStyle: { color: color !== null && color !== void 0 ? color : Utils.getGridColor(this.el) } },
axisLabel: {
hideOverlap: true,
color: color !== null && color !== void 0 ? color : Utils.getLabelColor(this.el),
show: !this.innerOptions.hideYAxis,
},
axisTick: { show: true, lineStyle: { color: color !== null && color !== void 0 ? color : Utils.getGridColor(this.el) } },
data: this.innerOptions.yLabelsMapping ? Object.keys(this.innerOptions.yLabelsMapping).map(k => this.innerOptions.yLabelsMapping[k]) : undefined,
scale: !(this.innerOptions.bounds && this.innerOptions.bounds.yRanges && this.innerOptions.bounds.yRanges.length > 0),
min: ((_d = (_c = (_b = this.innerOptions) === null || _b === void 0 ? void 0 : _b.bounds) === null || _c === void 0 ? void 0 : _c.yRanges) !== null && _d !== void 0 ? _d : [])[0],
max: ((_g = (_f = (_e = this.innerOptions) === null || _e === void 0 ? void 0 : _e.bounds) === null || _f === void 0 ? void 0 : _f.yRanges) !== null && _g !== void 0 ? _g : [])[1],
};
}
getXAxis(color) {
var _a, _b;
return {
type: this.innerOptions.timeMode === 'date' ? 'time' : 'value',
show: !this.innerOptions.hideXAxis,
splitNumber: this.innerOptions.timeMode === 'date' ? undefined : Math.max(Math.floor(Utils.getContentBounds(this.el.parentElement).w / 200) - 1, 1),
splitLine: { show: false, lineStyle: { color: Utils.getGridColor(this.el) } },
axisLine: { lineStyle: { color: color !== null && color !== void 0 ? color : Utils.getGridColor(this.el) } },
axisLabel: {
hideOverlap: true,
show: !this.innerOptions.hideXAxis,
color: color !== null && color !== void 0 ? color : Utils.getLabelColor(this.el),
formatter: this.innerOptions.fullDateDisplay
? (value) => GTSLib.toISOString(GTSLib.zonedTimeToUtc(value, 1, this.innerOptions.timeZone), 1, this.innerOptions.timeZone, this.innerOptions.timeFormat)
.replace('T', '\n').replace(/\+[0-9]{2}:[0-9]{2}$/gi, '')
: undefined,
},
axisTick: { lineStyle: { color: color !== null && color !== void 0 ? color : Utils.getGridColor(this.el) } },
scale: !(this.innerOptions.bounds && (this.innerOptions.bounds.minDate || this.innerOptions.bounds.maxDate)),
min: ((_a = this.innerOptions.bounds) === null || _a === void 0 ? void 0 : _a.minDate) !== undefined
? this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(this.innerOptions.bounds.minDate, this.divider, this.innerOptions.timeZone)
: this.innerOptions.bounds.minDate
: undefined,
max: ((_b = this.innerOptions.bounds) === null || _b === void 0 ? void 0 : _b.maxDate) !== undefined
? this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(this.innerOptions.bounds.maxDate, this.divider, this.innerOptions.timeZone)
: this.innerOptions.bounds.maxDate
: undefined,
};
}
static getStepShape(type) {
switch (type) {
case 'line':
case 'area':
case 'spline':
return undefined;
case 'step':
case 'step-area':
return 'end';
case 'step-before':
return 'start';
case 'step-after':
return 'end';
}
}
zoomHandler(start, end) {
var _a, _b, _c, _d, _e, _f;
this.zoomXInfo = {
start,
end,
min: (_b = (_a = this.innerOptions.bounds) === null || _a === void 0 ? void 0 : _a.minDate) !== null && _b !== void 0 ? _b : (_c = this.bounds) === null || _c === void 0 ? void 0 : _c.min,
max: (_e = (_d = this.innerOptions.bounds) === null || _d === void 0 ? void 0 : _d.maxDate) !== null && _e !== void 0 ? _e : (_f = this.bounds) === null || _f === void 0 ? void 0 : _f.max,
orientation: 'x',
};
this.dataZoom.emit(this.zoomXInfo);
}
zoomYHandler(start, end) {
var _a, _b, _c, _d, _e, _f;
this.zoomYInfo = {
start,
end,
min: (_b = (_a = this.innerOptions.bounds) === null || _a === void 0 ? void 0 : _a.minDate) !== null && _b !== void 0 ? _b : (_c = this.bounds) === null || _c === void 0 ? void 0 : _c.min,
max: (_e = (_d = this.innerOptions.bounds) === null || _d === void 0 ? void 0 : _d.maxDate) !== null && _e !== void 0 ? _e : (_f = this.bounds) === null || _f === void 0 ? void 0 : _f.max,
orientation: 'y',
};
this.dataZoomY.emit(this.zoomYInfo);
}
// noinspection JSUnusedGlobalSymbols
componentDidLoad() {
const zoomHandler = throttle((start, end) => this.zoomHandler(start, end), 16, { leading: true, trailing: true });
const zoomYHandler = throttle((start, end) => this.zoomYHandler(start, end), 16, { leading: true, trailing: true });
const focusHandler = throttle((type, event) => {
var _a;
if (this.hasFocus) {
switch (type) {
case 'mouseover':
const c = event.data.coord || event.data;
this.dataPointOver.emit({ date: c[0], name: event.seriesName, value: c[1], meta: {} });
break;
case 'highlight':
let ts;
for (const b of ((_a = event.batch) !== null && _a !== void 0 ? _a : [])) {
const s = this.myChart.getOption().series[b.seriesIndex];
ts = s.data[b.dataIndex][0];
ts = this.innerOptions.timeMode === 'date'
? GTSLib.zonedTimeToUtc(ts * this.divider, this.divider, this.innerOptions.timeZone || 'UTC') * this.divider
: ts;
}
if (ts !== undefined) {
this.dataPointOver.emit({ date: ts, name: '.*', meta: {} });
}
break;
default:
break;
}
}
}, 200, { leading: true, trailing: true });
setTimeout(() => {
this.parsing = false;
this.rendering = true;
this.myChart = init(this.graph, null, { renderer: 'canvas' });
let initial = false;
this.myChart.on('rendered', () => {
this.rendering = false;
let found = false;
let x = 0;
setTimeout(() => {
while (!found && x < 1024) {
found = this.myChart.containPixel({ gridIndex: 0 }, [x, this.myChart.getHeight() / 2]);
x++;
}
if (this.leftMargin !== x && x < 1024) {
setTimeout(() => {
this.leftMarginComputed.emit(x);
this.leftMargin = x;
});
}
if (initial)
setTimeout(() => this.draw.emit());
initial = false;
});
});
this.myChart.on('dataZoom', () => {
var _a;
const option = this.myChart.getOption();
const sliders = ((_a = option.dataZoom) !== null && _a !== void 0 ? _a : []).filter(z => z.type === 'inside');
sliders.forEach(s => {
if (s.orient === 'horizontal') {
zoomHandler(s.start, s.end);
}
else {
zoomYHandler(s.start, s.end);
}
});
});
this.myChart.on('restore', () => {
this.dataZoom.emit({ type: 'restore', start: 0, end: 100 });
});
this.el.addEventListener('dblclick', () => this.myChart.dispatchAction({
type: 'dataZoom',
start: 0,
end: 100,
}));
this.el.addEventListener('mouseover', () => this.hasFocus = true);
this.el.addEventListener('mouseout', () => {
this.hasFocus = false;
this.dataPointOver.emit({});
});
this.myChart.on('mouseout', () => {
this.dataPointOver.emit({});
});
this.myChart.on('mouseover', (event) => focusHandler('mouseover', event));
this.myChart.on('highlight', (event) => focusHandler('highlight', event));
this.myChart.on('click', (event) => {
const c = event.data.coord || event.data;
const date = this.innerOptions.timeMode === 'date'
? GTSLib.zonedTimeToUtc(c[0], 1, this.innerOptions.timeZone) * this.divider
: c[0];
if (event.componentType !== 'markLine') {
this.dataPointSelected.emit({ date, name: GTSLib.getName(event.seriesName), value: c[1], meta: {} });
}
if (this.innerOptions.poi) {
if (this.pois.find(p => p.date === date)) {
this.pois = this.pois.filter(p => p.date !== date);
}
else if (event.componentType !== 'markLine') {
this.pois.push({
date,
name: GTSLib.getName(event.seriesName),
value: c[1],
meta: {},
uid: v4(),
});
}
this.chartOpts.series = this.chartOpts.series.filter(s => 'poi' !== s.id);
this.poi.emit(this.pois);
this.chartOpts.series.push({
name: '',
id: 'poi',
type: 'line',
data: [],
markLine: {
emphasis: { lineStyle: { width: 1 } },
symbol: ['none', 'pin'],
symbolSize: 20,
symbolKeepAspect: true,
data: this.pois.map(p => {
return {
name: 'poi-' + p.uid,
label: { show: false },
lineStyle: { color: this.innerOptions.poiColor, type: this.innerOptions.poiLine },
xAxis: this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(p.date / this.divider, 1, this.innerOptions.timeZone)
: p.date,
};
}),
},
});
setTimeout(() => { var _a; return this.myChart.setOption((_a = this.chartOpts) !== null && _a !== void 0 ? _a : {}, true, false); });
}
});
setTimeout(() => { var _a; return this.myChart.setOption((_a = this.chartOpts) !== null && _a !== void 0 ? _a : {}, true, false); });
initial = true;
});
}
async resize() {
const dims = Utils.getContentBounds(this.el.parentElement);
const width = dims.w - 4;
const height = dims.h;
if (this.myChart && (this.innerWidth !== width || this.innerHeight !== dims.h)) {
this.innerWidth = width;
this.innerHeight = this.innerHeight !== dims.h ? height - this.el.parentElement.offsetTop : this.innerHeight;
this.myChart.resize({ width: this.innerWidth, height: this.innerHeight, silent: true });
}
return Promise.resolve();
}
async setZoom(dataZoom) {
var _a, _b, _c;
if (this.myChart) {
dataZoom.start = (_a = dataZoom.start) !== null && _a !== void 0 ? _a : 0;
if (((_b = this.zoom) === null || _b === void 0 ? void 0 : _b.start) !== dataZoom.start || ((_c = this.zoom) === null || _c === void 0 ? void 0 : _c.end) !== dataZoom.end) {
this.zoom = dataZoom;
this.myChart.dispatchAction(Object.assign(Object.assign({ type: 'dataZoom' }, dataZoom), { dataZoomIndex: 0 }));
}
}
return Promise.resolve();
}
async export(type = 'png') {
return Promise.resolve(this.myChart ? this.myChart.getDataURL({
type,
excludeComponents: ['toolbox'],
}) : undefined);
}
async show(regexp) {
this.myChart.dispatchAction({
type: 'legendSelect',
batch: this.myChart.getOption().series
.filter(s => new RegExp(regexp).test(GTSLib.getName(s.name))),
});
return Promise.resolve();
}
async hide(regexp) {
this.myChart.dispatchAction({
type: 'legendUnSelect',
batch: this.myChart.getOption().series
.filter(s => new RegExp(regexp).test(GTSLib.getName(s.name))),
});
return Promise.resolve();
}
async hideById(id) {
if (this.myChart) {
this.myChart.dispatchAction({
type: 'legendUnSelect',
batch: this.myChart.getOption().series
.filter((s, i) => new RegExp(id.toString()).test((s.id || i).toString())),
});
}
return Promise.resolve();
}
async showById(id) {
if (this.myChart) {
this.myChart.dispatchAction({
type: 'legendSelect',
batch: this.myChart.getOption().series
.filter((s, i) => new RegExp(id.toString()).test((s.id || i).toString())),
});
}
return Promise.resolve();
}
async setFocus(regexp, ts, value) {
if (!this.myChart || this.hasFocus)
return;
const date = this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(ts || 0, this.divider, this.innerOptions.timeZone)
: ts || 0;
let seriesIndex = 0;
let dataIndex = 0;
if (regexp) {
this.chartOpts.series
.filter(s => new RegExp(regexp).test(s.name