@senx/discovery-widgets
Version:
Discovery Widgets Elements
517 lines (516 loc) • 20.2 kB
JavaScript
/*
* Copyright 2022-2025 SenX S.A.S.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { h } from "@stencil/core";
import { DataModel } from "../../model/types";
import { Param } from "../../model/param";
import { Logger } from "../../utils/logger";
import { GTSLib } from "../../utils/gts.lib";
import { Utils } from "../../utils/utils";
import html2canvas from "html2canvas";
import streamSaver from "streamsaver";
export class DiscoveryTabular {
constructor() {
this.options = Object.assign(Object.assign({}, new Param()), { timeMode: 'date' });
this.debug = false;
this.parsing = false;
this.rendering = false;
this.tabularData = [];
this.divider = 1000;
}
updateRes() {
this.tabularData = this.convert(GTSLib.getData(this.result));
}
async resize() {
const dims = Utils.getContentBounds(this.el.parentElement);
this.width = dims.w;
this.height = dims.h;
return Promise.resolve();
}
// noinspection JSUnusedLocalSymbols
async export(_type = 'png') {
return (await html2canvas(this.pngWrapper, {
allowTaint: true,
backgroundColor: this.options.bgColor || Utils.getCSSColor(this.el, '--warp-view-tile-background', '#fff'),
})).toDataURL();
}
// noinspection JSUnusedGlobalSymbols
componentWillLoad() {
var _a, _b, _c;
this.parsing = true;
this.LOG = new Logger(DiscoveryTabular, this.debug);
if (typeof this.options === 'string') {
this.options = JSON.parse(this.options);
}
this.result = GTSLib.getData(this.result);
this.divider = GTSLib.getDivider((_a = this.options.timeUnit) !== null && _a !== void 0 ? _a : 'us');
this.tabularData = 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.options,
});
const dims = Utils.getContentBounds(this.el.parentElement);
this.width = dims.w;
this.height = dims.h;
this.el.addEventListener('mouseout', () => this.dataPointOver.emit({}));
}
static getHeaderParam(data, i, j, key, def) {
return data.params && data.params[i] && data.params[i][key] && data.params[i][key][j]
? data.params[i][key][j]
: data.globalParams && data.globalParams[key] && data.globalParams[key][j]
? data.globalParams[key][j]
: def;
}
handleDataPointOver(event) {
event.stopImmediatePropagation();
this.dataPointOver.emit(event.detail);
}
handleDataPointSelected(event) {
event.stopImmediatePropagation();
this.dataPointSelected.emit(event.detail);
}
convert(data) {
var _a, _b, _c;
let options = Utils.mergeDeep(Object.assign(Object.assign({}, new Param()), { timeMode: 'date' }), (_a = this.options) !== null && _a !== void 0 ? _a : {});
options = Utils.mergeDeep(options !== null && options !== void 0 ? options : {}, data.globalParams);
this.options = Utils.clone(options);
this.params = (_b = data.params) !== null && _b !== void 0 ? _b : [];
let dataGrid;
if (GTSLib.isArray(data.data)) {
const dataList = GTSLib.flatDeep(data.data);
(_c = this.LOG) === null || _c === void 0 ? void 0 : _c.debug(['convert', 'isArray'], dataList, options);
if (data.data.length > 0 && GTSLib.isGts(dataList[0])) {
dataGrid = this.parseData(data, dataList);
}
else {
dataGrid = this.parseCustomData(data, dataList);
}
}
else {
dataGrid = this.parseCustomData(data, [data.data]);
}
this.parsing = false;
return dataGrid;
}
parseCustomData(dataModel, data) {
var _a;
const flatData = [];
data.forEach(d => {
var _a, _b, _c, _d;
if (d !== null && d !== undefined) {
const dataSet = {
name: (_a = d === null || d === void 0 ? void 0 : d.title) !== null && _a !== void 0 ? _a : '',
values: (_b = d === null || d === void 0 ? void 0 : d.rows) !== null && _b !== void 0 ? _b : [],
headers: (_c = d === null || d === void 0 ? void 0 : d.columns) !== null && _c !== void 0 ? _c : [],
isGTS: false,
params: (_d = d === null || d === void 0 ? void 0 : d.params) !== null && _d !== void 0 ? _d : [],
};
flatData.push(dataSet);
}
});
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['parseCustomData', 'flatData'], flatData, dataModel);
return flatData;
}
parseData(dataModel, data) {
var _a, _b;
const flatData = [];
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['parseData'], data);
data.forEach((d, i) => {
var _a, _b;
const dataSet = {
name: '',
values: [],
headers: [],
isGTS: false,
params: this.params,
};
if (GTSLib.isGts(d)) {
(_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['parseData', 'isGts'], d);
dataSet.name = ((dataModel.params || [])[i] || { key: undefined }).key || GTSLib.serializeGtsMetadata(d);
dataSet.values = d.v; // .map(v => [this.formatDate(v[0])].concat(v.slice(1, v.length)));
dataSet.isGTS = true;
dataSet.c = d.c;
dataSet.l = d.l;
dataSet.a = d.a;
}
else {
(_b = this.LOG) === null || _b === void 0 ? void 0 : _b.debug(['parseData', 'is not a Gts'], d);
dataSet.values = GTSLib.isArray(d) ? d : [d];
}
dataSet.headers = [DiscoveryTabular.getHeaderParam(dataModel, i, 0, 'headers', 'Date')];
if (d.v && d.v.length > 0 && d.v[0].length > 2) {
dataSet.headers.push(DiscoveryTabular.getHeaderParam(dataModel, i, 1, 'headers', 'Latitude'));
}
if (d.v && d.v.length > 0 && d.v[0].length > 3) {
dataSet.headers.push(DiscoveryTabular.getHeaderParam(dataModel, i, 2, 'headers', 'Longitude'));
}
if (d.v && d.v.length > 0 && d.v[0].length > 4) {
dataSet.headers.push(DiscoveryTabular.getHeaderParam(dataModel, i, 3, 'headers', 'Elevation'));
}
if (d.v && d.v.length > 0) {
dataSet.headers.push(DiscoveryTabular.getHeaderParam(dataModel, i, d.v[0].length - 1, 'headers', 'Value'));
}
if (dataSet.values.length > 0) {
flatData.push(dataSet);
}
});
(_b = this.LOG) === null || _b === void 0 ? void 0 : _b.debug(['parseData', 'flatData'], flatData, this.options);
return flatData;
}
addCSVHeader(headers, k) {
if (!headers.includes(k)) {
headers.push(k);
}
}
addPageable(elem) {
this.pageables.push(elem);
}
async csvExport() {
var _a;
const headers = [];
const csv = [];
const tabularData = [];
for (const p of this.pageables) {
tabularData.push(await p.getData());
}
tabularData.forEach(t => {
var _a;
((_a = t.headers) !== null && _a !== void 0 ? _a : []).forEach((h) => this.addCSVHeader(headers, h));
for (const v of t.data) {
csv.push(v);
}
});
const csvTxt = headers.join(';') + '\n' +
csv.map(line => headers.map(h => { var _a; return (_a = line[h]) !== null && _a !== void 0 ? _a : ''; }).join(';')).join('\n');
const uInt8 = new TextEncoder().encode(csvTxt);
const fileStream = streamSaver.createWriteStream(((_a = this.options.title) !== null && _a !== void 0 ? _a : 'export') + '.csv', {
size: uInt8.byteLength, // (optional filesize) Will show progress
writableStrategy: undefined, // (optional)
readableStrategy: undefined, // (optional)
});
const writer = fileStream.getWriter();
await writer.write(uInt8);
await writer.close();
}
render() {
this.draw.emit();
this.pageables = [];
return [
this.options.showControls ? h("div", { class: "tabular-action-button" }, h("button", { class: "tabular-export-csv", title: "CSV Export", onClick: () => void this.csvExport() }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16" }, h("path", { d: "M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5" }), h("path", { d: "M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708z" }))))
: '',
h("div", { key: '30335a2af8c4ae7b6da21a94d34882dee635fa7e', class: "tabular-wrapper", ref: (el) => this.pngWrapper = el }, h("div", { key: '2bd8f7ae1bf35c841452599552cd55cd8e29b3bf', class: "tabular-wrapper-inner" }, this.parsing ? h("discovery-spinner", null, "Parsing data...") : '', this.rendering ? h("discovery-spinner", null, "Rendering data...") : '', this.tabularData.map(d => h("discovery-pageable", { data: d, onDataPointOver: event => this.handleDataPointOver(event), onDataPointSelected: event => this.handleDataPointSelected(event), divider: this.divider, options: this.options, ref: elem => this.addPageable(elem), debug: this.debug })))),
];
}
static get is() { return "discovery-tabular"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["discovery-tabular.scss"]
};
}
static get styleUrls() {
return {
"$": ["discovery-tabular.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": true,
"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(), timeMode: 'date' }"
},
"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
}
};
}
static get states() {
return {
"parsing": {},
"rendering": {},
"tabularData": {}
};
}
static get events() {
return [{
"method": "draw",
"name": "draw",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": ""
},
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
}
}, {
"method": "dataPointOver",
"name": "dataPointOver",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": ""
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "dataPointSelected",
"name": "dataPointSelected",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": ""
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "discoveryEvent",
"name": "discoveryEvent",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": ""
},
"complexType": {
"original": "DiscoveryEvent",
"resolved": "DiscoveryEvent",
"references": {
"DiscoveryEvent": {
"location": "import",
"path": "../../model/types",
"id": "src/model/types.ts::DiscoveryEvent"
}
}
}
}];
}
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"
}
},
"return": "Promise<string>"
},
"docs": {
"text": "",
"tags": []
}
}
};
}
static get elementRef() { return "el"; }
static get watchers() {
return [{
"propName": "result",
"methodName": "updateRes"
}];
}
}
//# sourceMappingURL=discovery-tabular.js.map