@senx/discovery-widgets
Version:
Discovery Widgets Elements
892 lines (890 loc) • 91.5 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, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36;
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) + (this.innerOptions.unitPosition === 'middle' ? 40 : 0),
top: 30,
bottom: (this.innerOptions.showLegend ? 30 : 10) + (this.innerOptions.showRangeSelector ? 40 : 0) + (this.innerOptions.xUnit ? 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) => {
if (this.innerOptions.hideTooltip === true) {
return '';
}
const tooltipWidth = Math.floor(this.innerWidth / 2);
const contentWidth = tooltipWidth - 40; // Account for padding and margins
let maxTxtSize = 0;
params.forEach(s => {
maxTxtSize = Math.max(GTSLib.getName(s.seriesName).length, maxTxtSize);
});
return `
<style>
@keyframes scrollText {
0% { margin-left: 0; }
10% { margin-left: 0; }
90% { margin-left: -95%; }
100% { margin-left: -95%; }
}
.tooltip-scroll {
white-space: nowrap;
overflow: hidden;
display: inline-block;
vertical-align: middle;
}
.tooltip-marker {
flex-shrink: 0;
}
.tooltip-value {
flex-shrink: 0;
text-align: right;
margin-left:auto;
font-weight:900;
padding-left:10px;
}
.tooltip-scroll-container {
overflow:hidden;
}
.tooltip-scroll div {
${maxTxtSize > 100 ? "animation: scrollText " + (maxTxtSize * 0.08) + "s linear infinite alternate;" : ""}
display: inline-block;
width: fit-content;
}
</style>
<div style="max-width:${tooltipWidth}px;overflow:hidden;">
<div style="font-size:14px;color:#666;font-weight:400;line-height:1.4;padding:8px;white-space:nowrap;">
${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 => `
<div style="display:flex;align-items:center;padding:1px 8px;line-height:1.4;">
<span class="tooltip-marker">${s.marker}</span>
<div class="tooltip-scroll-container">
<div class="tooltip-scroll" >
<div>${GTSLib.formatLabel(GTSLib.getName(s.seriesName))}</div>
</div>
</div>
<div class="tooltip-value">
${this.innerOptions.decimals !== undefined ? GTSLib.roundValue(s.value[1], this.innerOptions.decimals) : s.value[1]}
</div>
</div>`).join('')}
</div>`;
},
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: typeof this.innerOptions.showControls === 'boolean'
? this.innerOptions.showControls
: ((_d = this.innerOptions.showControls.saveAsImage) !== null && _d !== void 0 ? _d : false) || ((_e = this.innerOptions.showControls.saveAsCSV) !== null && _e !== void 0 ? _e : false) || ((_f = this.innerOptions.showControls.restore) !== null && _f !== void 0 ? _f : false) || ((_g = this.innerOptions.showControls.dataZoom) !== null && _g !== void 0 ? _g : false) || (typeof this.innerOptions.showControls.dataView === 'boolean' ? this.innerOptions.showControls.dataView : (_j = (_h = this.innerOptions.showControls.dataView) === null || _h === void 0 ? void 0 : _h.show) !== null && _j !== void 0 ? _j : false),
feature: {
saveAsImage: {
type: 'png',
excludeComponents: ['toolbox'],
show: typeof this.innerOptions.showControls === 'boolean'
? this.innerOptions.showControls
: (_k = this.innerOptions.showControls.saveAsImage) !== null && _k !== void 0 ? _k : false
},
myCsvExport: {
name: 'myCsvExport',
show: typeof this.innerOptions.showControls === 'boolean'
? this.innerOptions.showControls
: (_l = this.innerOptions.showControls.saveAsCSV) !== null && _l !== void 0 ? _l : false,
title: 'Export CSV',
icon: 'path://M15.29 1H3v11h1V2h10v6h6v14H4v-3H3v4h18V6.709zM20 7h-5V2h.2L20 6.8zm-4.96 11l2.126-5H16.08l-1.568 3.688L12.966 13h-1.084l2.095 5zM7 14.349v.302A1.35 1.35 0 0 0 8.349 16H9.65a.349.349 0 0 1 .349.349v.302A.349.349 0 0 1 9.65 17H7v1h2.651A1.35 1.35 0 0 0 11 16.651v-.302A1.35 1.35 0 0 0 9.651 15H8.35a.349.349 0 0 1-.35-.349v-.302A.349.349 0 0 1 8.349 14H11v-1H8.349A1.35 1.35 0 0 0 7 14.349zm-5 .692v.918A2.044 2.044 0 0 0 4.041 18H6v-1H4.041A1.042 1.042 0 0 1 3 15.959v-.918A1.042 1.042 0 0 1 4.041 14H6v-1H4.041A2.044 2.044 0 0 0 2 15.041z',
iconStyle: {
borderWidth: 0.5
},
onclick: () => {
const csv = this.dataToCSV(data);
const blob = new Blob([csv], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = (this.innerOptions.title ? this.innerOptions.title : 'export') + '.csv';
a.click();
window.URL.revokeObjectURL(url);
}
},
restore: {
show: typeof this.innerOptions.showControls === 'boolean'
? this.innerOptions.showControls
: (_m = this.innerOptions.showControls.restore) !== null && _m !== void 0 ? _m : false
},
dataZoom: {
show: typeof this.innerOptions.showControls === 'boolean'
? this.innerOptions.showControls
: (_o = this.innerOptions.showControls.dataZoom) !== null && _o !== void 0 ? _o : false
},
dataView: {
show: typeof this.innerOptions.showControls === 'boolean'
? this.innerOptions.showControls
: typeof this.innerOptions.showControls.dataView === 'boolean'
? this.innerOptions.showControls.dataView
: (_q = (_p = this.innerOptions.showControls.dataView) === null || _p === void 0 ? void 0 : _p.show) !== null && _q !== void 0 ? _q : false,
lang: typeof this.innerOptions.showControls === 'object' && typeof this.innerOptions.showControls.dataView === 'object' && ((_r = this.innerOptions.showControls.dataView) === null || _r === void 0 ? void 0 : _r.lang)
? this.innerOptions.showControls.dataView.lang
: ['Data view', 'Close', 'Refresh'],
optionToContent: () => this.dataToHTMLTable(data),
textColor: Utils.getCSSColor(this.el, '--warp-view-data-view-text-color', 'white'),
backgroundColor: Utils.getCSSColor(this.el, '--warp-view-data-view-bg-color', 'white'),
buttonColor: Utils.getCSSColor(this.el, '--warp-view-button-bg-color', '#004eff'),
buttonTextColor: Utils.getCSSColor(this.el, '--warp-view-button-label-color', '#ffffff'),
readOnly: true
}
},
}, 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: [] }, (_u = (_t = (_s = this.innerOptions) === null || _s === void 0 ? void 0 : _s.extra) === null || _t === void 0 ? void 0 : _t.chartOpts) !== null && _u !== void 0 ? _u : {});
let min = Number.MAX_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
let hasTimeBounds = false;
((_v = this.innerOptions.actions) !== null && _v !== void 0 ? _v : []).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(((_w = data.params) !== null && _w !== void 0 ? _w : [])
.filter(p => p.yAxis !== null && p.yAxis !== undefined)
.map(p => p.yAxis)).length > 1;
const multiX = uniq(((_x = data.params) !== null && _x !== void 0 ? _x : [])
.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 = (_0 = (_z = ((_y = data.params) !== null && _y !== void 0 ? _y : [])[index]) === null || _z === void 0 ? void 0 : _z.datasetNoAlpha) !== null && _0 !== void 0 ? _0 : this.innerOptions.datasetNoAlpha;
if (GTSLib.isGtsToPlot(gts)) {
const c = ColorLib.getColor(gts.id, this.innerOptions.scheme);
const color = (_3 = (_2 = ((_1 = data.params) !== null && _1 !== void 0 ? _1 : [])[gts.id]) === null || _2 === void 0 ? void 0 : _2.datasetColor) !== null && _3 !== void 0 ? _3 : c;
const type = (_6 = (_5 = ((_4 = data.params) !== null && _4 !== void 0 ? _4 : [])[gts.id]) === null || _5 === void 0 ? void 0 : _5.type) !== null && _6 !== void 0 ? _6 : this.type;
if (!!data.params && !!data.params[gts.id] && ((_7 = data.params[gts.id].pieces) !== null && _7 !== void 0 ? _7 : []).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 < ((_8 = gts.v) !== null && _8 !== void 0 ? _8 : []).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 = ((_10 = ((_9 = data.params) !== null && _9 !== void 0 ? _9 : [])[gts.id]) === null || _10 === void 0 ? void 0 : _10.stacked) !== undefined
? (_12 = ((_11 = data.params) !== null && _11 !== void 0 ? _11 : [])[gts.id]) === null || _12 === void 0 ? void 0 : _12.stacked
: (_13 = this.innerOptions) === null || _13 === void 0 ? void 0 : _13.stacked;
const s = {
type: type === 'scatter' || gts.v.length <= 1 ? 'scatter' : ['scatter', 'line', 'bar'].includes(type) ? type : 'line',
name: GTSLib.setName(gts.id, ((_16 = ((_15 = ((_14 = data.params) !== null && _14 !== void 0 ? _14 : [])[gts.id]) !== null && _15 !== void 0 ? _15 : { key: undefined }).key) !== null && _16 !== void 0 ? _16 : 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: (_17 = this.innerOptions.dotSize) !== null && _17 !== void 0 ? _17 : 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: (_21 = (_20 = (_19 = ((_18 = data.params) !== null && _18 !== void 0 ? _18 : [])[gts.id]) === null || _19 === void 0 ? void 0 : _19.strokeWidth) !== null && _20 !== void 0 ? _20 : this.innerOptions.strokeWidth) !== null && _21 !== void 0 ? _21 : 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 (((_22 = data.params[gts.id]) === null || _22 === void 0 ? void 0 : _22.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 (((_23 = data.params[gts.id]) === null || _23 === void 0 ? void 0 : _23.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 = (_24 = gts === null || gts === void 0 ? void 0 : gts.id) !== null && _24 !== void 0 ? _24 : index;
const color = (_27 = (_26 = ((_25 = data.params) !== null && _25 !== void 0 ? _25 : [])[id]) === null || _26 === void 0 ? void 0 : _26.datasetColor) !== null && _27 !== void 0 ? _27 : 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
? ((_28 = gts.values) !== null && _28 !== void 0 ? _28 : []).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 },
formatter: function (d) {
return d.data.length === 4 ? d.data[3] : '';
}
},
labelLayout: {
hideOverlap: (_29 = this.innerOptions.hideOverlap) !== null && _29 !== void 0 ? _29 : false
},
itemStyle: isBubble || this.innerOptions.dotSize > 10 ? {
opacity: 0.8,
borderColor: color,
borderWidth: (_32 = ((_31 = ((_30 = data.params) !== null && _30 !== void 0 ? _30 : [])[gts.id]) !== null && _31 !== void 0 ? _31 : { strokeWidth: undefined }).strokeWidth) !== null && _32 !== void 0 ? _32 : 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 (((_33 = data.params[gts.id]) === null || _33 === void 0 ? void 0 : _33.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 (((_34 = data.params[gts.id]) === null || _34 === void 0 ? void 0 : _34.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);
}
}
((_35 = this.innerOptions.polygons) !== null && _35 !== void 0 ? _35 : []).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);
}
(_36 = this.LOG) === null || _36 === void 0 ? void 0 : _36.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;
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 Object.assign({ type: this.innerOptions.yLabelsMapping ? 'category' : 'value', name: unit !== null && unit !== void 0 ? unit : (this.unit !== undefined && this.unit !== '' ? this.unit : this.innerOptions.unit), show: !this.innerOptions.hideYAxis, nameTextStyle: {
color: color !== null && color !== void 0 ? color : Utils.getLabelColor(this.el),
fontSize: this.innerOptions.unitFontSize
}, 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,
formatter: (x) => {
// very close to echarts addCommas() source, but with a thin space
if (typeof x === 'string') {
return x;
}
var parts = (x + '').split('.');
return parts[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1 ') + (parts.length > 1 ? '.' + parts[1] : '');
}
}, 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: ((_c = (_b = (_a = this.innerOptions) === null || _a === void 0 ? void 0 : _a.bounds) === null || _b === void 0 ? void 0 : _b.yRanges) !== null && _c !== void 0 ? _c : [])[0], max: ((_f = (_e = (_d = this.innerOptions) === null || _d === void 0 ? void 0 : _d.bounds) === null || _e === void 0 ? void 0 : _e.yRanges) !== null && _f !== void 0 ? _f : [])[1] }, (this.innerOptions.unitPosition === 'middle' ? {
nameLocation: "middle",
nameRotate: 90,
nameGap: 30,
} : {}));
}
getXAxis(color) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
return Object.assign({ name: (_a = this.innerOptions.xUnit) !== null && _a !== void 0 ? _a : '', nameTextStyle: {
color: color !== null && color !== void 0 ? color : Utils.getLabelColor(this.el),
fontSize: this.innerOptions.xUnitFontSize
}, 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: ((_c = (_b = this.innerOptions) === null || _b === void 0 ? void 0 : _b.bounds) === null || _c === void 0 ? void 0 : _c.xRanges) && Array.isArray((_e = (_d = this.innerOptions) === null || _d === void 0 ? void 0 : _d.bounds) === null || _e === void 0 ? void 0 : _e.xRanges) && ((_g = (_f = this.innerOptions) === null || _f === void 0 ? void 0 : _f.bounds) === null || _g === void 0 ? void 0 : _g.xRanges.length) === 2
? (_j = (_h = this.innerOptions) === null || _h === void 0 ? void 0 : _h.bounds) === null || _j === void 0 ? void 0 : _j.xRanges[0]
: ((_k = this.innerOptions.bounds) === null || _k === void 0 ? void 0 : _k.minDate) !== undefined
? this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(this.innerOptions.bounds.minDate, this.divider, this.innerOptions.timeZone)
: this.innerOptions.bounds.minDate
: undefined, max: ((_m = (_l = this.innerOptions) === null || _l === void 0 ? void 0 : _l.bounds) === null || _m === void 0 ? void 0 : _m.xRanges) && Array.isArray((_p = (_o = this.innerOptions) === null || _o === void 0 ? void 0 : _o.bounds) === null || _p === void 0 ? void 0 : _p.xRanges) && ((_r = (_q = this.innerOptions) === null || _q === void 0 ? void 0 : _q.bounds) === null || _r === void 0 ? void 0 : _r.xRanges.length) === 2
? (_t = (_s = this.innerOptions) === null || _s === void 0 ? void 0 : _s.bounds) === null || _t === void 0 ? void 0 : _t.xRanges[1]
: ((_u = this.innerOptions.bounds) === null || _u === void 0 ? void 0 : _u.maxDate) !== undefined
? this.innerOptions.timeMode === 'date'
? GTSLib.utcToZonedTime(this.innerOptions.bounds.maxDate, this.divider, this.innerOptions.timeZone)
: this.innerOptions.bounds.maxDate
: undefined }, (this.innerOptions.xUnit ? {
nameLocation: "middle",
nameGap: 30,
} : {}));
}
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) => t