UNPKG

@senx/discovery-widgets

Version:

Discovery Widgets Elements

981 lines 74.2 kB
/* * 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