UI: Range chart widget config improvements.
This commit is contained in:
parent
2fb604e398
commit
ce3be06796
@ -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<ColorRange>): 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<RangeItem>): number[] => {
|
||||
const points = new Set<number>();
|
||||
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<TimeSeriesChartKeySettings>;
|
||||
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<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,
|
||||
};
|
||||
const settings = rangeChartTimeSeriesSettings(this.settings, this.rangeItems, this.decimals, this.units);
|
||||
this.timeSeriesChart = new TbTimeSeriesChart(this.ctx, settings, this.chartShape.nativeElement, this.renderer);
|
||||
}
|
||||
|
||||
|
||||
@ -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<TimeSeriesChartSettings> => {
|
||||
const thresholds: DeepPartial<TimeSeriesChartThreshold>[] = 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<TimeSeriesChartThreshold>));
|
||||
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<TimeSeriesChartKeySettings> => ({
|
||||
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<ColorRange>): 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<RangeItem>): number[] => {
|
||||
const points = new Set<number>();
|
||||
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();
|
||||
};
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user