diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts index afc2c720f9..42c72d6526 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts @@ -30,116 +30,25 @@ import { import { WidgetContext } from '@home/models/widget-component.models'; import { backgroundStyle, - ColorRange, ComponentStyle, - filterIncludingColorRanges, getDataKey, overlayStyle, - sortedColorRange, textStyle } from '@shared/models/widget-settings.models'; -import { isDefinedAndNotNull, isNumber } from '@core/utils'; -import { rangeChartDefaultSettings, RangeChartWidgetSettings } from './range-chart-widget.models'; +import { isDefinedAndNotNull } from '@core/utils'; +import { + rangeChartDefaultSettings, + rangeChartTimeSeriesKeySettings, + rangeChartTimeSeriesSettings, + RangeChartWidgetSettings, + RangeItem, + toRangeItems +} 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 { - 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; - color: string; - label: string; - visible: boolean; - enabled: boolean; - piece: TimeSeriesChartVisualMapPiece; -} - -const rangeItemLabel = (from?: number, to?: number): string => { - if (isNumber(from) && isNumber(to)) { - if (from === to) { - return `${from}`; - } else { - return `${from} - ${to}`; - } - } else if (isNumber(from)) { - return `≥ ${from}`; - } else if (isNumber(to)) { - return `< ${to}`; - } else { - return null; - } -}; - -const toRangeItems = (colorRanges: Array): RangeItem[] => { - const rangeItems: RangeItem[] = []; - let counter = 0; - const ranges = sortedColorRange(filterIncludingColorRanges(colorRanges)).filter(r => isNumber(r.from) || isNumber(r.to)); - for (let i = 0; i < ranges.length; i++) { - const range = ranges[i]; - let from = range.from; - const to = range.to; - if (i > 0) { - const prevRange = ranges[i - 1]; - if (isNumber(prevRange.to) && isNumber(from) && from < prevRange.to) { - from = prevRange.to; - } - } - rangeItems.push( - { - index: counter++, - color: range.color, - enabled: true, - visible: true, - from, - to, - label: rangeItemLabel(from, to), - piece: createTimeSeriesChartVisualMapPiece(range.color, from, to) - } - ); - if (!isNumber(from) || !isNumber(to)) { - const value = !isNumber(from) ? to : from; - rangeItems.push( - { - index: counter++, - color: 'transparent', - enabled: true, - visible: false, - label: '', - piece: { gt: value - 0.000000001, lt: value + 0.000000001, color: 'transparent'} - } - ); - } - } - return rangeItems; -}; - -const getMarkPoints = (ranges: Array): number[] => { - const points = new Set(); - for (const range of ranges) { - if (range.visible) { - if (isNumber(range.from)) { - points.add(range.from); - } - if (isNumber(range.to)) { - points.add(range.to); - } - } - } - return Array.from(points).sort(); -}; - @Component({ selector: 'tb-range-chart-widget', templateUrl: './range-chart-widget.component.html', @@ -196,17 +105,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn 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; + dataKey.settings = rangeChartTimeSeriesKeySettings(this.settings); } this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer); @@ -226,64 +125,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn } ngAfterViewInit() { - const thresholds: DeepPartial[] = 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)); - const settings: DeepPartial = { - 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, - }; + const settings = rangeChartTimeSeriesSettings(this.settings, this.rangeItems, this.decimals, this.units); this.timeSeriesChart = new TbTimeSeriesChart(this.ctx, settings, this.chartShape.nativeElement, this.renderer); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts index 31905e70ba..bff0c8fb1b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts @@ -18,11 +18,37 @@ import { BackgroundSettings, BackgroundType, ColorRange, + filterIncludingColorRanges, Font, - simpleDateFormat + simpleDateFormat, + sortedColorRange } from '@shared/models/widget-settings.models'; import { LegendPosition } from '@shared/models/widget.models'; import { EChartsTooltipWidgetSettings } from '@home/components/widget/lib/chart/echarts-widget.models'; +import { + createTimeSeriesChartVisualMapPiece, + SeriesFillType, + TimeSeriesChartKeySettings, + TimeSeriesChartSeriesType, + TimeSeriesChartSettings, + TimeSeriesChartShape, + TimeSeriesChartThreshold, + TimeSeriesChartThresholdType, + TimeSeriesChartVisualMapPiece +} from '@home/components/widget/lib/chart/time-series-chart.models'; +import { isNumber } from '@core/utils'; +import { DeepPartial } from '@shared/models/common'; + +export interface RangeItem { + index: number; + from?: number; + to?: number; + color: string; + label: string; + visible: boolean; + enabled: boolean; + piece: TimeSeriesChartVisualMapPiece; +} export interface RangeChartWidgetSettings extends EChartsTooltipWidgetSettings { dataZoom: boolean; @@ -94,3 +120,152 @@ export const rangeChartDefaultSettings: RangeChartWidgetSettings = { } } }; + +export const rangeChartTimeSeriesSettings = (settings: RangeChartWidgetSettings, rangeItems: RangeItem[], + decimals: number, units: string): DeepPartial => { + const thresholds: DeepPartial[] = getMarkPoints(rangeItems).map(item => ({ + type: TimeSeriesChartThresholdType.constant, + yAxisId: 'default', + units, + 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)); + return { + dataZoom: settings.dataZoom, + thresholds, + yAxes: { + default: { + show: true, + showLine: false, + showTicks: false, + showTickLabels: true, + showSplitLines: true, + decimals, + units + } + }, + xAxis: { + show: true, + showLine: true, + showTicks: true, + showTickLabels: true, + showSplitLines: false + }, + visualMapSettings: { + outOfRangeColor: settings.outOfRangeColor, + pieces: rangeItems.map(item => item.piece) + }, + showTooltip: settings.showTooltip, + tooltipValueFont: settings.tooltipValueFont, + tooltipValueColor: settings.tooltipValueColor, + tooltipShowDate: settings.tooltipShowDate, + tooltipDateInterval: settings.tooltipDateInterval, + tooltipDateFormat: settings.tooltipDateFormat, + tooltipDateFont: settings.tooltipDateFont, + tooltipDateColor: settings.tooltipDateColor, + tooltipBackgroundColor: settings.tooltipBackgroundColor, + tooltipBackgroundBlur: settings.tooltipBackgroundBlur, + }; +}; + +export const rangeChartTimeSeriesKeySettings = (settings: RangeChartWidgetSettings): DeepPartial => ({ + type: TimeSeriesChartSeriesType.line, + lineSettings: { + showLine: true, + smooth: false, + showPoints: false, + fillAreaSettings: { + type: settings.fillArea ? SeriesFillType.opacity : SeriesFillType.none, + opacity: 0.7 + } + } + }); + +export const toRangeItems = (colorRanges: Array): RangeItem[] => { + const rangeItems: RangeItem[] = []; + let counter = 0; + const ranges = sortedColorRange(filterIncludingColorRanges(colorRanges)).filter(r => isNumber(r.from) || isNumber(r.to)); + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + let from = range.from; + const to = range.to; + if (i > 0) { + const prevRange = ranges[i - 1]; + if (isNumber(prevRange.to) && isNumber(from) && from < prevRange.to) { + from = prevRange.to; + } + } + rangeItems.push( + { + index: counter++, + color: range.color, + enabled: true, + visible: true, + from, + to, + label: rangeItemLabel(from, to), + piece: createTimeSeriesChartVisualMapPiece(range.color, from, to) + } + ); + if (!isNumber(from) || !isNumber(to)) { + const value = !isNumber(from) ? to : from; + rangeItems.push( + { + index: counter++, + color: 'transparent', + enabled: true, + visible: false, + label: '', + piece: { gt: value - 0.000000001, lt: value + 0.000000001, color: 'transparent'} + } + ); + } + } + return rangeItems; +}; + +const rangeItemLabel = (from?: number, to?: number): string => { + if (isNumber(from) && isNumber(to)) { + if (from === to) { + return `${from}`; + } else { + return `${from} - ${to}`; + } + } else if (isNumber(from)) { + return `≥ ${from}`; + } else if (isNumber(to)) { + return `< ${to}`; + } else { + return null; + } +}; + +const getMarkPoints = (ranges: Array): number[] => { + const points = new Set(); + for (const range of ranges) { + if (range.visible) { + if (isNumber(range.from)) { + points.add(range.from); + } + if (isNumber(range.to)) { + points.add(range.to); + } + } + } + return Array.from(points).sort(); +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts index 297e4b025a..02cd2bba75 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts @@ -715,7 +715,7 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = { }; export interface SeriesFillSettings { - type: SeriesFillType | 'default'; + type: SeriesFillType; opacity: number; gradient: { start: number; @@ -1322,7 +1322,7 @@ const createTimeSeriesChartSeries = (item: TimeSeriesChartDataItem, borderWidth: barSettings.showBorder ? barSettings.borderWidth : 0, borderRadius: barSettings.borderRadius }; - if (barSettings.backgroundSettings.type === SeriesFillType.none || barSettings.backgroundSettings.type === 'default') { + if (barSettings.backgroundSettings.type === SeriesFillType.none) { barVisualSettings.color = seriesColor; } else if (barSettings.backgroundSettings.type === SeriesFillType.opacity) { barVisualSettings.color = tinycolor(seriesColor).setAlpha(barSettings.backgroundSettings.opacity).toRgbString();