@senx/discovery-widgets
Version:
Discovery Widgets Elements
531 lines (530 loc) • 22.4 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 { DataModel } from "../../model/types";
import { Param } from "../../model/param";
import { Logger } from "../../utils/logger";
import { GTSLib } from "../../utils/gts.lib";
import fitty from "fitty";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { Utils } from "../../utils/utils";
import domtoimage from "dom-to-image";
import showdown from "showdown";
dayjs.extend(relativeTime);
export class DiscoveryDisplayComponent {
constructor() {
this.options = new Param();
this.debug = false;
this.unit = '';
this.parsing = false;
this.rendering = false;
this.message = '';
this.defOptions = Object.assign(Object.assign({}, new Param()), { responsive: true });
this.divider = 1000;
this.initial = false;
this.chartOptions = Object.assign(Object.assign({}, new Param()), { hideXAxis: true, hideYAxis: true, bgColor: 'transparent', scheme: 'ATLANTIS' });
}
updateRes(newValue) {
var _a;
const message = this.convert((_a = GTSLib.getData(newValue)) !== null && _a !== void 0 ? _a : new DataModel());
if (message !== this.message) {
this.message = message;
this.fitContent();
}
}
optionsUpdate(newValue, oldValue) {
var _a, _b, _c;
(_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 = Utils.clone(opts);
this.chartOptions = Utils.clone(Object.assign(Object.assign({}, this.chartOptions), { fontColor: this.innerOptions.fontColor }));
this.message = this.convert((_b = this.result) !== null && _b !== void 0 ? _b : new DataModel());
(_c = this.LOG) === null || _c === void 0 ? void 0 : _c.debug(['optionsUpdate 2'], { options: this.innerOptions, newValue, oldValue }, this.chartOptions);
}
this.fitContent();
}
discoveryEventHandler(event) {
var _a;
const res = Utils.parseEventData(event.detail, ((_a = this.innerOptions) === null || _a === void 0 ? void 0 : _a.eventHandler) || '', this.el.id);
if (res.style) {
this.innerStyle = Utils.clone(Object.assign(Object.assign({}, this.innerStyle), res.style));
}
}
async resize() {
const dims = Utils.getContentBounds(this.el.parentElement);
this.width = dims.w;
this.height = dims.h;
if (this.wrapper) {
const height = Utils.getContentBounds(this.wrapper.parentElement).h - 20;
if (height !== this.innerHeight) {
this.innerHeight = height;
}
this.fitContent();
}
return Promise.resolve();
}
// noinspection JSUnusedLocalSymbols
async export(_type = 'png') {
let bgColor = Utils.getCSSColor(this.el, '--warp-view-bg-color', 'transparent');
bgColor = ((this.innerOptions) || { bgColor }).bgColor || bgColor;
const dm = ((this.result || {
globalParams: { bgColor },
}).globalParams || { bgColor });
bgColor = dm.bgColor || bgColor;
return await domtoimage.toPng(this.pngWrapper, { height: this.height, width: this.width, bgcolor: bgColor });
}
// noinspection JSUnusedGlobalSymbols
componentWillLoad() {
var _a, _b, _c;
this.parsing = true;
this.LOG = new Logger(DiscoveryDisplayComponent, this.debug);
if (typeof this.options === 'string') {
this.innerOptions = JSON.parse(this.options);
}
else {
this.innerOptions = this.options;
}
this.chartOptions = Utils.clone(Object.assign(Object.assign({}, this.chartOptions), { fontColor: this.innerOptions.fontColor }));
this.result = GTSLib.getData(this.result);
this.divider = GTSLib.getDivider((_a = this.innerOptions.timeUnit) !== null && _a !== void 0 ? _a : 'us');
this.message = this.convert((_b = this.result) !== null && _b !== void 0 ? _b : new DataModel());
(_c = this.LOG) === null || _c === void 0 ? void 0 : _c.debug(['componentWillLoad'], {
type: this.type,
options: this.innerOptions,
});
}
// noinspection JSUnusedGlobalSymbols
componentDidLoad() {
setTimeout(() => {
var _a;
this.height = Utils.getContentBounds(this.el.parentElement).h;
this.initial = true;
this.parsing = false;
if (this.wrapper) {
const height = Utils.getContentBounds(this.wrapper.parentElement).h - 20;
if (height !== this.innerHeight) {
this.innerHeight = height;
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['flexFont'], height);
}
this.fitContent();
}
this.initial = false;
this.draw.emit();
});
}
fitContent() {
var _a, _b;
if (this.innerOptions.responsive && !((_b = (_a = this.innerOptions) === null || _a === void 0 ? void 0 : _a.display) === null || _b === void 0 ? void 0 : _b.markdown)) {
if (!this.fitties) {
const height = Utils.getContentBounds(this.wrapper.parentElement).h - 20;
this.fitties = fitty(this.wrapper, {
maxSize: height * 0.80, minSize: 14, observeMutations: {
subtree: false,
childList: false,
characterData: true,
},
});
}
this.fitties.fit();
}
else {
if (this.fitties) {
this.fitties.unsubscribe();
this.fitties = null;
this.wrapper.style.fontSize = ''; // unsubscribe do not exactly restore the previous state
}
}
}
// noinspection JSUnusedGlobalSymbols
disconnectedCallback() {
if (this.timer) {
clearInterval(this.timer);
}
if (this.fitties) {
this.fitties.unsubscribe();
}
}
convert(dataModel) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
if (this.timer) {
clearInterval(this.timer);
}
let options = Utils.mergeDeep(this.defOptions, (_a = this.innerOptions) !== null && _a !== void 0 ? _a : {});
options = Utils.mergeDeep(options !== null && options !== void 0 ? options : {}, dataModel.globalParams);
this.innerOptions = Utils.clone(options);
if (this.innerOptions.customStyles) {
this.innerStyle = Utils.clone(Object.assign(Object.assign({}, this.innerStyle), (_b = this.innerOptions.customStyles) !== null && _b !== void 0 ? _b : {}));
}
this.chartOptions = Utils.clone(Object.assign(Object.assign({}, this.chartOptions), { fontColor: this.innerOptions.fontColor }));
(_c = this.LOG) === null || _c === void 0 ? void 0 : _c.debug(['convert'], 'dataModel', dataModel);
let display;
if (dataModel.data !== undefined) {
display = GTSLib.isArray(dataModel.data) ? (_d = dataModel.data[0]) !== null && _d !== void 0 ? _d : this.message : (_e = dataModel.data) !== null && _e !== void 0 ? _e : this.message;
}
else {
display = GTSLib.isArray(dataModel) ? (_f = dataModel[0]) !== null && _f !== void 0 ? _f : this.message : dataModel !== null && dataModel !== void 0 ? dataModel : this.message;
}
display = GTSLib.isArray(display) ? (_g = display[0]) !== null && _g !== void 0 ? _g : this.message : display !== null && display !== void 0 ? display : this.message;
if (GTSLib.isGts(display)) {
this.gts = [display];
let v = (_j = (_h = this.innerOptions.display) === null || _h === void 0 ? void 0 : _h.value) !== null && _j !== void 0 ? _j : '';
if (((_k = this.innerOptions.display) === null || _k === void 0 ? void 0 : _k.value) === undefined && display.v && display.v.length > 0) {
const dataPoint = display.v[display.v.length - 1];
v = dataPoint[dataPoint.length - 1];
if ((_l = this.innerOptions.display) === null || _l === void 0 ? void 0 : _l.decimals) {
const dec = Math.pow(10, (_o = (_m = this.innerOptions.display) === null || _m === void 0 ? void 0 : _m.decimals) !== null && _o !== void 0 ? _o : 2);
v = Math.round(parseFloat(v + '') * dec) / dec;
}
}
display = v;
}
if (display && display.hasOwnProperty('text')) {
if (display.hasOwnProperty('url')) {
display = `<a href="${display.url}" target="_blank">${display.text}</a>`;
}
else {
display = display.text;
}
}
switch (this.innerOptions.timeMode) {
case 'date':
if (display && !isNaN(parseInt(display, 10))) {
display = GTSLib.toISOString(parseInt(display, 10), this.divider, this.innerOptions.timeZone, this.innerOptions.fullDateDisplay ? this.innerOptions.timeFormat : undefined);
}
break;
case 'duration':
if (display && !isNaN(parseInt(display, 10))) {
const start = GTSLib.toISOString(parseInt(display, 10), this.divider, this.innerOptions.timeZone, this.innerOptions.fullDateDisplay ? this.innerOptions.timeFormat : undefined);
display = this.displayDuration(dayjs(start));
}
break;
case 'custom':
case 'timestamp':
display = decodeURIComponent(decodeURIComponent(display));
}
if ((_q = (_p = this.innerOptions) === null || _p === void 0 ? void 0 : _p.display) === null || _q === void 0 ? void 0 : _q.markdown) {
const converter = new showdown.Converter({
emoji: true,
tables: true,
tasklists: true,
flavor: 'github',
moreStyling: true,
parseImgDimensions: true,
requireSpaceBeforeHeadingText: true,
simpleLineBreaks: false,
encodeEmails: false,
simplifiedAutoLink: false,
metadata: true,
ghCodeBlocks: true,
});
display = converter.makeHtml(display);
}
return display === undefined ? '' : display.toString();
}
render() {
var _a, _b, _c, _d, _e, _f;
return h("div", { key: '140844f32ead047e9618a6a521a6fc9e43a30ac6', ref: (el) => this.pngWrapper = el, class: "png-wrapper" }, h("style", { key: 'a39ee2a909127b7cabc580fb378e9bb9e02e4894' }, this.generateStyle(this.innerStyle)), h("div", { key: '7ff6c220a459d21205fa6a1948e9942b5272845b', style: { color: this.innerOptions.fontColor }, class: this.getClass() }, this.parsing ? h("discovery-spinner", null, "Parsing data...") : '', this.rendering ? h("discovery-spinner", null, "Rendering data...") : '', h("div", { key: '603deb23419ca326d3a3a15fbc3fcfa4e84e5eea', ref: (el) => this.wrapper = el, class: "value" }, h("span", { key: '5c806adbf4c18678d1a6c2b091efb8b17f37a77f', innerHTML: this.message === undefined ? '' : this.message }), h("small", { key: '86967a5aa67288fbed7716e5890cec57d2ad1a5b' }, (_b = (_a = this.innerOptions.unit) !== null && _a !== void 0 ? _a : this.unit) !== null && _b !== void 0 ? _b : ''))), this.gts && ((_c = this.innerOptions.display) === null || _c === void 0 ? void 0 : _c.showChart)
? h("div", { class: "chart-wrapper" }, h("div", null, h("discovery-tile-result", { url: "", result: (_d = this.gts) !== null && _d !== void 0 ? _d : [], type: (_f = (_e = this.innerOptions.display) === null || _e === void 0 ? void 0 : _e.chartType) !== null && _f !== void 0 ? _f : 'area', options: this.chartOptions })))
: '');
}
displayDuration(start) {
this.timer = setInterval(() => this.message = dayjs().to(start), 1000);
return dayjs().to(start);
}
generateStyle(innerStyle) {
return Object.keys(innerStyle !== null && innerStyle !== void 0 ? innerStyle : {}).map(k => k + ' { ' + innerStyle[k] + ' }').join('\n');
}
getClass() {
var _a, _b, _c, _d, _e;
return 'display-container pos-' + ((_c = (_b = (_a = this.innerOptions) === null || _a === void 0 ? void 0 : _a.display) === null || _b === void 0 ? void 0 : _b.labelPosition) !== null && _c !== void 0 ? _c : 'c') + (((_e = (_d = this.innerOptions) === null || _d === void 0 ? void 0 : _d.display) === null || _e === void 0 ? void 0 : _e.markdown) ? ' display-md' : '');
}
static get is() { return "discovery-display"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["discovery-display.scss"]
};
}
static get styleUrls() {
return {
"$": ["discovery-display.css"]
};
}
static get properties() {
return {
"result": {
"type": "string",
"mutable": true,
"complexType": {
"original": "DataModel | string",
"resolved": "DataModel | string",
"references": {
"DataModel": {
"location": "import",
"path": "../../model/types",
"id": "src/model/types.ts::DataModel"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "result",
"reflect": false
},
"type": {
"type": "string",
"mutable": false,
"complexType": {
"original": "ChartType",
"resolved": "string",
"references": {
"ChartType": {
"location": "import",
"path": "../../model/types",
"id": "src/model/types.ts::ChartType"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "type",
"reflect": false
},
"options": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Param | string",
"resolved": "Param | string",
"references": {
"Param": {
"location": "import",
"path": "../../model/param",
"id": "src/model/param.ts::Param"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "options",
"reflect": false,
"defaultValue": "new Param()"
},
"width": {
"type": "number",
"mutable": true,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "width",
"reflect": false
},
"height": {
"type": "number",
"mutable": true,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "height",
"reflect": false
},
"debug": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "debug",
"reflect": false,
"defaultValue": "false"
},
"unit": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"attribute": "unit",
"reflect": false,
"defaultValue": "''"
}
};
}
static get states() {
return {
"width": {},
"height": {},
"parsing": {},
"rendering": {},
"message": {},
"innerStyle": {},
"innerOptions": {}
};
}
static get events() {
return [{
"method": "draw",
"name": "draw",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": ""
},
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
}
}];
}
static get methods() {
return {
"resize": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "",
"tags": []
}
},
"export": {
"complexType": {
"signature": "(_type?: \"png\" | \"svg\") => Promise<string>",
"parameters": [{
"name": "_type",
"type": "\"svg\" | \"png\"",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"Param": {
"location": "import",
"path": "../../model/param",
"id": "src/model/param.ts::Param"
},
"DataModel": {
"location": "import",
"path": "../../model/types",
"id": "src/model/types.ts::DataModel"
}
},
"return": "Promise<string>"
},
"docs": {
"text": "",
"tags": []
}
}
};
}
static get elementRef() { return "el"; }
static get watchers() {
return [{
"propName": "result",
"methodName": "updateRes"
}, {
"propName": "options",
"methodName": "optionsUpdate"
}];
}
static get listeners() {
return [{
"name": "discoveryEvent",
"method": "discoveryEventHandler",
"target": "window",
"capture": false,
"passive": false
}];
}
}
//# sourceMappingURL=discovery-display.js.map