@senx/warpview
Version:
WarpView Elements
565 lines • 108 kB
JavaScript
/*
* Copyright 2021 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 { Component, ElementRef, EventEmitter, Input, NgZone, Output, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core';
import { GTSLib } from '../../utils/gts.lib';
import { ChartBounds } from '../../model/chartBounds';
import { ColorLib } from '../../utils/color-lib';
import { WarpViewComponent } from '../warp-view-component';
import { SizeService } from '../../services/resize.service';
import { Logger } from '../../utils/logger';
import { Subject } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
import { ChartLib } from '../../utils/chart-lib';
import * as i0 from "@angular/core";
import * as i1 from "../../services/resize.service";
import * as i2 from "../warp-view-spinner/warp-view-spinner.component";
import * as i3 from "../../plotly/plotly.component";
import * as i4 from "@angular/common";
export class WarpViewChartComponent extends WarpViewComponent {
constructor(el, renderer, sizeService, ngZone) {
super(el, renderer, sizeService, ngZone);
this.el = el;
this.renderer = renderer;
this.sizeService = sizeService;
this.ngZone = ngZone;
this.standalone = true;
this.boundsDidChange = new EventEmitter();
this.pointHover = new EventEmitter();
this.warpViewChartResize = new EventEmitter();
// tslint:disable-next-line:variable-name
this._type = 'line';
this.visibility = [];
this.maxTick = 0;
this.minTick = 0;
this.visibleGtsId = [];
this.gtsId = [];
this.dataHashset = {};
this.chartBounds = new ChartBounds();
this.visibilityStatus = 'unknown';
this.afterBoundsUpdate = false;
this.maxPlottable = 10000;
this.parsing = false;
this.unhighliteCurve = new Subject();
this.highliteCurve = new Subject();
this.layout = {
legend: {
orientation: 'h',
y: -0.3
},
showlegend: false,
autosize: true,
hovermode: 'x',
hoverdistance: 20,
xaxis: {
font: {}
},
yaxis: {
exponentformat: 'none',
fixedrange: true,
automargin: true,
showline: true,
font: {}
},
margin: {
t: 0,
b: 40,
r: 10,
l: 50
},
};
this.LOG = new Logger(WarpViewChartComponent, this._debug);
}
set hiddenData(hiddenData) {
const previousVisibility = JSON.stringify(this.visibility);
this.LOG.debug(['hiddenData', 'previousVisibility'], previousVisibility);
this._hiddenData = hiddenData;
this.visibility = [];
this.visibleGtsId.forEach(id => this.visibility.push(hiddenData.indexOf(id) < 0 && (id !== -1)));
this.LOG.debug(['hiddenData', 'hiddendygraphfullv'], this.visibility);
const newVisibility = JSON.stringify(this.visibility);
this.LOG.debug(['hiddenData', 'json'], previousVisibility, newVisibility, this._hiddenData);
if (previousVisibility !== newVisibility) {
const visible = [];
const hidden = [];
(this.gtsId || []).forEach((id, i) => {
if (this._hiddenData.indexOf(id) > -1) {
hidden.push(i);
}
else {
visible.push(i);
}
});
if (visible.length > 0) {
this.graph.restyleChart({ visible: true }, visible);
}
if (hidden.length > 0) {
this.graph.restyleChart({ visible: false }, hidden);
}
this.LOG.debug(['hiddendygraphtrig', 'destroy'], 'redraw by visibility change', visible, hidden);
}
}
set type(type) {
this._type = type;
this.drawChart();
}
update(options, refresh) {
this.drawChart(refresh);
}
ngOnInit() {
this._options = this._options || this.defOptions;
}
async getTimeClip() {
return new Promise(resolve => {
this.LOG.debug(['getTimeClip'], this.chartBounds);
resolve(this.chartBounds);
});
}
resize(layout) {
if (!!layout) {
this.LOG.debug(['resize'], layout);
this.height = layout.height;
this.layout.height = this.height;
if (this._options.showRangeSelector) {
this.layout.xaxis.rangeslider = {
bgcolor: 'transparent',
thickness: 40 / this.height
};
}
}
}
drawChart(reparseNewData = false) {
this.LOG.debug(['drawChart', 'this.layout', 'this.options'], this.layout, this._options, (this._options.bounds || {}).minDate);
if (!this.initChart(this.el, false, false, reparseNewData)) {
this.LOG.debug(['drawChart', 'initChart', 'empty'], this._options);
return;
}
this.plotlyConfig.scrollZoom = true;
this.layout.yaxis.gridcolor = this.getGridColor(this.el.nativeElement);
this.layout.xaxis.gridcolor = this.getGridColor(this.el.nativeElement);
this.layout.yaxis.zerolinecolor = this.getGridColor(this.el.nativeElement);
this.layout.xaxis.zerolinecolor = this.getGridColor(this.el.nativeElement);
this.layout.margin.t = this.standalone ? 20 : 10;
if (!this._responsive) {
this.layout.width = this.width;
this.layout.height = this.height;
}
this.LOG.debug(['drawChart', 'this.options'], this.layout, this._options);
this.LOG.debug(['drawChart', 'this.layout'], this.layout);
this.LOG.debug(['drawChart', 'this.plotlyConfig'], this.plotlyConfig);
if (!!this._options.showRangeSelector) {
this.resize({ height: this.height, width: 0 });
}
else {
this.layout.margin.b = 30;
}
this.layout.showlegend = !!this._options.showlegend;
this.layout = { ...this.layout };
this.highliteCurve.pipe(throttleTime(200)).subscribe(value => {
this.graph.restyleChart({ opacity: 0.4 }, value.off);
this.graph.restyleChart({ opacity: 1 }, value.on);
});
this.unhighliteCurve.pipe(throttleTime(200)).subscribe(value => {
this.graph.restyleChart({ opacity: 1 }, value);
});
this.loading = false;
}
emitNewBounds(min, max, marginLeft) {
this.LOG.debug(['emitNewBounds'], min, max);
this.boundsDidChange.emit({ bounds: { min, max, marginLeft }, source: 'chart' });
}
initChart(el, resize = true, customData = false, firstDraw = false) {
const res = super.initChart(el);
const x = { tick0: undefined, range: [] };
this.LOG.debug(['initChart', 'updateBounds'], this.chartBounds, this._options.bounds);
const min = (this._options.bounds || {}).minDate || this.chartBounds.tsmin || this.minTick;
const max = (this._options.bounds || {}).maxDate || this.chartBounds.tsmax || this.maxTick;
this.LOG.debug(['initChart', 'updateBounds'], [min, max]);
const pad = ChartLib.fraction2r(this.minTick, this.maxTick, 0.067);
if (this._options.timeMode && this._options.timeMode === 'timestamp') {
x.tick0 = min - pad;
x.range = [x.tick0, max + pad];
}
else {
x.tick0 = GTSLib.toISOString(min - pad, this.divider, this._options.timeZone);
x.range = [x.tick0, GTSLib.toISOString(max + pad, this.divider, this._options.timeZone)];
}
this.layout.xaxis = x;
if (!!res) {
this.resize({ height: this.height, width: 0 });
}
return res;
}
convert(data, firstDraw = false) {
this.parsing = !this._options.isRefresh;
this.chartBounds.tsmin = undefined;
this.chartBounds.tsmax = undefined;
const dataset = [];
this.LOG.debug(['convert'], this._options.timeMode);
this.LOG.debug(['convert', 'this._hiddenData'], this._hiddenData);
this.LOG.debug(['convert', 'this._options.timezone'], this._options.timeZone);
if (GTSLib.isArray(data.data)) {
let gtsList = GTSLib.flatDeep(GTSLib.flattenGtsIdArray(data.data, 0).res);
this.maxTick = Number.MIN_VALUE;
this.minTick = Number.MAX_VALUE;
this.visibleGtsId = [];
this.gtsId = [];
const nonPlottable = gtsList.filter(g => (g.v && !GTSLib.isGtsToPlot(g)));
gtsList = gtsList.filter(g => g.v && GTSLib.isGtsToPlot(g));
// initialize visibility status
if (this.visibilityStatus === 'unknown') {
this.visibilityStatus = gtsList.length > 0 ? 'plottableShown' : 'nothingPlottable';
}
let timestampMode = firstDraw;
if (firstDraw) {
const tsLimit = 100 * GTSLib.getDivider(this._options.timeUnit);
gtsList.forEach((gts) => {
const ticks = gts.v.map(t => t[0]);
const size = gts.v.length;
timestampMode = timestampMode && (ticks[0] > -tsLimit && ticks[0] < tsLimit);
timestampMode = timestampMode && (ticks[size - 1] > -tsLimit && ticks[size - 1] < tsLimit);
});
}
if (timestampMode || this._options.timeMode === 'timestamp') {
this.layout.xaxis.type = 'linear';
}
else {
this.layout.xaxis.type = 'date';
}
const gtsCount = gtsList.length;
for (let i = 0; i < gtsCount; i++) {
const gts = gtsList[i];
if (gts.v && GTSLib.isGtsToPlot(gts)) {
// Timsort.sort(gts.v, (a, b) => a[0] - b[0]);
const size = gts.v.length;
const label = GTSLib.serializeGtsMetadata(gts);
const c = ColorLib.getColor(gts.id, this._options.scheme);
const color = ((data.params || [])[i] || { datasetColor: c }).datasetColor || c;
const type = ((data.params || [])[i] || { type: this._type }).type || this._type;
const series = {
type: type === 'spline' ? 'scatter' : 'scattergl',
mode: type === 'scatter' || size <= 1
? 'markers'
: size > this.maxPlottable ? 'lines' : 'lines+markers',
name: label,
text: label,
x: [],
y: [],
line: { color },
hoverinfo: 'none',
connectgaps: false,
visible: !(this._hiddenData.filter(h => h === gts.id).length > 0),
};
if (size < this.maxPlottable) {
series.marker = {
size: 3,
color: new Array(size).fill(color),
line: { color, width: 3 },
opacity: new Array(size).fill(this._type === 'scatter' || size <= 1 || this._options.showDots ? 1 : 0)
};
}
switch (type) {
case 'spline':
series.line.shape = 'spline';
break;
case 'area':
series.fill = 'tozeroy';
series.fillcolor = ColorLib.transparentize(color, 0.3);
break;
case 'step':
series.line.shape = 'hvh';
break;
case 'step-before':
series.line.shape = 'vh';
break;
case 'step-after':
series.line.shape = 'hv';
break;
}
this.visibleGtsId.push(gts.id);
this.gtsId.push(gts.id);
// this.LOG.debug(['convert'], 'forEach value');
const ticks = gts.v.map(t => t[0]);
const values = gts.v.map(t => t[t.length - 1]);
if (size > 0) {
for (let v = 1; v < size; v++) {
const ts = ticks[v];
this.minTick = ts <= this.minTick ? ts : this.minTick;
this.maxTick = ts >= this.maxTick ? ts : this.maxTick;
}
}
if (timestampMode || this._options.timeMode === 'timestamp') {
series.x = ticks;
}
else {
series.x = ticks.map(t => GTSLib.toISOString(t, this.divider, this._options.timeZone));
}
series.y = values;
dataset.push(series);
}
}
if (nonPlottable.length > 0 && gtsList.length === 0) {
nonPlottable.forEach(g => {
g.v.forEach(value => {
const ts = value[0];
this.minTick = ts <= this.minTick ? ts : this.minTick;
this.maxTick = ts >= this.maxTick ? ts : this.maxTick;
});
});
// if there is not any plottable data, we must add a fake one with id -1. This one will always be hidden.
if (0 === gtsList.length) {
if (!this.dataHashset[this.minTick]) {
this.dataHashset[this.minTick] = [0];
}
if (!this.dataHashset[this.maxTick]) {
this.dataHashset[this.maxTick] = [0];
}
this.visibility.push(false);
this.visibleGtsId.push(-1);
}
}
}
this.LOG.debug(['convert'], 'end', dataset, this.minTick, this.maxTick, GTSLib.toISOString(this.minTick, this.divider, this._options.timeZone), GTSLib.toISOString(this.maxTick, this.divider, this._options.timeZone));
this.noData = dataset.length === 0;
this.parsing = false;
return dataset;
}
afterPlot(plotlyInstance) {
super.afterPlot(plotlyInstance);
this.marginLeft = parseInt(this.graph.plotEl.nativeElement.querySelector('g.bglayer > rect').getAttribute('x'), 10);
this.LOG.debug(['afterPlot', 'marginLeft'], this.marginLeft);
if (this.chartBounds.tsmin !== this.minTick || this.chartBounds.tsmax !== this.maxTick) {
this.chartBounds.tsmin = this.minTick;
this.chartBounds.tsmax = this.maxTick;
this.chartBounds.marginLeft = this.marginLeft;
this.chartDraw.emit(this.chartBounds);
if (this.afterBoundsUpdate || this.standalone) {
this.LOG.debug(['afterPlot', 'updateBounds'], this.minTick, this.maxTick, this.afterBoundsUpdate);
this.emitNewBounds(this.minTick, this.maxTick, this.marginLeft);
this.loading = false;
this.afterBoundsUpdate = false;
}
}
else {
this.loading = false;
}
}
relayout(data) {
let change = false;
if (data['xaxis.range'] && data['xaxis.range'].length === 2) {
if (this.chartBounds.msmin !== data['xaxis.range'][0] || this.chartBounds.msmax !== data['xaxis.range'][1]) {
this.LOG.debug(['relayout', 'updateBounds', 'xaxis.range'], data['xaxis.range']);
change = true;
this.chartBounds.msmin = data['xaxis.range'][0];
this.chartBounds.msmax = data['xaxis.range'][1];
this.chartBounds.tsmin = GTSLib.toTimestamp(this.chartBounds.msmin, this.divider, this._options.timeZone);
this.chartBounds.tsmax = GTSLib.toTimestamp(this.chartBounds.msmax, this.divider, this._options.timeZone);
}
}
else if (data['xaxis.range[0]'] && data['xaxis.range[1]']) {
if (this.chartBounds.msmin !== data['xaxis.range[0]'] || this.chartBounds.msmax !== data['xaxis.range[1]']) {
this.LOG.debug(['relayout', 'updateBounds', 'xaxis.range[x]'], data['xaxis.range[0]']);
change = true;
this.chartBounds.msmin = data['xaxis.range[0]'];
this.chartBounds.msmax = data['xaxis.range[1]'];
this.chartBounds.tsmin = GTSLib.toTimestamp(this.chartBounds.msmin, this.divider, this._options.timeZone);
this.chartBounds.tsmax = GTSLib.toTimestamp(this.chartBounds.msmax, this.divider, this._options.timeZone);
}
}
else if (data['xaxis.autorange']) {
if (this.chartBounds.tsmin !== this.minTick || this.chartBounds.tsmax !== this.maxTick) {
this.LOG.debug(['relayout', 'updateBounds', 'autorange'], data, this.minTick, this.maxTick);
change = true;
this.chartBounds.tsmin = this.minTick;
this.chartBounds.tsmax = this.maxTick;
}
}
if (change) {
this.LOG.debug(['relayout', 'updateBounds'], this.chartBounds);
this.LOG.debug(['relayout', 'updateBounds'], GTSLib.toISOString(this.chartBounds.tsmin, this.divider, this._options.timeZone));
if (this._options.timeMode && this._options.timeMode === 'timestamp') {
this.emitNewBounds(this.chartBounds.msmin, this.chartBounds.msmax, this.marginLeft);
}
else {
this.emitNewBounds(this.chartBounds.tsmin, this.chartBounds.tsmax, this.marginLeft);
}
}
this.loading = false;
this.afterBoundsUpdate = true;
this.chartDraw.emit();
}
sliderChange($event) {
this.LOG.debug(['sliderChange'], $event);
}
updateBounds(min, max) {
this.LOG.debug(['updateBounds'], min, max, this._options);
this._options.bounds.minDate = min;
this._options.bounds.maxDate = max;
this.layout.xaxis.autorange = false;
this.LOG.debug(['updateBounds'], GTSLib.toISOString(min, this.divider, this._options.timeZone), GTSLib.toISOString(max, this.divider, this._options.timeZone));
this.minTick = min;
this.maxTick = max;
if (this._options.timeMode && this._options.timeMode === 'timestamp') {
this.layout.xaxis.tick0 = min;
this.layout.xaxis.range = [min, max];
}
else {
this.layout.xaxis.tick0 = GTSLib.toISOString(min, this.divider, this._options.timeZone);
this.layout.xaxis.range = [
GTSLib.toISOString(min, this.divider, this._options.timeZone),
GTSLib.toISOString(max, this.divider, this._options.timeZone)
];
}
this.layout = { ...this.layout };
this.LOG.debug(['updateBounds'], { ...this.layout.xaxis.range });
this.afterBoundsUpdate = true;
}
setRealBounds(chartBounds) {
this.minTick = chartBounds.tsmin;
this.maxTick = chartBounds.tsmax;
this._options.bounds = this._options.bounds || {};
const x = {
tick0: undefined,
range: [],
};
if (this._options.showRangeSelector) {
x.rangeslider = {
bgcolor: 'transparent',
thickness: 40 / this.height
};
}
if (this._options.timeMode && this._options.timeMode === 'timestamp') {
x.tick0 = this.minTick / this.divider;
x.range = [this.minTick, this.maxTick];
}
else {
x.tick0 = GTSLib.toISOString(this.minTick, this.divider, this._options.timeZone);
x.range = [
GTSLib.toISOString(this.minTick, this.divider, this._options.timeZone),
GTSLib.toISOString(this.maxTick, this.divider, this._options.timeZone)
];
}
this.layout.xaxis = x;
this.layout = { ...this.layout };
}
hover(data) {
const xaxis = data.points[0].xaxis;
const yaxis = data.points[0].yaxis;
let toHighlight;
const curves = [];
let delta = Number.MAX_VALUE;
let point;
const annotations = [];
data.points.forEach(p => {
curves.push(p.curveNumber);
/* annotations.push({
x: p.x,
y: p.y,
arrowhead: 6,
arrowsize: 1,
ax: 3,
ay: 3,
arrowcolor: p.data.line.color
});*/
const dist = Math.abs(data.yvals[0] - p.y);
if (delta > dist) {
delta = dist;
toHighlight = p.curveNumber;
point = p;
data.meta = {
x: p.x,
y: p.y.toPrecision(3),
w: xaxis.l2p(p.x),
h: yaxis.l2p(p.y),
name: p.data.text
};
}
});
if (!!this.hoverTimeout) {
clearTimeout(this.hoverTimeout);
}
/*this.graph.relayoutPlot('annotations', 'remove');
this.graph.relayoutPlot('annotations', annotations);*/
super.hover(data, toHighlight);
}
unhover(data) {
super.unhover(data);
if (!!this.hoverTimeout) {
clearTimeout(this.hoverTimeout);
}
}
handleMouseMove(evt) {
evt.preventDefault();
if (this.standalone && this.line && !this.noData) {
this.line.nativeElement.style.left = Math.max(evt.offsetX, 50) + 'px';
}
}
handleMouseEnter(evt) {
evt.preventDefault();
this.marginLeft = this.marginLeft || this.el.nativeElement.getBoundingClientRect().left;
if (this.standalone && this.line && !this.noData) {
const h = this.graph.getElement('.draglayer')[0].getBoundingClientRect().height - 60;
this.renderer.setStyle(this.line.nativeElement, 'height', h + 'px');
this.renderer.setStyle(this.line.nativeElement, 'display', 'block');
this.renderer.setStyle(this.line.nativeElement, 'bottom', (40 / this.height) + 'px');
}
}
queryShadow([firstShadowSelector, ...restOfTheShadowSelectors], itemSelector) {
const reduceFunction = (currShadow, nextShadowSelector) => currShadow.shadowRoot.querySelector(nextShadowSelector);
const firstShadow = document.querySelector(firstShadowSelector);
const lastShadow = restOfTheShadowSelectors.reduce(reduceFunction, firstShadow);
return lastShadow && lastShadow.querySelector(itemSelector);
}
handleMouseOut(evt) {
// evt.preventDefault();
if (this.standalone && this.line && !this.noData) {
this.renderer.setStyle(this.line.nativeElement, 'left', '-100px');
this.renderer.setStyle(this.line.nativeElement, 'display', 'none');
}
if (!!this.hoverTimeout) {
clearTimeout(this.hoverTimeout);
}
// setTimeout(() => this.graph.relayoutPlot('annotations', 'remove'), 1000);
}
}
WarpViewChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.SizeService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
WarpViewChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: WarpViewChartComponent, selector: "warpview-chart", inputs: { hiddenData: "hiddenData", type: "type", standalone: "standalone" }, outputs: { boundsDidChange: "boundsDidChange", pointHover: "pointHover", warpViewChartResize: "warpViewChartResize" }, viewQueries: [{ propertyName: "line", first: true, predicate: ["line"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<!--\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<div id=\"chartContainer\" #chartContainer (mouseleave)=\"hideTooltip()\">\n <warpview-spinner *ngIf=\"loading\" message=\"Parsing data\"></warpview-spinner>\n <p class=\"noData\" *ngIf=\"noData\">No data to display</p>\n <p class=\"noData\" *ngIf=\"parsing\">Parsing data</p>\n <div *ngIf=\"!loading && !noData\" (mouseleave)=\"handleMouseOut($event)\"\n (mousemove)=\"handleMouseMove($event)\"\n (mouseenter)=\"handleMouseEnter($event)\">\n <div class=\"bar\" #line [ngClass]=\"{'full': !_options.showRangeSelector }\"></div>\n <warpview-plotly #graph\n [data]=\"plotlyData\" [layout]=\"layout\" [config]=\"plotlyConfig\"\n (afterPlot)=\"afterPlot($event)\"\n (relayout)=\"relayout($event)\" (hover)=\"hover($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n (sliderChange)=\"sliderChange($event)\" (unhover)=\"unhover($event)\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n <div #toolTip class=\"wv-tooltip\"></div>\n</div>\n", styles: [":root{--warp-view-chart-width: 100%;--warp-view-chart-height: 100%;--warp-view-datagrid-cell-padding: 5px;--warp-view-map-margin: 0;--warp-view-switch-height: 30px;--warp-view-switch-width: 100px;--warp-view-switch-radius: 18px;--warp-view-plot-chart-height: 100%;--warp-view-slider-pointer-size: 65px;--warp-view-resize-handle-height: 10px;--warp-view-tile-width: 100%;--warp-view-tile-height: 100%;--warp-view-font-color: #000000;--warp-view-bar-color: #dc3545;--warp-view-datagrid-odd-bg-color: #ffffff;--warp-view-datagrid-odd-color: #404040;--warp-view-datagrid-even-bg-color: #c0c0c0;--warp-view-datagrid-even-color: #000000;--warp-view-pagination-border-color: #c0c0c0;--warp-view-pagination-bg-color: #ffffff;--warp-view-pagination-active-bg-color: #4CAF50;--warp-view-pagination-active-color: #ffffff;--warp-view-pagination-active-border-color: #4CAF50;--warp-view-pagination-hover-bg-color: #c0c0c0;--warp-view-pagination-hover-color: #000000;--warp-view-pagination-hover-border-color: #c0c0c0;--warp-view-pagination-disabled-color: #c0c0c0;--warp-view-switch-inset-color: #c0c0c0;--warp-view-switch-inset-checked-color: #00cd00;--warp-view-switch-handle-color: radial-gradient(#ffffff 15%, #c0c0c0 100%);--warp-view-switch-handle-checked-color: radial-gradient(#ffffff 15%, #00cd00 100%);--warp-view-resize-handle-color: #c0c0c0;--warp-view-chart-legend-bg: #ffffff;--warp-view-chart-legend-color: #404040;--gts-classname-font-color: #004eff;--gts-labelname-font-color: #19A979;--gts-attrname-font-color: #ED4A7B;--gts-separator-font-color: #a0a0a0;--gts-labelvalue-font-color: #000000;--gts-attrvalue-font-color: #000000;--gts-stack-font-color: #000000;--gts-tree-expanded-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7klEQVQ4T82TMW7CQBBF/0g+QOpINEkVCmpaLoBm5COk5QYoaeAY3MDSei2LGu4QKakiBA1tCpTK8kS2sLVe2xSh8XSrnf9m/s4s4c6gO/UYGEBEXlT1bK396bFGIjIJguA7iqJLkVNbYOZXItoQ0QHAzBhz9CCFeAVgCeAjy7Jpmqa/NUBEEgDzktqGuOKKO47j+KsGhGH4lOf5HsDIg5ycyqVYVd+steuGheLAzM9EtPMgW1VdVGWJ6N0YU1gpozVGH+K+gy/uBHR1crXUqNzbQXXhduJ69sd7cxOZ+UFVH5Mk+exb+YGt8n9+5h8up1sReYC0WAAAAABJRU5ErkJggg==);--gts-tree-collapsed-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0UlEQVQ4T6WTUW7CQAxEPQdozxYb9Qb94Aj9gQSoVCp6lMr21doDZFCQiFCU3YDY//d2PeOFPHnwJC+zAlVdA/jp+/6YmZ+1S0qCPxF5HUAAO3fvSpKS4ENEvm6gfUS0c5JiBma2Ibm/QiQPmbmdSqohquoA7GqSxRaapmkBjBkAeHP336t0UWBmHcnb+VcR4XcJpjDJLjPHkS4tleqZubmNiDHU6gumDQDYuvvh7hpV9V9EXgaA5Ka2jbMjmNk7yZOIfEfE8eFVfuSDLda4JDsD3FNdEckTC0YAAAAASUVORK5CYII=);--warp-view-popup-bg-color: #ffffff;--warp-view-popup-border-color: rgba(0, 0, 0, .2);--warp-view-popup-header-bg-color: #c0c0c0;--warp-view-popup-title-color: #404040;--warp-view-popup-close-color: #404040;--warp-view-popup-body-bg-color: #ffffff;--warp-view-popup-body-color: #000000;--warp-view-annotationtooltip-value-font-color: #004eff;--warp-view-annotationtooltip-font-color: #404040;--warp-view-spinner-color: #ff9900;--warp-view-tooltip-bg: #ffffff;--warp-view-tooltip-color: #000000;--warp-slider-connect-color: #ff9900;--warp-slider-handle-bg-color: #ffffff;--warp-slider-handle-color: #004eff;--warp-slider-handle-shadow: inset 0 0 1px #ffffff, inset 0 1px 7px #c0c0c0, 0 3px 6px -3px #a0a0a0}.noData{width:100%;text-align:center;color:var(--warp-view-chart-legend-color);position:relative}.js-plotly-plot .plotly .cursor-ew-resize{cursor:default!important}/*!\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 */.gts-classname{color:var(--gts-classname-font-color)}.gts-labelname{color:var(--gts-labelname-font-color)}.gts-attrname{color:var(--gts-attrname-font-color)}.gts-separator{color:var(--gts-separator-font-color)}.gts-labelvalue{color:var(--gts-labelvalue-font-color);font-style:italic}.gts-attrvalue{color:var(--gts-attrvalue-font-color);font-style:italic}.wv-tooltip{background-color:var(--warp-view-tooltip-bg)!important;color:var(--warp-view-tooltip-color)!important;text-align:left;position:absolute;display:none;padding:10px;border:1px solid grey;border-radius:5px;box-shadow:none;pointer-events:none;font-size:10px;min-width:100px;width:auto;max-width:50%;z-index:999;height:auto!important;left:-1000px}.wv-tooltip .chip{border-radius:50%;background-color:#bbb;display:inline-block;width:5px;height:5px;border:2px solid #454545;margin-top:auto;margin-bottom:auto;vertical-align:middle;cursor:pointer}:host{display:block;height:100%}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host .bar{width:1px;left:-100px;position:absolute;background-color:transparent;-webkit-backface-visibility:hidden;backface-visibility:hidden;top:30px;bottom:55px;overflow:hidden;display:none;z-index:0;pointer-events:none;border-left:dashed 1px var(--warp-view-bar-color)}:host div.chart{width:var(--warp-view-chart-width);height:var(--warp-view-chart-height)}:host .executionErrorText{color:red;padding:10px;border-color:red;border-width:2px;border-radius:3px;border-style:solid;background:antiquewhite;position:absolute;top:-30px}\n"], components: [{ type: i2.WarpViewSpinnerComponent, selector: "warpview-spinner", inputs: ["message"] }, { type: i3.PlotlyComponent, selector: "warpview-plotly", inputs: ["data", "layout", "config", "debug", "frames", "style", "divId", "revision", "className", "useResizeHandler", "updateOnLayoutChange", "updateOnDataChange", "updateOnlyWithRevision"], outputs: ["initialized", "update", "purge", "error", "afterExport", "afterPlot", "animated", "animatingFrame", "animationInterrupted", "autoSize", "beforeExport", "buttonClicked", "click", "plotly_click", "clickAnnotation", "deselect", "doubleClick", "framework", "hover", "legendClick", "legendDoubleClick", "relayout", "restyle", "redraw", "selected", "selecting", "sliderChange", "sliderEnd", "sliderStart", "transitioning", "transitionInterrupted", "unhover", "relayouting"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewChartComponent, decorators: [{
type: Component,
args: [{ selector: 'warpview-chart', encapsulation: ViewEncapsulation.ShadowDom, template: "<!--\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<div id=\"chartContainer\" #chartContainer (mouseleave)=\"hideTooltip()\">\n <warpview-spinner *ngIf=\"loading\" message=\"Parsing data\"></warpview-spinner>\n <p class=\"noData\" *ngIf=\"noData\">No data to display</p>\n <p class=\"noData\" *ngIf=\"parsing\">Parsing data</p>\n <div *ngIf=\"!loading && !noData\" (mouseleave)=\"handleMouseOut($event)\"\n (mousemove)=\"handleMouseMove($event)\"\n (mouseenter)=\"handleMouseEnter($event)\">\n <div class=\"bar\" #line [ngClass]=\"{'full': !_options.showRangeSelector }\"></div>\n <warpview-plotly #graph\n [data]=\"plotlyData\" [layout]=\"layout\" [config]=\"plotlyConfig\"\n (afterPlot)=\"afterPlot($event)\"\n (relayout)=\"relayout($event)\" (hover)=\"hover($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n (sliderChange)=\"sliderChange($event)\" (unhover)=\"unhover($event)\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n <div #toolTip class=\"wv-tooltip\"></div>\n</div>\n", styles: [":root{--warp-view-chart-width: 100%;--warp-view-chart-height: 100%;--warp-view-datagrid-cell-padding: 5px;--warp-view-map-margin: 0;--warp-view-switch-height: 30px;--warp-view-switch-width: 100px;--warp-view-switch-radius: 18px;--warp-view-plot-chart-height: 100%;--warp-view-slider-pointer-size: 65px;--warp-view-resize-handle-height: 10px;--warp-view-tile-width: 100%;--warp-view-tile-height: 100%;--warp-view-font-color: #000000;--warp-view-bar-color: #dc3545;--warp-view-datagrid-odd-bg-color: #ffffff;--warp-view-datagrid-odd-color: #404040;--warp-view-datagrid-even-bg-color: #c0c0c0;--warp-view-datagrid-even-color: #000000;--warp-view-pagination-border-color: #c0c0c0;--warp-view-pagination-bg-color: #ffffff;--warp-view-pagination-active-bg-color: #4CAF50;--warp-view-pagination-active-color: #ffffff;--warp-view-pagination-active-border-color: #4CAF50;--warp-view-pagination-hover-bg-color: #c0c0c0;--warp-view-pagination-hover-color: #000000;--warp-view-pagination-hover-border-color: #c0c0c0;--warp-view-pagination-disabled-color: #c0c0c0;--warp-view-switch-inset-color: #c0c0c0;--warp-view-switch-inset-checked-color: #00cd00;--warp-view-switch-handle-color: radial-gradient(#ffffff 15%, #c0c0c0 100%);--warp-view-switch-handle-checked-color: radial-gradient(#ffffff 15%, #00cd00 100%);--warp-view-resize-handle-color: #c0c0c0;--warp-view-chart-legend-bg: #ffffff;--warp-view-chart-legend-color: #404040;--gts-classname-font-color: #004eff;--gts-labelname-font-color: #19A979;--gts-attrname-font-color: #ED4A7B;--gts-separator-font-color: #a0a0a0;--gts-labelvalue-font-color: #000000;--gts-attrvalue-font-color: #000000;--gts-stack-font-color: #000000;--gts-tree-expanded-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7klEQVQ4T82TMW7CQBBF/0g+QOpINEkVCmpaLoBm5COk5QYoaeAY3MDSei2LGu4QKakiBA1tCpTK8kS2sLVe2xSh8XSrnf9m/s4s4c6gO/UYGEBEXlT1bK396bFGIjIJguA7iqJLkVNbYOZXItoQ0QHAzBhz9CCFeAVgCeAjy7Jpmqa/NUBEEgDzktqGuOKKO47j+KsGhGH4lOf5HsDIg5ycyqVYVd+steuGheLAzM9EtPMgW1VdVGWJ6N0YU1gpozVGH+K+gy/uBHR1crXUqNzbQXXhduJ69sd7cxOZ+UFVH5Mk+exb+YGt8n9+5h8up1sReYC0WAAAAABJRU5ErkJggg==);--gts-tree-collapsed-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0UlEQVQ4T6WTUW7CQAxEPQdozxYb9Qb94Aj9gQSoVCp6lMr21doDZFCQiFCU3YDY//d2PeOFPHnwJC+zAlVdA/jp+/6YmZ+1S0qCPxF5HUAAO3fvSpKS4ENEvm6gfUS0c5JiBma2Ibm/QiQPmbmdSqohquoA7GqSxRaapmkBjBkAeHP336t0UWBmHcnb+VcR4XcJpjDJLjPHkS4tleqZubmNiDHU6gumDQDYuvvh7hpV9V9EXgaA5Ka2jbMjmNk7yZOIfEfE8eFVfuSDLda4JDsD3FNdEckTC0YAAAAASUVORK5CYII=);--warp-view-popup-bg-color: #ffffff;--warp-view-popup-border-color: rgba(0, 0, 0, .2);--warp-view-popup-header-bg-color: #c0c0c0;--warp-view-popup-title-color: #404040;--warp-view-popup-close-color: #404040;--warp-view-popup-body-bg-color: #ffffff;--warp-view-popup-body-color: #000000;--warp-view-annotationtooltip-value-font-color: #004eff;--warp-view-annotationtooltip-font-color: #404040;--warp-view-spinner-color: #ff9900;--warp-view-tooltip-bg: #ffffff;--warp-view-tooltip-color: #000000;--warp-slider-connect-color: #ff9900;--warp-slider-handle-bg-color: #ffffff;--warp-slider-handle-color: #004eff;--warp-slider-handle-shadow: inset 0 0 1px #ffffff, inset 0 1px 7px #c0c0c0, 0 3px 6px -3px #a0a0a0}.noData{width:100%;text-align:center;color:var(--warp-view-chart-legend-color);position:relative}.js-plotly-plot .plotly .cursor-ew-resize{cursor:default!important}/*!\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 */.gts-classname{color:var(--gts-classname-font-color)}.gts-labelname{color:var(--gts-labelname-font-color)}.gts-attrname{color:var(--gts-attrname-font-color)}.gts-separator{color:var(--gts-separator-font-color)}.gts-labelvalue{color:var(--gts-labelvalue-font-color);font-style:italic}.gts-attrvalue{color:var(--gts-attrvalue-font-color);font-style:italic}.wv-tooltip{background-color:var(--warp-view-tooltip-bg)!important;color:var(--warp-view-tooltip-color)!important;text-align:left;position:absolute;display:none;padding:10px;border:1px solid grey;border-radius:5px;box-shadow:none;pointer-events:none;font-size:10px;min-width:100px;width:auto;max-width:50%;z-index:999;height:auto!important;left:-1000px}.wv-tooltip .chip{border-radius:50%;background-color:#bbb;display:inline-block;width:5px;height:5px;border:2px solid #454545;margin-top:auto;margin-bottom:auto;vertical-align:middle;cursor:pointer}:host{display:block;height:100%}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host .bar{width:1px;left:-100px;position:absolute;background-color:transparent;-webkit-backface-visibility:hidden;backface-visibility:hidden;top:30px;bottom:55px;overflow:hidden;display:none;z-index:0;pointer-events:none;border-left:dashed 1px var(--warp-view-bar-color)}:host div.chart{width:var(--warp-view-chart-width);height:var(--warp-view-chart-height)}:host .executionErrorText{color:red;padding:10px;border-color:red;border-width:2px;border-radius:3px;border-style:solid;background:antiquewhite;position:absolute;top:-30px}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.SizeService }, { type: i0.NgZone }]; }, propDecorators: { line: [{
type: ViewChild,
args: ['line']
}], hiddenData: [{
type: Input,
args: ['hiddenData']
}], type: [{
type: Input,
args: ['type']
}], standalone: [{
type: Input,
args: ['standalone']
}], boundsDidChange: [{
type: Output,
args: ['boundsDidChange']
}], pointHover: [{
type: Output,
args: ['pointHover']
}], warpViewChartResize: [{
type: Output,
args: ['warpViewChartResize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FycC12aWV3LWNoYXJ0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcnB2aWV3LW5nL3NyYy9saWIvZWxlbWVudHMvd2FycC12aWV3LWNoYXJ0L3dhcnAtdmlldy1jaGFydC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXJwdmlldy1uZy9zcmMvbGliL2VsZW1lbnRzL3dhcnAtdmlldy1jaGFydC93YXJwLXZpZXctY2hhcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQVUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFHMUksT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDL0MsT0FBTyxFQUFrQixpQkFBaUIsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQzFFLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUMxRCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDMUMsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7QUFTL0MsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGlCQUFpQjtJQTRGM0QsWUFD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QWEsQ0FBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNqRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQy9CLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7U0FDbEM7UUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQ