UI: Refactor range chart widget to use time series chart class.
This commit is contained in:
parent
7900d5f29c
commit
2fb604e398
@ -32,48 +32,38 @@ import {
|
||||
backgroundStyle,
|
||||
ColorRange,
|
||||
ComponentStyle,
|
||||
DateFormatProcessor,
|
||||
filterIncludingColorRanges,
|
||||
getDataKey,
|
||||
overlayStyle,
|
||||
sortedColorRange,
|
||||
textStyle
|
||||
} from '@shared/models/widget-settings.models';
|
||||
import { ResizeObserver } from '@juggle/resize-observer';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { formatValue, isDefinedAndNotNull, isNumber } from '@core/utils';
|
||||
import { isDefinedAndNotNull, isNumber } from '@core/utils';
|
||||
import { rangeChartDefaultSettings, RangeChartWidgetSettings } from './range-chart-widget.models';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ImagePipe } from '@shared/pipe/image.pipe';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { DeepPartial } from '@shared/models/common';
|
||||
import {
|
||||
ECharts,
|
||||
echartsModule,
|
||||
EChartsOption,
|
||||
echartsTooltipFormatter, timeAxisBandWidthCalculator,
|
||||
toNamedData
|
||||
} from '@home/components/widget/lib/chart/echarts-widget.models';
|
||||
import { CallbackDataParams } from 'echarts/types/dist/shared';
|
||||
import { AggregationType } from '@shared/models/time/time.models';
|
||||
|
||||
interface VisualPiece {
|
||||
lt?: number;
|
||||
gt?: number;
|
||||
lte?: number;
|
||||
gte?: number;
|
||||
value?: number;
|
||||
color?: string;
|
||||
}
|
||||
createTimeSeriesChartVisualMapPiece,
|
||||
SeriesFillType,
|
||||
TimeSeriesChartKeySettings,
|
||||
TimeSeriesChartSettings,
|
||||
TimeSeriesChartShape,
|
||||
TimeSeriesChartThreshold,
|
||||
TimeSeriesChartThresholdType, TimeSeriesChartVisualMapPiece
|
||||
} from '@home/components/widget/lib/chart/time-series-chart.models';
|
||||
import { TbTimeSeriesChart } from '@home/components/widget/lib/chart/time-series-chart';
|
||||
|
||||
interface RangeItem {
|
||||
index: number;
|
||||
from?: number;
|
||||
to?: number;
|
||||
piece: VisualPiece;
|
||||
color: string;
|
||||
label: string;
|
||||
visible: boolean;
|
||||
enabled: boolean;
|
||||
piece: TimeSeriesChartVisualMapPiece;
|
||||
}
|
||||
|
||||
const rangeItemLabel = (from?: number, to?: number): string => {
|
||||
@ -92,25 +82,6 @@ const rangeItemLabel = (from?: number, to?: number): string => {
|
||||
}
|
||||
};
|
||||
|
||||
const toVisualPiece = (color: string, from?: number, to?: number): VisualPiece => {
|
||||
const piece: VisualPiece = {
|
||||
color
|
||||
};
|
||||
if (isNumber(from) && isNumber(to)) {
|
||||
if (from === to) {
|
||||
piece.value = from;
|
||||
} else {
|
||||
piece.gte = from;
|
||||
piece.lt = to;
|
||||
}
|
||||
} else if (isNumber(from)) {
|
||||
piece.gte = from;
|
||||
} else if (isNumber(to)) {
|
||||
piece.lt = to;
|
||||
}
|
||||
return piece;
|
||||
};
|
||||
|
||||
const toRangeItems = (colorRanges: Array<ColorRange>): RangeItem[] => {
|
||||
const rangeItems: RangeItem[] = [];
|
||||
let counter = 0;
|
||||
@ -134,7 +105,7 @@ const toRangeItems = (colorRanges: Array<ColorRange>): RangeItem[] => {
|
||||
from,
|
||||
to,
|
||||
label: rangeItemLabel(from, to),
|
||||
piece: toVisualPiece(range.color, from, to)
|
||||
piece: createTimeSeriesChartVisualMapPiece(range.color, from, to)
|
||||
}
|
||||
);
|
||||
if (!isNumber(from) || !isNumber(to)) {
|
||||
@ -198,23 +169,12 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn
|
||||
disabledLegendLabelStyle: ComponentStyle;
|
||||
visibleRangeItems: RangeItem[];
|
||||
|
||||
private get noAggregation(): boolean {
|
||||
return this.ctx.defaultSubscription.timeWindowConfig?.aggregation?.type === AggregationType.NONE;
|
||||
}
|
||||
|
||||
private rangeItems: RangeItem[];
|
||||
|
||||
private shapeResize$: ResizeObserver;
|
||||
|
||||
private decimals = 0;
|
||||
private units = '';
|
||||
|
||||
private drawChartPending = false;
|
||||
private rangeChart: ECharts;
|
||||
private rangeChartOptions: EChartsOption;
|
||||
private selectedRanges: {[key: number]: boolean} = {};
|
||||
private rangeItems: RangeItem[];
|
||||
|
||||
private tooltipDateFormat: DateFormatProcessor;
|
||||
private timeSeriesChart: TbTimeSeriesChart;
|
||||
|
||||
constructor(private imagePipe: ImagePipe,
|
||||
private sanitizer: DomSanitizer,
|
||||
@ -235,16 +195,25 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn
|
||||
if (dataKey?.units) {
|
||||
this.units = dataKey.units;
|
||||
}
|
||||
|
||||
if (dataKey) {
|
||||
dataKey.settings = {
|
||||
type: 'line',
|
||||
lineSettings: {
|
||||
showLine: true,
|
||||
smooth: false,
|
||||
showPoints: false,
|
||||
fillAreaSettings: {
|
||||
type: this.settings.fillArea ? 'default' : SeriesFillType.none
|
||||
}
|
||||
}
|
||||
} as DeepPartial<TimeSeriesChartKeySettings>;
|
||||
}
|
||||
|
||||
this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer);
|
||||
this.overlayStyle = overlayStyle(this.settings.background.overlay);
|
||||
|
||||
this.rangeItems = toRangeItems(this.settings.rangeColors);
|
||||
this.visibleRangeItems = this.rangeItems.filter(item => item.visible);
|
||||
for (const range of this.rangeItems) {
|
||||
this.selectedRanges[range.index] = true;
|
||||
}
|
||||
|
||||
this.showLegend = this.settings.showLegend && !!this.rangeItems.length;
|
||||
|
||||
@ -254,193 +223,90 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn
|
||||
this.disabledLegendLabelStyle = textStyle(this.settings.legendLabelFont);
|
||||
this.legendLabelStyle.color = this.settings.legendLabelColor;
|
||||
}
|
||||
|
||||
if (this.settings.showTooltip && this.settings.tooltipShowDate) {
|
||||
this.tooltipDateFormat = DateFormatProcessor.fromSettings(this.ctx.$injector, this.settings.tooltipDateFormat);
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (this.drawChartPending) {
|
||||
this.drawChart();
|
||||
const thresholds: DeepPartial<TimeSeriesChartThreshold>[] = getMarkPoints(this.rangeItems).map(item => ({
|
||||
type: TimeSeriesChartThresholdType.constant,
|
||||
yAxisId: 'default',
|
||||
units: this.units,
|
||||
decimals: this.decimals,
|
||||
lineWidth: 1,
|
||||
lineColor: '#37383b',
|
||||
lineType: [3, 3],
|
||||
startSymbol: TimeSeriesChartShape.circle,
|
||||
startSymbolSize: 5,
|
||||
endSymbol: TimeSeriesChartShape.arrow,
|
||||
endSymbolSize: 7,
|
||||
showLabel: true,
|
||||
labelPosition: 'insideEndTop',
|
||||
labelColor: '#37383b',
|
||||
additionalLabelOption: {
|
||||
backgroundColor: 'rgba(255,255,255,0.56)',
|
||||
padding: [4, 5],
|
||||
borderRadius: 4,
|
||||
},
|
||||
value: item
|
||||
} as DeepPartial<TimeSeriesChartThreshold>));
|
||||
const settings: DeepPartial<TimeSeriesChartSettings> = {
|
||||
dataZoom: this.settings.dataZoom,
|
||||
thresholds,
|
||||
yAxes: {
|
||||
default: {
|
||||
show: true,
|
||||
showLine: false,
|
||||
showTicks: false,
|
||||
showTickLabels: true,
|
||||
showSplitLines: true,
|
||||
decimals: this.decimals,
|
||||
units: this.units
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
show: true,
|
||||
showLine: true,
|
||||
showTicks: true,
|
||||
showTickLabels: true,
|
||||
showSplitLines: false
|
||||
},
|
||||
visualMapSettings: {
|
||||
outOfRangeColor: this.settings.outOfRangeColor,
|
||||
pieces: this.rangeItems.map(item => item.piece)
|
||||
},
|
||||
showTooltip: this.settings.showTooltip,
|
||||
tooltipValueFont: this.settings.tooltipValueFont,
|
||||
tooltipValueColor: this.settings.tooltipValueColor,
|
||||
tooltipShowDate: this.settings.tooltipShowDate,
|
||||
tooltipDateInterval: this.settings.tooltipDateInterval,
|
||||
tooltipDateFormat: this.settings.tooltipDateFormat,
|
||||
tooltipDateFont: this.settings.tooltipDateFont,
|
||||
tooltipDateColor: this.settings.tooltipDateColor,
|
||||
tooltipBackgroundColor: this.settings.tooltipBackgroundColor,
|
||||
tooltipBackgroundBlur: this.settings.tooltipBackgroundBlur,
|
||||
};
|
||||
this.timeSeriesChart = new TbTimeSeriesChart(this.ctx, settings, this.chartShape.nativeElement, this.renderer);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.shapeResize$) {
|
||||
this.shapeResize$.disconnect();
|
||||
}
|
||||
if (this.rangeChart) {
|
||||
this.rangeChart.dispose();
|
||||
if (this.timeSeriesChart) {
|
||||
this.timeSeriesChart.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public onInit() {
|
||||
const borderRadius = this.ctx.$widgetElement.css('borderRadius');
|
||||
this.overlayStyle = {...this.overlayStyle, ...{borderRadius}};
|
||||
if (this.chartShape) {
|
||||
this.drawChart();
|
||||
} else {
|
||||
this.drawChartPending = true;
|
||||
}
|
||||
this.cd.detectChanges();
|
||||
}
|
||||
|
||||
public onDataUpdated() {
|
||||
if (this.rangeChart) {
|
||||
this.rangeChart.setOption({
|
||||
xAxis: {
|
||||
min: this.ctx.defaultSubscription.timeWindow.minTime,
|
||||
max: this.ctx.defaultSubscription.timeWindow.maxTime,
|
||||
tbTimeWindow: this.ctx.defaultSubscription.timeWindow
|
||||
},
|
||||
series: [
|
||||
{data: this.ctx.data?.length ? toNamedData(this.ctx.data[0].data) : []}
|
||||
],
|
||||
visualMap: {
|
||||
selected: this.selectedRanges
|
||||
}
|
||||
});
|
||||
if (this.timeSeriesChart) {
|
||||
this.timeSeriesChart.update();
|
||||
}
|
||||
}
|
||||
|
||||
public toggleRangeItem(item: RangeItem) {
|
||||
item.enabled = !item.enabled;
|
||||
this.selectedRanges[item.index] = item.enabled;
|
||||
this.rangeChart.dispatchAction({
|
||||
type: 'selectDataRange',
|
||||
selected: this.selectedRanges
|
||||
});
|
||||
}
|
||||
|
||||
private drawChart() {
|
||||
echartsModule.init();
|
||||
const dataKey = getDataKey(this.ctx.datasources);
|
||||
this.rangeChart = echarts.init(this.chartShape.nativeElement, null, {
|
||||
renderer: 'canvas',
|
||||
});
|
||||
this.rangeChartOptions = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
confine: true,
|
||||
appendTo: 'body',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
},
|
||||
formatter: (params: CallbackDataParams[]) =>
|
||||
this.settings.showTooltip ? echartsTooltipFormatter(this.renderer, this.tooltipDateFormat,
|
||||
this.settings, params, this.decimals, this.units, 0, null,
|
||||
this.noAggregation ? null : this.ctx.timeWindow.interval) : undefined,
|
||||
padding: [8, 12],
|
||||
backgroundColor: this.settings.tooltipBackgroundColor,
|
||||
borderWidth: 0,
|
||||
extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);`
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
top: '30',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: this.settings.dataZoom ? 60 : 0
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
axisTick: {
|
||||
show: true
|
||||
},
|
||||
axisLabel: {
|
||||
hideOverlap: true,
|
||||
fontSize: 10
|
||||
},
|
||||
axisLine: {
|
||||
onZero: false
|
||||
},
|
||||
min: this.ctx.defaultSubscription.timeWindow.minTime,
|
||||
max: this.ctx.defaultSubscription.timeWindow.maxTime,
|
||||
bandWidthCalculator: timeAxisBandWidthCalculator
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: (value: any) => formatValue(value, this.decimals, this.units, false)
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
type: 'line',
|
||||
name: dataKey?.label,
|
||||
smooth: false,
|
||||
showSymbol: false,
|
||||
animation: true,
|
||||
areaStyle: this.settings.fillArea ? {} : undefined,
|
||||
data: this.ctx.data?.length ? toNamedData(this.ctx.data[0].data) : [],
|
||||
markLine: this.rangeItems.length ? {
|
||||
animation: true,
|
||||
symbol: ['circle', 'arrow'],
|
||||
symbolSize: [5, 7],
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
type: [3, 3],
|
||||
color: '#37383b'
|
||||
},
|
||||
label: {
|
||||
position: 'insideEndTop',
|
||||
color: '#37383b',
|
||||
backgroundColor: 'rgba(255,255,255,0.56)',
|
||||
padding: [4, 5],
|
||||
borderRadius: 4,
|
||||
formatter: params => formatValue(params.value, this.decimals, this.units, false)
|
||||
},
|
||||
emphasis: {
|
||||
disabled: true
|
||||
},
|
||||
data: getMarkPoints(this.rangeItems).map(point => ({ yAxis: point }))
|
||||
} : undefined
|
||||
}],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
disabled: !this.settings.dataZoom
|
||||
},
|
||||
{
|
||||
type: 'slider',
|
||||
show: this.settings.dataZoom,
|
||||
showDetail: false,
|
||||
right: 10
|
||||
}
|
||||
],
|
||||
visualMap: {
|
||||
show: false,
|
||||
type: 'piecewise',
|
||||
selected: this.selectedRanges,
|
||||
dimension: 1,
|
||||
pieces: this.rangeItems.map(item => item.piece),
|
||||
outOfRange: {
|
||||
color: this.settings.outOfRangeColor
|
||||
},
|
||||
inRange: !this.rangeItems.length ? {
|
||||
color: this.settings.outOfRangeColor
|
||||
} : undefined
|
||||
}
|
||||
};
|
||||
|
||||
(this.rangeChartOptions.xAxis as any).tbTimeWindow = this.ctx.defaultSubscription.timeWindow;
|
||||
|
||||
this.rangeChart.setOption(this.rangeChartOptions);
|
||||
|
||||
this.shapeResize$ = new ResizeObserver(() => {
|
||||
this.onResize();
|
||||
});
|
||||
this.shapeResize$.observe(this.chartShape.nativeElement);
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
private onResize() {
|
||||
const width = this.rangeChart.getWidth();
|
||||
const height = this.rangeChart.getHeight();
|
||||
const shapeWidth = this.chartShape.nativeElement.offsetWidth;
|
||||
const shapeHeight = this.chartShape.nativeElement.offsetHeight;
|
||||
if (width !== shapeWidth || height !== shapeHeight) {
|
||||
this.rangeChart.resize();
|
||||
}
|
||||
this.timeSeriesChart.toggleVisualMapRange(item.index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,12 +31,17 @@ import {
|
||||
textStyle,
|
||||
tsToFormatTimeUnit
|
||||
} from '@shared/models/widget-settings.models';
|
||||
import { LabelLayoutOptionCallback, XAXisOption, YAXisOption } from 'echarts/types/dist/shared';
|
||||
import {
|
||||
LabelLayoutOptionCallback,
|
||||
VisualMapComponentOption,
|
||||
XAXisOption,
|
||||
YAXisOption
|
||||
} from 'echarts/types/dist/shared';
|
||||
import { CustomSeriesOption, LineSeriesOption } from 'echarts/charts';
|
||||
import {
|
||||
formatValue,
|
||||
isDefinedAndNotNull,
|
||||
isFunction,
|
||||
isFunction, isNumber,
|
||||
isNumeric,
|
||||
isUndefined,
|
||||
isUndefinedOrNull,
|
||||
@ -417,7 +422,7 @@ export interface TimeSeriesChartThreshold {
|
||||
units?: string;
|
||||
decimals?: number;
|
||||
lineColor: string;
|
||||
lineType: TimeSeriesChartLineType;
|
||||
lineType: TimeSeriesChartLineType | number | number[];
|
||||
lineWidth: number;
|
||||
startSymbol: TimeSeriesChartShape;
|
||||
startSymbolSize: number;
|
||||
@ -427,6 +432,7 @@ export interface TimeSeriesChartThreshold {
|
||||
labelPosition: ThresholdLabelPosition;
|
||||
labelFont: Font;
|
||||
labelColor: string;
|
||||
additionalLabelOption?: {[key: string]: any};
|
||||
}
|
||||
|
||||
export const timeSeriesChartThresholdValid = (threshold: TimeSeriesChartThreshold): boolean => {
|
||||
@ -567,6 +573,39 @@ export interface TimeSeriesChartAnimationSettings {
|
||||
animationDelayUpdate: number;
|
||||
}
|
||||
|
||||
export interface TimeSeriesChartVisualMapPiece {
|
||||
lt?: number;
|
||||
gt?: number;
|
||||
lte?: number;
|
||||
gte?: number;
|
||||
value?: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const createTimeSeriesChartVisualMapPiece = (color: string, from?: number, to?: number): TimeSeriesChartVisualMapPiece => {
|
||||
const piece: TimeSeriesChartVisualMapPiece = {
|
||||
color
|
||||
};
|
||||
if (isNumber(from) && isNumber(to)) {
|
||||
if (from === to) {
|
||||
piece.value = from;
|
||||
} else {
|
||||
piece.gte = from;
|
||||
piece.lt = to;
|
||||
}
|
||||
} else if (isNumber(from)) {
|
||||
piece.gte = from;
|
||||
} else if (isNumber(to)) {
|
||||
piece.lt = to;
|
||||
}
|
||||
return piece;
|
||||
};
|
||||
|
||||
export interface TimeSeriesChartVisualMapSettings {
|
||||
outOfRangeColor: string;
|
||||
pieces: TimeSeriesChartVisualMapPiece[];
|
||||
}
|
||||
|
||||
export interface TimeSeriesChartSettings extends EChartsTooltipWidgetSettings {
|
||||
thresholds: TimeSeriesChartThreshold[];
|
||||
darkMode: boolean;
|
||||
@ -577,6 +616,7 @@ export interface TimeSeriesChartSettings extends EChartsTooltipWidgetSettings {
|
||||
animation: TimeSeriesChartAnimationSettings;
|
||||
barWidthSettings: TimeSeriesChartBarWidthSettings;
|
||||
noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings;
|
||||
visualMapSettings?: TimeSeriesChartVisualMapSettings;
|
||||
}
|
||||
|
||||
export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = {
|
||||
@ -675,7 +715,7 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = {
|
||||
};
|
||||
|
||||
export interface SeriesFillSettings {
|
||||
type: SeriesFillType;
|
||||
type: SeriesFillType | 'default';
|
||||
opacity: number;
|
||||
gradient: {
|
||||
start: number;
|
||||
@ -960,7 +1000,7 @@ export const createTimeSeriesXAxisOption = (settings: TimeSeriesChartXAxisSettin
|
||||
fontFamily: xAxisTickLabelStyle.fontFamily,
|
||||
fontSize: xAxisTickLabelStyle.fontSize,
|
||||
hideOverlap: true,
|
||||
formatter: (value: number, index: number, extra: {level: number}) => {
|
||||
formatter: (value: number, _index: number, extra: {level: number}) => {
|
||||
const unit = tsToFormatTimeUnit(value);
|
||||
const format = ticksFormat[unit];
|
||||
const formatted = datePipe.transform(value, format);
|
||||
@ -990,6 +1030,21 @@ export const createTimeSeriesXAxisOption = (settings: TimeSeriesChartXAxisSettin
|
||||
};
|
||||
};
|
||||
|
||||
export const createTimeSeriesVisualMapOption = (settings: TimeSeriesChartVisualMapSettings,
|
||||
selectedRanges: {[key: number]: boolean}): VisualMapComponentOption => ({
|
||||
show: false,
|
||||
type: 'piecewise',
|
||||
selected: selectedRanges,
|
||||
dimension: 1,
|
||||
pieces: settings.pieces,
|
||||
outOfRange: {
|
||||
color: settings.outOfRangeColor
|
||||
},
|
||||
inRange: !settings.pieces.length ? {
|
||||
color: settings.outOfRangeColor
|
||||
} : undefined
|
||||
});
|
||||
|
||||
export const generateChartData = (dataItems: TimeSeriesChartDataItem[],
|
||||
thresholdItems: TimeSeriesChartThresholdItem[],
|
||||
stack: boolean,
|
||||
@ -1072,6 +1127,9 @@ const generateChartThresholds = (thresholdItems: TimeSeriesChartThresholdItem[])
|
||||
}
|
||||
}
|
||||
};
|
||||
if (item.settings.additionalLabelOption) {
|
||||
seriesOption.markLine.label = {...seriesOption.markLine.label, ...item.settings.additionalLabelOption};
|
||||
}
|
||||
item.option = seriesOption;
|
||||
}
|
||||
seriesOption.markLine.data = [];
|
||||
@ -1147,7 +1205,7 @@ const generateChartSeries = (dataItems: TimeSeriesChartDataItem[],
|
||||
|
||||
export const updateDarkMode = (options: EChartsOption, settings: TimeSeriesChartSettings,
|
||||
yAxisList: TimeSeriesChartYAxis[],
|
||||
dataItems: TimeSeriesChartDataItem[], thresholdDataItems: TimeSeriesChartThresholdItem[],
|
||||
dataItems: TimeSeriesChartDataItem[],
|
||||
darkMode: boolean): EChartsOption => {
|
||||
options.darkMode = darkMode;
|
||||
if (Array.isArray(options.yAxis)) {
|
||||
@ -1246,7 +1304,7 @@ const createTimeSeriesChartSeries = (item: TimeSeriesChartDataItem,
|
||||
lineSeriesOption.areaStyle = {};
|
||||
if (lineSettings.fillAreaSettings.type === SeriesFillType.opacity) {
|
||||
lineSeriesOption.areaStyle.opacity = lineSettings.fillAreaSettings.opacity;
|
||||
} else {
|
||||
} else if (lineSettings.fillAreaSettings.type === SeriesFillType.gradient) {
|
||||
lineSeriesOption.areaStyle.opacity = 1;
|
||||
lineSeriesOption.areaStyle.color = createLinearOpacityGradient(seriesColor, lineSettings.fillAreaSettings.gradient);
|
||||
}
|
||||
@ -1264,7 +1322,7 @@ const createTimeSeriesChartSeries = (item: TimeSeriesChartDataItem,
|
||||
borderWidth: barSettings.showBorder ? barSettings.borderWidth : 0,
|
||||
borderRadius: barSettings.borderRadius
|
||||
};
|
||||
if (barSettings.backgroundSettings.type === SeriesFillType.none) {
|
||||
if (barSettings.backgroundSettings.type === SeriesFillType.none || barSettings.backgroundSettings.type === 'default') {
|
||||
barVisualSettings.color = seriesColor;
|
||||
} else if (barSettings.backgroundSettings.type === SeriesFillType.opacity) {
|
||||
barVisualSettings.color = tinycolor(seriesColor).setAlpha(barSettings.backgroundSettings.opacity).toRgbString();
|
||||
|
||||
@ -18,6 +18,7 @@ import { WidgetContext } from '@home/models/widget-component.models';
|
||||
import {
|
||||
AxisPosition,
|
||||
calculateThresholdsOffset,
|
||||
createTimeSeriesVisualMapOption,
|
||||
createTimeSeriesXAxisOption,
|
||||
createTimeSeriesYAxis,
|
||||
defaultTimeSeriesChartYAxisSettings,
|
||||
@ -51,7 +52,8 @@ import {
|
||||
EChartsOption,
|
||||
echartsTooltipFormatter,
|
||||
EChartsTooltipTrigger,
|
||||
getAxisExtent, getFocusedSeriesIndex,
|
||||
getAxisExtent,
|
||||
getFocusedSeriesIndex,
|
||||
measureXAxisNameHeight,
|
||||
measureYAxisNameWidth,
|
||||
toNamedData
|
||||
@ -60,7 +62,7 @@ import { DateFormatProcessor } from '@shared/models/widget-settings.models';
|
||||
import { isDefinedAndNotNull, isEqual, mergeDeep } from '@core/utils';
|
||||
import { DataKey, Datasource, DatasourceType, widgetType } from '@shared/models/widget.models';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { CallbackDataParams } from 'echarts/types/dist/shared';
|
||||
import { CallbackDataParams, PiecewiseVisualMapOption } from 'echarts/types/dist/shared';
|
||||
import { Renderer2 } from '@angular/core';
|
||||
import { CustomSeriesOption, LineSeriesOption } from 'echarts/charts';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
@ -107,6 +109,9 @@ export class TbTimeSeriesChart {
|
||||
private dataItems: TimeSeriesChartDataItem[] = [];
|
||||
private thresholdItems: TimeSeriesChartThresholdItem[] = [];
|
||||
|
||||
private hasVisualMap = false;
|
||||
private visualMapSelectedRanges: {[key: number]: boolean};
|
||||
|
||||
private timeSeriesChart: ECharts;
|
||||
private timeSeriesChartOptions: EChartsOption;
|
||||
|
||||
@ -145,6 +150,7 @@ export class TbTimeSeriesChart {
|
||||
this.setupYAxes();
|
||||
this.setupData();
|
||||
this.setupThresholds();
|
||||
this.setupVisualMap();
|
||||
if (this.settings.showTooltip && this.settings.tooltipShowDate) {
|
||||
this.tooltipDateFormat = DateFormatProcessor.fromSettings(this.ctx.$injector, this.settings.tooltipDateFormat);
|
||||
}
|
||||
@ -186,6 +192,9 @@ export class TbTimeSeriesChart {
|
||||
} else {
|
||||
this.timeSeriesChartOptions.tooltip[0].axisPointer.type = 'shadow';
|
||||
}
|
||||
if (this.hasVisualMap) {
|
||||
(this.timeSeriesChartOptions.visualMap as PiecewiseVisualMapOption).selected = this.visualMapSelectedRanges;
|
||||
}
|
||||
this.barRenderSharedContext.timeInterval = this.ctx.timeWindow.interval;
|
||||
this.updateSeriesData(true);
|
||||
if (this.highlightedDataKey) {
|
||||
@ -263,6 +272,16 @@ export class TbTimeSeriesChart {
|
||||
}
|
||||
}
|
||||
|
||||
public toggleVisualMapRange(index: number): void {
|
||||
if (this.hasVisualMap) {
|
||||
this.visualMapSelectedRanges[index] = !this.visualMapSelectedRanges[index];
|
||||
this.timeSeriesChart.dispatchAction({
|
||||
type: 'selectDataRange',
|
||||
selected: this.visualMapSelectedRanges
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
if (this.shapeResize$) {
|
||||
this.shapeResize$.disconnect();
|
||||
@ -284,8 +303,7 @@ export class TbTimeSeriesChart {
|
||||
this.darkMode = darkMode;
|
||||
if (this.timeSeriesChart) {
|
||||
this.timeSeriesChartOptions = updateDarkMode(this.timeSeriesChartOptions,
|
||||
this.settings, this.yAxisList, this.dataItems,
|
||||
this.thresholdItems, darkMode);
|
||||
this.settings, this.yAxisList, this.dataItems, darkMode);
|
||||
this.timeSeriesChart.setOption(this.timeSeriesChartOptions);
|
||||
}
|
||||
}
|
||||
@ -431,6 +449,15 @@ export class TbTimeSeriesChart {
|
||||
}
|
||||
}
|
||||
|
||||
private setupVisualMap(): void {
|
||||
if (this.settings.visualMapSettings?.pieces && this.settings.visualMapSettings?.pieces.length) {
|
||||
this.hasVisualMap = true;
|
||||
this.visualMapSelectedRanges = {};
|
||||
this.settings.visualMapSettings.pieces.forEach((_val, index) => {
|
||||
this.visualMapSelectedRanges[index] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private nextComponentId(): string {
|
||||
return (this.componentIndexCounter++) + '';
|
||||
@ -536,6 +563,10 @@ export class TbTimeSeriesChart {
|
||||
animationEasingUpdate: this.settings.animation.animationEasingUpdate,
|
||||
animationDelayUpdate: this.settings.animation.animationDelayUpdate
|
||||
};
|
||||
if (this.hasVisualMap) {
|
||||
this.timeSeriesChartOptions.visualMap =
|
||||
createTimeSeriesVisualMapOption(this.settings.visualMapSettings, this.visualMapSelectedRanges);
|
||||
}
|
||||
|
||||
this.timeSeriesChartOptions.xAxis[0].tbTimeWindow = this.ctx.defaultSubscription.timeWindow;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user