@senx/warpview
Version:
WarpView Elements
1 lines • 836 kB
Source Map (JSON)
{"version":3,"file":"warpview.mjs","sources":["../../../projects/warpview-ng/src/lib/model/dataModel.ts","../../../projects/warpview-ng/src/lib/utils/logger.ts","../../../projects/warpview-ng/src/lib/utils/jsonLib.ts","../../../projects/warpview-ng/src/lib/utils/gts.lib.ts","../../../projects/warpview-ng/src/lib/model/chartBounds.ts","../../../projects/warpview-ng/src/lib/utils/color-lib.ts","../../../projects/warpview-ng/src/lib/utils/chart-lib.ts","../../../projects/warpview-ng/src/lib/model/param.ts","../../../projects/warpview-ng/src/lib/services/resize.service.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-spinner/warp-view-spinner.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-spinner/warp-view-spinner.component.html","../../../projects/warpview-ng/src/lib/plotly/plotly.component.ts","../../../projects/warpview-ng/src/lib/plotly/plotly.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-chart/warp-view-chart.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-chart/warp-view-chart.component.html","../../../projects/warpview-ng/src/lib/services/http-error-handler.service.ts","../../../projects/warpview-ng/src/lib/services/warp10.service.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-display/warp-view-display.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-display/warp-view-display.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-spectrum/warp-view-spectrum.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-spectrum/warp-view-spectrum.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-modal/warp-view-modal.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-modal/warp-view-modal.component.html","../../../projects/warpview-ng/src/lib/model/GTS.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-gts-tree/warp-view-chip/warp-view-chip.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-gts-tree/warp-view-chip/warp-view-chip.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-gts-popup/warp-view-gts-popup.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-gts-popup/warp-view-gts-popup.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-toggle/warp-view-toggle.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-toggle/warp-view-toggle.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-gts-tree/warp-view-gts-tree.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-gts-tree/warp-view-gts-tree.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-annotation/warp-view-annotation.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-annotation/warp-view-annotation.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-resize/warp-view-resize.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-resize/warp-view-resize.component.html","../../../projects/warpview-ng/src/lib/utils/map-lib.ts","../../../projects/warpview-ng/src/lib/utils/timsort.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-slider/warp-view-slider.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-slider/warp-view-slider.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-range-slider/warp-view-range-slider.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-range-slider/warp-view-range-slider.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-map/warp-view-heatmap-sliders/warp-view-heatmap-sliders.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-map/warp-view-heatmap-sliders/warp-view-heatmap-sliders.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-map/warp-view-map.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-map/warp-view-map.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-plot/warp-view-plot.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-plot/warp-view-plot.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-bar/warp-view-bar.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-bar/warp-view-bar.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-bubble/warp-view-bubble.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-bubble/warp-view-bubble.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-datagrid/warp-view-paginable/warp-view-paginable.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-datagrid/warp-view-paginable/warp-view-paginable.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-datagrid/warp-view-datagrid.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-datagrid/warp-view-datagrid.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-drill-down/model/datum.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-drill-down/calendar-heatmap/calendar-heatmap.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-drill-down/calendar-heatmap/calendar-heatmap.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-drill-down/warp-view-drill-down.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-drill-down/warp-view-drill-down.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-image/warp-view-image.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-image/warp-view-image.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-pie/warp-view-pie.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-pie/warp-view-pie.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-gauge/warp-view-gauge.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-gauge/warp-view-gauge.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-event-drop/warp-view-event-drop.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-event-drop/warp-view-event-drop.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-polar/warp-view-polar.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-polar/warp-view-polar.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-radar/warp-view-radar.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-radar/warp-view-radar.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-box/warp-view-box.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-box/warp-view-box.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-3d-line/warp-view-3d-line.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-3d-line/warp-view-3d-line.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-globe/warp-view-globe.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-globe/warp-view-globe.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-result-tile/warp-view-result-tile.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-result-tile/warp-view-result-tile.component.html","../../../projects/warpview-ng/src/lib/elements/warp-view-tile/warp-view-tile.component.ts","../../../projects/warpview-ng/src/lib/elements/warp-view-tile/warp-view-tile.component.html","../../../projects/warpview-ng/src/lib/warp-view-angular.module.ts","../../../projects/warpview-ng/public-api.ts","../../../projects/warpview-ng/warpview.ts"],"sourcesContent":["/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport {Param} from './param';\n\nexport class DataModel {\n data: any[] | string;\n params?: Param[];\n globalParams?: Param;\n bounds?: {\n xmin?: number,\n xmax?: number,\n ymin?: number,\n ymax?: number\n };\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/* tslint:disable:no-console */\n\nexport class Logger {\n\n className: string;\n isDebug = false;\n\n constructor(className: any, isDebug: boolean = false) {\n this.className = className.name;\n this.isDebug = isDebug;\n }\n\n setDebug(debug: boolean) {\n this.isDebug = debug;\n }\n\n log(level: LEVEL, methods: any[], args: any[]) {\n let logChain = [];\n logChain.push(`[${new Date().toISOString()} - [${this.className}] ${methods.join(' - ')}`);\n logChain = logChain.concat(args);\n switch (level) {\n case LEVEL.DEBUG: {\n if (this.isDebug) {\n console.debug(...logChain);\n }\n break;\n }\n case LEVEL.ERROR: {\n console.error(...logChain);\n break;\n }\n case LEVEL.INFO: {\n console.log(...logChain);\n break;\n }\n case LEVEL.WARN: {\n console.warn(...logChain);\n break;\n }\n default: {\n if (this.isDebug) {\n console.log(...logChain);\n }\n }\n }\n }\n\n debug(methods: any[], ...args: any[]) {\n this.log(LEVEL.DEBUG, methods, args);\n }\n\n error(methods: any[], ...args: any[]) {\n this.log(LEVEL.ERROR, methods, args);\n }\n\n warn(methods: any[], ...args: any[]) {\n this.log(LEVEL.WARN, methods, args);\n }\n\n info(methods: any[], ...args: any[]) {\n this.log(LEVEL.INFO, methods, args);\n }\n}\n\nexport enum LEVEL {\n DEBUG, ERROR, WARN, INFO\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n// adapted from Canop's JSON,parseMore https://github.com/Canop/JSON.parseMore/\nexport class JsonLib {\n at;\t // The index of the current character\n ch;\t // The current character\n escapee = {\n '\"': '\"',\n '\\\\': '\\\\',\n '/': '/',\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t'\n };\n text;\n\n private error(m) {\n throw {\n name: 'SyntaxError',\n message: m,\n at: this.at,\n text: this.text\n };\n }\n\n private next() {\n return this.ch = this.text.charAt(this.at++);\n }\n\n private check(c) {\n if (c !== this.ch) {\n this.error('Expected \\'' + c + '\\' instead of \\'' + this.ch + '\\'');\n }\n this.ch = this.text.charAt(this.at++);\n }\n\n private number() {\n let string = '';\n if (this.ch === '-') {\n string = '-';\n this.check('-');\n }\n if (this.ch === 'I') {\n this.check('I');\n this.check('n');\n this.check('f');\n this.check('i');\n this.check('n');\n this.check('i');\n this.check('t');\n this.check('y');\n return -Infinity;\n }\n while (this.ch >= '0' && this.ch <= '9') {\n string += this.ch;\n this.next();\n }\n if (this.ch === '.') {\n string += '.';\n while (this.next() && this.ch >= '0' && this.ch <= '9') {\n string += this.ch;\n }\n }\n if (this.ch === 'e' || this.ch === 'E') {\n string += this.ch;\n this.next();\n if (this.ch === '-' || this.ch === '+') {\n string += this.ch;\n this.next();\n }\n while (this.ch >= '0' && this.ch <= '9') {\n string += this.ch;\n this.next();\n }\n }\n return +string;\n }\n\n private string() {\n let hex;\n let string = '';\n let uffff;\n if (this.ch === '\"') {\n while (this.next()) {\n if (this.ch === '\"') {\n this.next();\n return string;\n }\n if (this.ch === '\\\\') {\n this.next();\n if (this.ch === 'u') {\n uffff = 0;\n for (let i = 0; i < 4; i++) {\n hex = parseInt(this.next(), 16);\n if (!isFinite(hex)) {\n break;\n }\n uffff = uffff * 16 + hex;\n }\n string += String.fromCharCode(uffff);\n } else if (this.escapee[this.ch]) {\n string += this.escapee[this.ch];\n } else {\n break;\n }\n } else {\n string += this.ch;\n }\n }\n }\n this.error('Bad string');\n }\n\n private white() { // Skip whitespace.\n while (this.ch && this.ch <= ' ') {\n this.next();\n }\n }\n\n private word() {\n switch (this.ch) {\n case 't':\n this.check('t');\n this.check('r');\n this.check('u');\n this.check('e');\n return true;\n case 'f':\n this.check('f');\n this.check('a');\n this.check('l');\n this.check('s');\n this.check('e');\n return false;\n case 'n':\n this.check('n');\n this.check('u');\n this.check('l');\n this.check('l');\n return null;\n case 'N':\n this.check('N');\n this.check('a');\n this.check('N');\n return NaN;\n case 'I':\n this.check('I');\n this.check('n');\n this.check('f');\n this.check('i');\n this.check('n');\n this.check('i');\n this.check('t');\n this.check('y');\n return Infinity;\n }\n this.error('Unexpected \\'' + this.ch + '\\'');\n }\n\n private array() {\n const array = [];\n if (this.ch === '[') {\n this.check('[');\n this.white();\n if (this.ch === ']') {\n this.check(']');\n return array; // empty array\n }\n while (this.ch) {\n array.push(this.value());\n this.white();\n if (this.ch === ']') {\n this.check(']');\n return array;\n }\n this.check(',');\n this.white();\n }\n }\n this.error('Bad array');\n }\n\n private object() {\n let key;\n const object = {};\n if (this.ch === '{') {\n this.check('{');\n this.white();\n if (this.ch === '}') {\n this.check('}');\n return object; // empty object\n }\n while (this.ch) {\n key = this.string();\n this.white();\n this.check(':');\n if (Object.hasOwnProperty.call(object, key)) {\n this.error('Duplicate key \"' + key + '\"');\n }\n object[key] = this.value();\n this.white();\n if (this.ch === '}') {\n this.check('}');\n return object;\n }\n this.check(',');\n this.white();\n }\n }\n this.error('Bad object');\n }\n\n private value() {\n this.white();\n switch (this.ch) {\n case '{':\n return this.object();\n case '[':\n return this.array();\n case '\"':\n return this.string();\n case '-':\n return this.number();\n default:\n return this.ch >= '0' && this.ch <= '9' ? this.number() : this.word();\n }\n }\n\n public parse(source, reviver?) {\n let result;\n this.text = source;\n this.at = 0;\n this.ch = ' ';\n result = this.value();\n this.white();\n if (this.ch) {\n this.error('Syntax error');\n }\n return typeof reviver === 'function'\n ? (function walk(holder, key) {\n let k;\n let v;\n const value = holder[key];\n if (value && typeof value === 'object') {\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = walk(value, k);\n if (v !== undefined) {\n value[k] = v;\n } else {\n delete value[k];\n }\n }\n }\n }\n return reviver.call(holder, key, value);\n }({'': result}, ''))\n : result;\n }\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport {DataModel} from '../model/dataModel';\nimport {GTS} from '../model/GTS';\nimport {Logger} from './logger';\nimport moment from 'moment-timezone';\nimport {JsonLib} from './jsonLib';\n\n// @dynamic\nexport class GTSLib {\n private static LOG: Logger = new Logger(GTSLib);\n\n static cleanArray(actual: any[]) {\n return actual.filter((i) => !!i);\n }\n\n static unique(arr) {\n const u = {};\n const a = [];\n for (let i = 0, l = arr.length; i < l; ++i) {\n if (!u.hasOwnProperty(arr[i])) {\n a.push(arr[i]);\n u[arr[i]] = 1;\n }\n }\n return a;\n }\n\n static isArray(value) {\n return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number'\n && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));\n }\n\n static formatElapsedTime(elapsed: number) {\n if (elapsed < 1000) {\n return elapsed.toFixed(3) + ' ns';\n }\n if (elapsed < 1000000) {\n return (elapsed / 1000).toFixed(3) + ' μs';\n }\n if (elapsed < 1000000000) {\n return (elapsed / 1000000).toFixed(3) + ' ms';\n }\n if (elapsed < 1000000000000) {\n return (elapsed / 1000000000).toFixed(3) + ' s ';\n }\n // Max exec time for nice output: 999.999 minutes (should be OK, timeout should happen before that).\n return (elapsed / 60000000000).toFixed(3) + ' m ';\n }\n\n static isValidResponse(data) {\n let response;\n try {\n response = new JsonLib().parse(data);\n } catch (e) {\n this.LOG.error(['isValidResponse'], 'Response non JSON compliant', data);\n return false;\n }\n if (!GTSLib.isArray(response)) {\n this.LOG.error(['isValidResponse'], 'Response isn\\'t an Array', response);\n return false;\n }\n return true;\n }\n\n static isEmbeddedImage(item) {\n return !(typeof item !== 'string' || !/^data:image/.test(item));\n }\n\n static isEmbeddedImageObject(item) {\n return !((item === null) || (item.image === null) ||\n (item.caption === null) || !GTSLib.isEmbeddedImage(item.image));\n }\n\n static isPositionArray(item) {\n if (!item || !item.positions) {\n return false;\n }\n if (GTSLib.isPositionsArrayWithValues(item) || GTSLib.isPositionsArrayWithTwoValues(item)) {\n return true;\n }\n (item.positions || []).forEach(p => {\n if (p.length < 2 || p.length > 3) {\n return false;\n }\n for (const j in p) {\n if (typeof p[j] !== 'number') {\n return false;\n }\n }\n });\n return true;\n }\n\n static isPositionsArrayWithValues(item) {\n if ((item === null) || (item.positions === null)) {\n return false;\n }\n (item.positions || []).forEach(p => {\n if (p.length !== 3) {\n return false;\n }\n for (const j in p) {\n if (typeof p[j] !== 'number') {\n return false;\n }\n }\n });\n return true;\n }\n\n static isPositionsArrayWithTwoValues(item) {\n if ((item === null) || (item.positions === null)) {\n return false;\n }\n (item.positions || []).forEach(p => {\n if (p.length !== 4) {\n return false;\n }\n for (const j in p) {\n if (typeof p[j] !== 'number') {\n return false;\n }\n }\n });\n return true;\n }\n\n static gtsFromJSON(json, id) {\n return {gts: {c: json.c, l: json.l, a: json.a, v: json.v, id}};\n }\n\n static uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n // tslint:disable-next-line:no-bitwise\n const r = Math.random() * 16 | 0;\n // tslint:disable-next-line:no-bitwise\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n }\n\n static gtsFromJSONList(jsonList, prefixId) {\n const gtsList = [];\n let id;\n (jsonList || []).forEach((item, i) => {\n let gts = item;\n if (item.gts) {\n gts = item.gts;\n }\n if ((prefixId !== undefined) && (prefixId !== '')) {\n id = prefixId + '-' + i;\n } else {\n id = i;\n }\n if (GTSLib.isArray(gts)) {\n gtsList.push(GTSLib.gtsFromJSONList(gts, id));\n }\n if (GTSLib.isGts(gts)) {\n gtsList.push(GTSLib.gtsFromJSON(gts, id));\n }\n if (GTSLib.isEmbeddedImage(gts)) {\n gtsList.push({image: gts, caption: 'Image', id});\n }\n if (GTSLib.isEmbeddedImageObject(gts)) {\n gtsList.push({image: gts.image, caption: gts.caption, id});\n }\n });\n return {\n content: gtsList || [],\n };\n }\n\n static flatDeep(arrays: any[]): any[] {\n const result = [];\n if (!GTSLib.isArray(arrays)) {\n arrays = [arrays];\n }\n GTSLib.flatten(arrays, result);\n return result;\n }\n\n static flatten(arr, result = []) {\n const size = arr.length;\n for (let i = 0; i < size; i++) {\n const value = arr[i];\n if (Array.isArray(value)) {\n GTSLib.flatten(value, result);\n } else {\n result.push(value);\n }\n }\n return result;\n }\n\n static flattenGtsIdArray(a: any[], r: number): { res: any[], r: number } {\n const res = [];\n if (GTSLib.isGts(a)) {\n a = [a];\n }\n (a || []).forEach(d => {\n if (GTSLib.isArray(d)) {\n const walk = GTSLib.flattenGtsIdArray(d, r);\n res.push(walk.res);\n r = walk.r;\n } else if (d && d.v) {\n d.id = r;\n res.push(d);\n r++;\n }\n });\n return {res, r};\n }\n\n static sanitizeNames(input: string): string {\n return (input || '').replace(/{/g, '{')\n .replace(/}/g, '}')\n .replace(/,/g, ',')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n }\n\n static serializeGtsMetadata(gts) {\n const serializedLabels = [];\n const serializedAttributes = [];\n if (gts.l) {\n Object.keys(gts.l).forEach((key) => {\n serializedLabels.push(this.sanitizeNames(key + '=' + gts.l[key]));\n });\n }\n if (gts.a) {\n Object.keys(gts.a).forEach((key) => {\n serializedAttributes.push(this.sanitizeNames(key + '=' + gts.a[key]));\n });\n }\n // tslint:disable-next-line:max-line-length\n return `${this.sanitizeNames(gts.c)}{${serializedLabels.join(',')}${serializedAttributes.length > 0 ? ',' : ''}${serializedAttributes.join(',')}}`;\n }\n\n static isGts(item) {\n return !!item && (item.c === '' || !!item.c) && !!item.v && GTSLib.isArray(item.v);\n }\n\n static isGtsToPlot(gts) {\n if (!GTSLib.isGts(gts) || gts.v.length === 0) {\n return false;\n }\n // We look at the first non-null value, if it's a String or Boolean it's an annotation GTS,\n // if it's a number it's a GTS to plot\n return (gts.v || []).some(v => {\n // noinspection JSPotentiallyInvalidConstructorUsage\n return typeof v[v.length - 1] === 'number' || !!v[v.length - 1].constructor.prototype.toFixed;\n });\n }\n\n static isGtsToPlotOnMap(gts) {\n if (!GTSLib.isGts(gts) || gts.v.length === 0) {\n return false;\n }\n // We look at the first non-null value, if it's a String or Boolean it's an annotation GTS,\n // if it's a number it's a GTS to plot\n return (gts.v || []).some(v => {\n return v.length >= 3;\n });\n }\n\n static isSingletonGTS(gts) {\n if (!GTSLib.isGts(gts) || gts.v.length === 0) {\n return false;\n }\n return (gts.v || []).length === 1;\n }\n\n static isGtsToAnnotate(gts) {\n if (!GTSLib.isGts(gts) || gts.v.length === 0) {\n return false;\n }\n // We look at the first non-null value, if it's a String or Boolean it's an annotation GTS,\n // if it's a number it's a GTS to plot\n return (gts.v || []).some(v => {\n if (v[v.length - 1] !== null) {\n // noinspection JSPotentiallyInvalidConstructorUsage\n return typeof (v[v.length - 1]) !== 'number' &&\n (!!v[v.length - 1].constructor && v[v.length - 1].constructor.name !== 'Big') &&\n v[v.length - 1].constructor.prototype.toFixed === undefined;\n }\n });\n }\n\n static gtsSort(gts) {\n if (gts.isSorted) {\n return;\n }\n gts.v = gts.v.sort((a, b) => a[0] - b[0]);\n gts.isSorted = true;\n }\n\n static getData(data: any): DataModel {\n if (typeof data === 'string') {\n if (data.startsWith('[') || data.startsWith('{')) {\n return GTSLib.getData(new JsonLib().parse(data as string));\n } else {\n return {data: new JsonLib().parse(`[${data}]`)};\n }\n } else if (data && data.hasOwnProperty('data')) {\n if (!GTSLib.isArray(data.data)) {\n data.data = [data.data];\n }\n return data as DataModel;\n } else if (GTSLib.isArray(data) && data.length > 0 && data[0].data) {\n return data[0] as DataModel;\n } else if (GTSLib.isArray(data)) {\n return {data: data as GTS[]} as DataModel;\n }\n return new DataModel();\n }\n\n static getDivider(timeUnit: string): number {\n let timestampDivider = 1000; // default for µs timeunit\n if (timeUnit === 'ms') {\n timestampDivider = 1;\n }\n if (timeUnit === 'ns') {\n timestampDivider = 1000000;\n }\n return timestampDivider;\n }\n\n static formatLabel(data: string): string {\n const serializedGTS = data.split('{');\n let display = `<span class=\"gtsInfo\"><span class='gts-classname'>${serializedGTS[0]}</span>`;\n if (serializedGTS.length > 1) {\n display += `<span class='gts-separator'>{</span>`;\n const labels = serializedGTS[1].substr(0, serializedGTS[1].length - 1).split(',');\n if (labels.length > 0) {\n labels.forEach((l, i) => {\n const label = l.split('=');\n if (l.length > 1) {\n display += `<span><span class='gts-labelname'>${label[0]}</span>\n<span class='gts-separator'>=</span><span class='gts-labelvalue'>${label[1]}</span>`;\n if (i !== labels.length - 1) {\n display += `<span>, </span>`;\n }\n }\n });\n }\n display += `<span class='gts-separator'>}</span>`;\n }\n if (serializedGTS.length > 2) {\n display += `<span class='gts-separator'>{</span>`;\n const labels = serializedGTS[2].substr(0, serializedGTS[2].length - 1).split(',');\n if (labels.length > 0) {\n labels.forEach((l, i) => {\n const label = l.split('=');\n if (l.length > 1) {\n display += `<span><span class='gts-attrname'>${label[0]}</span>\n<span class='gts-separator'>=</span><span class='gts-attrvalue'>${label[1]}</span>`;\n if (i !== labels.length - 1) {\n display += `<span>, </span>`;\n }\n }\n });\n }\n display += `<span class='gts-separator'>}</span>`;\n }\n display += '</span>';\n return display;\n }\n\n static toISOString(timestamp: number, divider: number, timeZone: string) {\n if (timeZone !== 'UTC') {\n return moment.tz(timestamp / divider, timeZone).format();\n } else {\n return moment.utc(timestamp / divider).toISOString();\n }\n }\n\n static toTimestamp(date: string, divider: number, timeZone: string) {\n if (timeZone !== 'UTC') {\n return moment.tz(date, timeZone).utc().valueOf() * divider;\n } else {\n return moment.utc(date).valueOf() * divider;\n }\n }\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nexport class ChartBounds {\n tsmin = 0;\n tsmax = 0;\n msmin = '';\n msmax = '';\n marginLeft = 0;\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nexport enum Colors {\n COHESIVE = 'COHESIVE',\n COHESIVE_2 = 'COHESIVE_2',\n BELIZE = 'BELIZE',\n VIRIDIS = 'VIRIDIS',\n MAGMA = 'MAGMA',\n INFERNO = 'INFERNO',\n PLASMA = 'PLASMA',\n YL_OR_RD = 'YL_OR_RD',\n YL_GN_BU = 'YL_GN_BU',\n BU_GN = 'BU_GN',\n WARP10 = 'WARP10',\n NINETEEN_EIGHTY_FOUR = 'NINETEEN_EIGHTY_FOUR',\n ATLANTIS = 'ATLANTIS',\n DO_ANDROIDS_DREAM = 'DO_ANDROIDS_DREAM',\n DELOREAN = 'DELOREAN',\n CTHULHU = 'CTHULHU',\n ECTOPLASM = 'ECTOPLASM',\n T_MAX_400_FILM = 'T_MAX_400_FILM',\n}\n\nexport class ColorLib {\n static color = {\n COHESIVE: ['#F2D354', '#E4612F', '#D32C2E', '#6D2627', '#6C7F55', '#934FC6', '#F07A5D', '#ED8371', '#94E751',\n '#C457F7', '#973AF7', '#B6FF7A', '#C7FFD5', '#90E4D0', '#E09234', '#D2FF91', '#17B201'],\n COHESIVE_2: ['#6F694E', '#65D0B2', '#D8F546', '#FF724B', '#D6523E', '#F9F470', '#F4BC78', '#B1D637', '#FFCFC8',\n '#56CDAB', '#CFDD22', '#B3F5D2', '#97DB29', '#9DC5EE', '#CFC0F5', '#EDEA29', '#5EC027', '#386C94'],\n BELIZE: ['#5899DA', '#E8743B', '#19A979', '#ED4A7B', '#945ECF', '#13A4B4', '#525DF4', '#BF399E', '#6C8893',\n '#EE6868', '#2F6497'],\n VIRIDIS: ['#440154', '#481f70', '#443983', '#3b528b', '#31688e', '#287c8e', '#21918c', '#20a486', '#35b779',\n '#5ec962', '#90d743', '#c8e020'],\n MAGMA: ['#000004', '#100b2d', '#2c115f', '#51127c', '#721f81', '#932b80', '#b73779', '#d8456c', '#f1605d',\n '#fc8961', '#feb078', '#fed799'],\n INFERNO: ['#000004', '#110a30', '#320a5e', '#57106e', '#781c6d', '#9a2865', '#bc3754', '#d84c3e', '#ed6925',\n '#f98e09', '#fbb61a', '#f4df53'],\n PLASMA: ['#0d0887', '#3a049a', '#5c01a6', '#7e03a8', '#9c179e', '#b52f8c', '#cc4778', '#de5f65', '#ed7953',\n '#f89540', '#fdb42f', '#fbd524'],\n YL_OR_RD: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'],\n YL_GN_BU: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'],\n BU_GN: ['#f7fcfd', '#ebf7fa', '#dcf2f2', '#c8eae4', '#aadfd2', '#88d1bc', '#68c2a3', '#4eb485', '#37a266',\n '#228c49', '#0d7635', '#025f27'],\n WARP10: [\n '#ff9900', '#E53935', '#F4511E', '#D81B60',\n '#00ACC1', '#1E88E5', '#43A047', '#FFB300',\n '#6D4C41', '#FDD835', '#00897B', '#3949AB',\n '#5E35B1', '#8E24AA', '#C0CA33', '#039BE5',\n '#7CB342', '#004eff'],\n NINETEEN_EIGHTY_FOUR: ['#fc9ca2', '#fb747d', '#fa4c58', '#f92432', '#e30613', '#c70512', '#9f040e', '#77030b', '#500207'],\n ATLANTIS: ['#edf2fb', '#e2eafc', '#d7e3fc', '#ccdbfd', '#c1d3fe', '#b6ccfe', '#abc4ff'],\n DO_ANDROIDS_DREAM: ['#d8f3dc', '#b7e4c7', '#95d5b2', '#74c69d', '#52b788', '#40916c', '#2d6a4f', '#1b4332',\n '#081c15'],\n DELOREAN: ['#b98b73', '#cb997e', '#ddbea9', '#ffe8d6', '#d4c7b0', '#b7b7a4', '#a5a58d', '#6b705c', '#3f4238'],\n CTHULHU: ['#004c6d', '#006083', '#007599', '#008bad', '#00a1c1', '#00b8d3', '#00cfe3', '#00e7f2', '#00ffff'],\n ECTOPLASM: ['#006466', '#065a60', '#0b525b', '#144552', '#1b3a4b', '#212f45', '#272640', '#312244', '#3e1f47', '#4d194d'],\n T_MAX_400_FILM: ['#f8f9fa', '#e9ecef', '#dee2e6', '#ced4da', '#adb5bd', '#6c757d', '#495057', '#343a40', '#212529'],\n MATRIX: ['#025f27', '#025f27', '#0d7635', '#228c49', '#37a266', '#4eb485', '#68c2a3', '#88d1bc'],\n CHARTANA: ['#77BE69', '#FADE2B', '#F24865', '#5694F2',\n '#FF9830', '#B876D9'],\n };\n\n static getColor(i: number, scheme: string) {\n if (!ColorLib.color[scheme]) {\n scheme = 'WARP10';\n }\n return ColorLib.color[scheme][i % 2 === 0\n ? i % ColorLib.color[scheme].length\n : ColorLib.color[scheme].length - i % ColorLib.color[scheme].length\n ];\n }\n\n static getColorGradient(id: number, scheme: string) {\n return [\n [0, ColorLib.transparentize(ColorLib.getColor(id, scheme), 0)],\n [1, ColorLib.transparentize(ColorLib.getColor(id, scheme), 0.7)]\n ];\n }\n\n static getBlendedColorGradient(id: number, scheme: string, bg = '#000000') {\n return [\n [0, ColorLib.blend_colors(bg, ColorLib.getColor(id, scheme), 0)],\n [1, ColorLib.blend_colors(bg, ColorLib.getColor(id, scheme), 1)]\n ];\n }\n\n static hexToRgb(hex) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? [\n parseInt(result[1], 16),\n parseInt(result[2], 16),\n parseInt(result[3], 16)\n ] : null;\n }\n\n static transparentize(color, alpha = 0.5): string {\n return 'rgba(' + ColorLib.hexToRgb(color).concat(alpha).join(',') + ')';\n }\n\n static generateTransparentColors(num, scheme) {\n const color = [];\n for (let i = 0; i < num; i++) {\n color.push(ColorLib.transparentize(ColorLib.getColor(i, scheme)));\n }\n return color;\n }\n\n static hsvGradientFromRgbColors(c1, c2, steps) {\n const c1hsv = ColorLib.rgb2hsv(c1.r, c1.g, c1.b);\n const c2hsv = ColorLib.rgb2hsv(c2.r, c2.g, c2.b);\n c1.h = c1hsv[0];\n c1.s = c1hsv[1];\n c1.v = c1hsv[2];\n c2.h = c2hsv[0];\n c2.s = c2hsv[1];\n c2.v = c2hsv[2];\n const gradient = ColorLib.hsvGradient(c1, c2, steps);\n for (const i in gradient) {\n if (gradient[i]) {\n gradient[i].rgb = ColorLib.hsv2rgb(gradient[i].h, gradient[i].s, gradient[i].v);\n gradient[i].r = Math.floor(gradient[i].rgb[0]);\n gradient[i].g = Math.floor(gradient[i].rgb[1]);\n gradient[i].b = Math.floor(gradient[i].rgb[2]);\n }\n }\n return gradient;\n }\n\n private static rgb2hsv(r: number, g: number, b: number) {\n // Normalize\n const normR = r / 255.0;\n const normG = g / 255.0;\n const normB = b / 255.0;\n const M = Math.max(normR, normG, normB);\n const m = Math.min(normR, normG, normB);\n const d = M - m;\n let h;\n let s;\n let v;\n v = M;\n if (d === 0) {\n h = 0;\n s = 0;\n } else {\n s = d / v;\n switch (M) {\n case normR:\n h = ((normG - normB) + d * (normG < normB ? 6 : 0)) / 6 * d;\n break;\n case normG:\n h = ((normB - normR) + d * 2) / 6 * d;\n break;\n case normB:\n h = ((normR - normG) + d * 4) / 6 * d;\n break;\n }\n }\n return [h, s, v];\n }\n\n private static hsvGradient(c1: any, c2: any, steps: any) {\n const gradient = new Array(steps);\n // determine clockwise and counter-clockwise distance between hues\n const distCCW = (c1.h >= c2.h) ? c1.h - c2.h : 1 + c1.h - c2.h;\n const distCW = (c1.h >= c2.h) ? 1 + c2.h - c1.h : c2.h - c1.h;\n // make gradient for this part\n for (let i = 0; i < steps; i++) {\n // interpolate h, s, b\n let h = (distCW <= distCCW) ? c1.h + (distCW * i / (steps - 1)) : c1.h - (distCCW * i / (steps - 1));\n if (h < 0) {\n h = 1 + h;\n }\n if (h > 1) {\n h = h - 1;\n }\n const s = (1 - i / (steps - 1)) * c1.s + i / (steps - 1) * c2.s;\n const v = (1 - i / (steps - 1)) * c1.v + i / (steps - 1) * c2.v;\n // add to gradient array\n gradient[i] = {h, s, v};\n }\n return gradient;\n }\n\n private static hsv2rgb(h: any, s: any, v: any) {\n let r;\n let g;\n let b;\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n switch (i % 6) {\n case 0:\n r = v;\n g = t;\n b = p;\n break;\n case 1:\n r = q;\n g = v;\n b = p;\n break;\n case 2:\n r = p;\n g = v;\n b = t;\n break;\n case 3:\n r = p;\n g = q;\n b = v;\n break;\n case 4:\n r = t;\n g = p;\n b = v;\n break;\n case 5:\n r = v;\n g = p;\n b = q;\n break;\n }\n return [r * 255, g * 255, b * 255];\n }\n\n static rgb2hex(r, g, b) {\n function componentToHex(c) {\n const hex = c.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n }\n\n return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b);\n }\n\n static blend_colors(color1, color2, percentage) {\n // check input\n color1 = color1 || '#000000';\n color2 = color2 || '#ffffff';\n percentage = percentage || 0.5;\n // 1: validate input, make sure we have provided a valid hex\n if (color1.length !== 4 && color1.length !== 7) {\n throw new Error('colors must be provided as hexes');\n }\n if (color2.length !== 4 && color2.length !== 7) {\n throw new Error('colors must be provided as hexes');\n }\n if (percentage > 1 || percentage < 0) {\n throw new Error('percentage must be between 0 and 1');\n }\n // 2: check to see if we need to convert 3 char hex to 6 char hex, else slice off hash\n // the three character hex is just a representation of the 6 hex where each character is repeated\n // ie: #060 => #006600 (green)\n if (color1.length === 4) {\n color1 = color1[1] + color1[1] + color1[2] + color1[2] + color1[3] + color1[3];\n } else {\n color1 = color1.substring(1);\n }\n if (color2.length === 4) {\n color2 = color2[1] + color2[1] + color2[2] + color2[2] + color2[3] + color2[3];\n } else {\n color2 = color2.substring(1);\n }\n // 3: we have valid input, convert colors to rgb\n color1 = [parseInt(color1[0] + color1[1], 16), parseInt(color1[2] + color1[3], 16), parseInt(color1[4] + color1[5], 16)];\n color2 = [parseInt(color2[0] + color2[1], 16), parseInt(color2[2] + color2[3], 16), parseInt(color2[4] + color2[5], 16)];\n // 4: blend\n const color3 = [\n (1 - percentage) * color1[0] + percentage * color2[0],\n (1 - percentage) * color1[1] + percentage * color2[1],\n (1 - percentage) * color1[2] + percentage * color2[2]\n ];\n // return hex\n return '#' + ColorLib.int_to_hex(color3[0]) + ColorLib.int_to_hex(color3[1]) + ColorLib.int_to_hex(color3[2]);\n }\n\n /*\n convert a Number to a two character hex string\n must round, or we will end up with more digits than expected (2)\n note: can also result in single digit, which will need to be padded with a 0 to the left\n @param: num => the number to conver to hex\n @returns: string => the hex representation of the provided number\n */\n static int_to_hex(num: number) {\n let hex = Math.round(num).toString(16);\n if (hex.length === 1) {\n hex = '0' + hex;\n }\n return hex;\n }\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n// @dynamic\nexport class ChartLib {\n\n static DEFAULT_WIDTH = 640;\n static DEFAULT_HEIGHT = 480;\n\n static mergeDeep<T>(base: T, ext: any) {\n const obj = {...base} as T;\n const extended = {...ext} as T;\n for (const prop in extended || {}) {\n // If property is an object, merge properties\n if (Object.prototype.toString.call(extended[prop]) === '[object Object]') {\n obj[prop] = ChartLib.mergeDeep<T>(obj[prop], extended[prop]);\n } else {\n obj[prop] = extended[prop];\n }\n }\n return obj as T;\n }\n\n static fraction2r(rl0, rl1, v) {\n return v * (rl1 - rl0);\n }\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nexport class Param {\n scheme = 'WARP10';\n bgColor?: string;\n datasetColor?: string;\n fontColor?: string;\n borderColor?: string;\n showlegend = false;\n responsive?: boolean;\n horizontal = false;\n stacked = false;\n key?: string;\n unit?: string;\n type?: string;\n showRangeSelector?: boolean;\n autoRefresh?: number;\n showControls = true;\n showErrors = true;\n showStatus = false;\n expandAnnotation = false;\n showGTSTree?: boolean;\n foldGTSTree?: boolean;\n timeMode?: 'timestamp' | 'date' | 'custom' | 'duration';\n showDots = false;\n delta?: number;\n timeUnit: 'us' | 'ms' | 'ns' = 'us';\n minColor?: string;\n maxColor?: string;\n startColor?: string;\n endColor?: string;\n numColorSteps?: number;\n split?: 'Y' | 'M' | 'D' | 'h' | 'm' | 's';\n popupButtonValidateClass?: string;\n popupButtonValidateLabel?: string;\n timeZone = 'UTC';\n properties?: any;\n map?: {\n tiles?: any[] ;\n heatRadius?: number;\n heatBlur?: number;\n heatOpacity?: number;\n heatControls?: boolean;\n mapType?: string;\n showTimeSlider?: boolean;\n showTimeRange?: boolean;\n timeSliderMin?: number;\n timeSliderMax?: number;\n timeSliderStep?: number;\n timeSliderMode?: 'timestamp' | 'date' | 'custom';\n timeStart?: number,\n timeSpan?: number,\n startLat?: number;\n startLong?: number;\n startZoom?: number;\n timeSpanList?: any[],\n animate?: boolean;\n maxNativeZoom?: number;\n maxZoom?: number;\n hideScale?: boolean;\n } = {\n tiles: [],\n showTimeSlider: false,\n showTimeRange: false,\n timeSliderMode: 'timestamp'\n };\n bounds: {\n minDate?: number;\n maxDate?: number;\n yRanges?: [number, number];\n } = {};\n histo?: {\n histnorm: 'percent' | 'probability' | 'density' | 'probability density';\n histfunc: 'count' | 'sum' | 'avg' | 'min' | 'max';\n };\n maxValue: number;\n isRefresh?: boolean;\n elemsCount?: number;\n windowed?: number;\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport {EventEmitter, Injectable} from '@angular/core';\nimport {Subject} from 'rxjs';\nimport {debounceTime} from 'rxjs/operators';\n\nexport class Size {\n constructor(public width: number, public height: number) {\n }\n}\n\n\n@Injectable()\nexport class SizeService {\n private debouncer: Subject<Size> = new Subject<Size>();\n public sizeChanged$: EventEmitter<Size> = new EventEmitter();\n\n\n constructor() {\n this.debouncer\n .pipe(debounceTime(100))\n .subscribe((value) => this.sizeChanged$.emit(value));\n }\n\n public change(size: Size): void {\n this.debouncer.next(size);\n }\n}\n","/*\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport {ChartLib} from '../utils/chart-lib';\nimport {Param} from '../model/param';\nimport {Logger} from '../utils/logger';\nimport {DataModel} from '../model/dataModel';\nimport {GTS} from '../model/GTS';\nimport {GTSLib} from '../utils/gts.lib';\nimport {Directive, ElementRef, EventEmitter, Input, NgZone, Output, Renderer2, ViewChild} from '@angular/core';\nimport {Size, SizeService} from '../services/resize.service';\nimport {PlotlyComponent} from '../plotly/plotly.component';\nimport {Config} from 'plotly.js';\n\nexport type VisibilityState = 'unknown' | 'nothingPlottable' | 'plottablesAllHidden' | 'plottableShown';\n\n@Directive()\n// tslint:disable-next-line:directive-class-suffix\nexport abstract class WarpViewComponent {\n @ViewChild('toolTip', {static: true}) toolTip: ElementRef;\n @ViewChild('graph') graph: PlotlyComponent;\n @ViewChild('chartContainer', {static: true}) chartContainer: ElementRef;\n\n @Input('width') width = ChartLib.DEFAULT_WIDTH;\n @Input('height') height = ChartLib.DEFAULT_HEIGHT;\n protected drawn = false;\n protected _type: string;\n\n @Input('hiddenData') set hiddenData(hiddenData: number[]) {\n this._hiddenData = hiddenData;\n }\n\n get hiddenData(): number[] {\n return this._hiddenData;\n }\n\n @Input('unit') set unit(unit: string) {\n this._unit = unit;\n if (!!this._data) {\n this.update(undefined, false);\n }\n }\n\n get unit() {\n return this._unit;\n }\n\n @Input('debug') set debug(debug: boolean | string) {\n if (typeof debug === 'string') {\n debug = 'true' === debug;\n }\n this._debug = debug;\n this.LOG.setDebug(debug);\n }\n\n get debug() {\n return this._debug;\n }\n\n @Input('responsive') set responsive(responsive: boolean | string) {\n if (typeof responsive === 'string') {\n responsive = 'true' === responsive;\n }\n this._responsive = responsive;\n }\n\n get responsive() {\n return this._responsive;\n }\n\n @Input('options') set options(options: Param | string) {\n this.LOG.debug(['onOptions'], options, {...this._options});\n if (typeof options === 'string') {\n options = JSON.parse(options);\n }\n if (JSON.stringify(options) !== JSON.stringify(this._options)) {\n this.drawn = false;\n this.LOG.debug(['onOptions', 'changed'], options, {...this._options});\n this._o