= {
dataZoom: false,
xAxis: {
show: false
},
- yAxis: {
- show: true,
- showLine: false,
- showTicks: false,
- showTickLabels: false,
- showSplitLines: true,
- min: 'dataMin',
- max: 'dataMax',
- intervalCalculator:
- 'var scale = axis.scale; return !scale.isBlank() ? ((scale.getExtent()[1] - scale.getExtent()[0]) / 2) : undefined;'
+ yAxes: {
+ default: {
+ show: true,
+ showLine: false,
+ showTicks: false,
+ showTickLabels: false,
+ showSplitLines: true,
+ min: 'dataMin',
+ max: 'dataMax',
+ intervalCalculator:
+ 'var scale = axis.scale; return !scale.isBlank() ? ((scale.getExtent()[1] - scale.getExtent()[0]) / 2) : undefined;'
+ }
},
tooltipDateInterval: false,
tooltipDateFormat: simpleDateFormat('dd MMM yyyy HH:mm:ss')
- } as TimeSeriesChartSettings;
+ };
this.lineChart = new TbTimeSeriesChart(this.ctx, settings, this.chartElement.nativeElement, this.renderer, true);
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/cards/value-chart-card-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/cards/value-chart-card-widget.component.ts
index f5a305a247..a7981b3acf 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/cards/value-chart-card-widget.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/cards/value-chart-card-widget.component.ts
@@ -57,6 +57,7 @@ import {
TimeSeriesChartSeriesType,
TimeSeriesChartSettings
} from '@home/components/widget/lib/chart/time-series-chart.models';
+import { DeepPartial } from '@shared/models/common';
const layoutHeight = 56;
const valueRelativeWidth = 0.35;
@@ -162,17 +163,19 @@ export class ValueChartCardWidgetComponent implements OnInit, AfterViewInit, OnD
}
public ngAfterViewInit() {
- const settings: TimeSeriesChartSettings = {
+ const settings: DeepPartial = {
dataZoom: false,
xAxis: {
show: false
},
- yAxis: {
- show: false
+ yAxes: {
+ default: {
+ show: false,
+ }
},
tooltipDateInterval: false,
tooltipDateFormat: simpleDateFormat('dd MMM yyyy HH:mm:ss')
- } as TimeSeriesChartSettings;
+ };
this.lineChart = new TbTimeSeriesChart(this.ctx, settings, this.chartElement.nativeElement, this.renderer, false);
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 edfaa3692d..9af41fa378 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
@@ -25,7 +25,15 @@ import {
import { ComponentStyle, Font, simpleDateFormat, textStyle } from '@shared/models/widget-settings.models';
import { XAXisOption, YAXisOption } from 'echarts/types/dist/shared';
import { CustomSeriesOption, LineSeriesOption } from 'echarts/charts';
-import { formatValue, isDefinedAndNotNull, isUndefined, isUndefinedOrNull, parseFunction } from '@core/utils';
+import {
+ formatValue,
+ isDefinedAndNotNull,
+ isNumeric,
+ isUndefined,
+ isUndefinedOrNull,
+ mergeDeep,
+ parseFunction
+} from '@core/utils';
import { LinearGradientObject } from 'zrender/lib/graphic/LinearGradient';
import tinycolor from 'tinycolor2';
import Axis2D from 'echarts/types/src/coord/cartesian/Axis2D';
@@ -289,13 +297,82 @@ export interface TimeSeriesChartAxisSettings {
splitLinesColor: string;
}
+export type TimeSeriesChartYAxisId = 'default' | string;
+
export interface TimeSeriesChartYAxisSettings extends TimeSeriesChartAxisSettings {
+ id?: TimeSeriesChartYAxisId;
+ order?: number;
+ units?: string;
+ decimals?: number;
min?: number | string;
max?: number | string;
intervalCalculator?: string;
ticksFormatter?: string;
}
+export const timeSeriesChartYAxisValid = (axis: TimeSeriesChartYAxisSettings): boolean =>
+ !(!axis.id || isUndefinedOrNull(axis.order));
+
+export const timeSeriesChartYAxisValidator = (control: AbstractControl): ValidationErrors | null => {
+ const axis: TimeSeriesChartYAxisSettings = control.value;
+ if (!timeSeriesChartYAxisValid(axis)) {
+ return {
+ axis: true
+ };
+ }
+ return null;
+};
+
+export const getNextTimeSeriesYAxisId = (axes: TimeSeriesChartYAxisSettings[]): TimeSeriesChartYAxisId => {
+ let id = 0;
+ for (const axis of axes) {
+ const existingId = axis.id;
+ if (existingId.startsWith('axis')) {
+ const idSuffix = existingId.substring('axis'.length);
+ if (isNumeric(idSuffix)) {
+ id = Math.max(id, Number(idSuffix));
+ }
+ }
+ }
+ return 'axis' + (id+1);
+};
+
+export const defaultTimeSeriesChartYAxisSettings: TimeSeriesChartYAxisSettings = {
+ units: null,
+ decimals: 0,
+ show: true,
+ label: '',
+ labelFont: {
+ family: 'Roboto',
+ size: 12,
+ sizeUnit: 'px',
+ style: 'normal',
+ weight: '600',
+ lineHeight: '1'
+ },
+ labelColor: timeSeriesChartColorScheme['axis.label'].light,
+ position: AxisPosition.left,
+ showTickLabels: true,
+ tickLabelFont: {
+ family: 'Roboto',
+ size: 12,
+ sizeUnit: 'px',
+ style: 'normal',
+ weight: '400',
+ lineHeight: '1'
+ },
+ tickLabelColor: timeSeriesChartColorScheme['axis.tickLabel'].light,
+ ticksFormatter: null,
+ showTicks: true,
+ ticksColor: timeSeriesChartColorScheme['axis.ticks'].light,
+ showLine: true,
+ lineColor: timeSeriesChartColorScheme['axis.line'].light,
+ showSplitLines: true,
+ splitLinesColor: timeSeriesChartColorScheme['axis.splitLine'].light
+};
+
+export type TimeSeriesChartYAxes = {[id: TimeSeriesChartYAxisId]: TimeSeriesChartYAxisSettings};
+
export interface TimeSeriesChartThreshold {
type: TimeSeriesChartThresholdType;
value?: number;
@@ -304,6 +381,7 @@ export interface TimeSeriesChartThreshold {
entityAlias?: string;
entityKey?: string;
entityKeyType?: DataKeyType.attribute | DataKeyType.timeseries;
+ yAxisId: TimeSeriesChartYAxisId;
units?: string;
decimals?: number;
lineColor: string;
@@ -320,7 +398,7 @@ export interface TimeSeriesChartThreshold {
}
export const timeSeriesChartThresholdValid = (threshold: TimeSeriesChartThreshold): boolean => {
- if (!threshold.type) {
+ if (!threshold.type || !threshold.yAxisId) {
return false;
}
switch (threshold.type) {
@@ -355,7 +433,8 @@ export const timeSeriesChartThresholdValidator = (control: AbstractControl): Val
export const timeSeriesChartThresholdDefaultSettings: TimeSeriesChartThreshold = {
type: TimeSeriesChartThresholdType.constant,
- units: '',
+ yAxisId: 'default',
+ units: null,
decimals: 0,
lineColor: timeSeriesChartColorScheme['threshold.line'].light,
lineType: TimeSeriesChartLineType.solid,
@@ -404,13 +483,61 @@ export interface TimeSeriesChartNoAggregationBarWidthSettings {
barWidth?: TimeSeriesChartBarWidth;
}
+export enum TimeSeriesChartAnimationEasing {
+ linear = 'linear',
+ quadraticIn = 'quadraticIn',
+ quadraticOut = 'quadraticOut',
+ quadraticInOut = 'quadraticInOut',
+ cubicIn = 'cubicIn',
+ cubicOut = 'cubicOut',
+ cubicInOut = 'cubicInOut',
+ quarticIn = 'quarticIn',
+ quarticOut = 'quarticOut',
+ quarticInOut = 'quarticInOut',
+ quinticIn = 'quinticIn',
+ quinticOut = 'quinticOut',
+ quinticInOut = 'quinticInOut',
+ sinusoidalIn = 'sinusoidalIn',
+ sinusoidalOut = 'sinusoidalOut',
+ sinusoidalInOut = 'sinusoidalInOut',
+ exponentialIn = 'exponentialIn',
+ exponentialOut = 'exponentialOut',
+ exponentialInOut = 'exponentialInOut',
+ circularIn = 'circularIn',
+ circularOut = 'circularOut',
+ circularInOut = 'circularInOut',
+ elasticIn = 'elasticIn',
+ elasticOut = 'elasticOut',
+ elasticInOut = 'elasticInOut',
+ backIn = 'backIn',
+ backOut = 'backOut',
+ backInOut = 'backInOut',
+ bounceIn = 'bounceIn',
+ bounceOut = 'bounceOut',
+ bounceInOut = 'bounceInOut'
+}
+
+export const timeSeriesChartAnimationEasings = Object.keys(TimeSeriesChartAnimationEasing) as TimeSeriesChartAnimationEasing[];
+
+export interface TimeSeriesChartAnimationSettings {
+ animation: boolean;
+ animationThreshold: number;
+ animationDuration: number;
+ animationEasing: TimeSeriesChartAnimationEasing;
+ animationDelay: number;
+ animationDurationUpdate: number;
+ animationEasingUpdate: TimeSeriesChartAnimationEasing;
+ animationDelayUpdate: number;
+}
+
export interface TimeSeriesChartSettings extends EChartsTooltipWidgetSettings {
thresholds: TimeSeriesChartThreshold[];
darkMode: boolean;
dataZoom: boolean;
stack: boolean;
- yAxis: TimeSeriesChartYAxisSettings;
+ yAxes: TimeSeriesChartYAxes;
xAxis: TimeSeriesChartAxisSettings;
+ animation: TimeSeriesChartAnimationSettings;
noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings;
}
@@ -419,36 +546,10 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = {
darkMode: false,
dataZoom: true,
stack: false,
- yAxis: {
- show: true,
- label: '',
- labelFont: {
- family: 'Roboto',
- size: 12,
- sizeUnit: 'px',
- style: 'normal',
- weight: '600',
- lineHeight: '1'
- },
- labelColor: timeSeriesChartColorScheme['axis.label'].light,
- position: AxisPosition.left,
- showTickLabels: true,
- tickLabelFont: {
- family: 'Roboto',
- size: 12,
- sizeUnit: 'px',
- style: 'normal',
- weight: '400',
- lineHeight: '1'
- },
- tickLabelColor: timeSeriesChartColorScheme['axis.tickLabel'].light,
- ticksFormatter: null,
- showTicks: true,
- ticksColor: timeSeriesChartColorScheme['axis.ticks'].light,
- showLine: true,
- lineColor: timeSeriesChartColorScheme['axis.line'].light,
- showSplitLines: true,
- splitLinesColor: timeSeriesChartColorScheme['axis.splitLine'].light
+ yAxes: {
+ default: mergeDeep({} as TimeSeriesChartYAxisSettings,
+ defaultTimeSeriesChartYAxisSettings,
+ { id: 'default', order: 0 } as TimeSeriesChartYAxisSettings)
},
xAxis: {
show: true,
@@ -480,6 +581,16 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = {
showSplitLines: true,
splitLinesColor: timeSeriesChartColorScheme['axis.splitLine'].light
},
+ animation: {
+ animation: true,
+ animationThreshold: 2000,
+ animationDuration: 1000,
+ animationEasing: TimeSeriesChartAnimationEasing.cubicOut,
+ animationDelay: 0,
+ animationDurationUpdate: 300,
+ animationEasingUpdate: TimeSeriesChartAnimationEasing.cubicOut,
+ animationDelayUpdate: 0
+ },
noAggregationBarWidthSettings: {
strategy: TimeSeriesChartNoAggregationBarWidthStrategy.group,
groupWidth: {
@@ -558,6 +669,7 @@ export interface BarSeriesSettings {
}
export interface TimeSeriesChartKeySettings {
+ yAxisId: TimeSeriesChartYAxisId;
showInLegend: boolean;
dataHiddenByDefault: boolean;
type: TimeSeriesChartSeriesType;
@@ -566,6 +678,7 @@ export interface TimeSeriesChartKeySettings {
}
export const timeSeriesChartKeyDefaultSettings: TimeSeriesChartKeySettings = {
+ yAxisId: 'default',
showInLegend: true,
dataHiddenByDefault: false,
type: TimeSeriesChartSeriesType.line,
@@ -626,6 +739,7 @@ export const timeSeriesChartKeyDefaultSettings: TimeSeriesChartKeySettings = {
};
export interface TimeSeriesChartDataItem extends EChartsSeriesItem {
+ yAxisId: TimeSeriesChartYAxisId;
yAxisIndex: number;
option?: LineSeriesOption | CustomSeriesOption;
barRenderContext?: BarRenderContext;
@@ -635,6 +749,7 @@ type TimeSeriesChartThresholdValue = number | string | (number | string)[];
export interface TimeSeriesChartThresholdItem {
id: string;
+ yAxisId: TimeSeriesChartYAxisId;
yAxisIndex: number;
latestDataKey?: DataKey;
units?: string;
@@ -646,14 +761,16 @@ export interface TimeSeriesChartThresholdItem {
export interface TimeSeriesChartYAxis {
id: string;
- units: string;
+ decimals: number;
+ settings: TimeSeriesChartYAxisSettings;
option: YAXisOption & ValueAxisBaseOption;
intervalCalculator?: (axis: Axis2D) => number;
ticksFormatter?: (value: any) => string;
}
-export const createTimeSeriesYAxis = (axisId: string, units: string,
- decimals: number, settings: TimeSeriesChartYAxisSettings,
+export const createTimeSeriesYAxis = (units: string,
+ decimals: number,
+ settings: TimeSeriesChartYAxisSettings,
darkMode: boolean): TimeSeriesChartYAxis => {
const yAxisTickLabelStyle = createChartTextStyle(settings.tickLabelFont,
settings.tickLabelColor, darkMode, 'axis.tickLabel');
@@ -664,13 +781,14 @@ export const createTimeSeriesYAxis = (axisId: string, units: string,
ticksFormatter = parseFunction(settings.ticksFormatter, ['value']);
}
const yAxis: TimeSeriesChartYAxis = {
- id: axisId,
- units,
+ id: settings.id,
+ decimals,
+ settings,
option: {
show: settings.show,
type: 'value',
position: settings.position,
- id: axisId,
+ id: settings.id,
offset: 0,
alignTicks: true,
scale: true,
@@ -843,13 +961,11 @@ const generateChartThresholds = (thresholdItems: TimeSeriesChartThresholdItem[],
id: item.id,
dataGroupId: item.id,
yAxisIndex: item.yAxisIndex,
- animation: true,
data: [],
tooltip: {
show: false
},
markLine: {
- animation: true,
lineStyle: {
width: item.settings.lineWidth,
color: prepareChartThemeColor(item.settings.lineColor, darkMode, 'threshold.line'),
@@ -956,16 +1072,19 @@ const generateChartSeries = (dataItems: TimeSeriesChartDataItem[],
};
export const updateDarkMode = (options: EChartsOption, settings: TimeSeriesChartSettings,
+ yAxisList: TimeSeriesChartYAxis[],
dataItems: TimeSeriesChartDataItem[], thresholdDataItems: TimeSeriesChartThresholdItem[],
darkMode: boolean): EChartsOption => {
options.darkMode = darkMode;
if (Array.isArray(options.yAxis)) {
- for (const yAxis of options.yAxis) {
- yAxis.nameTextStyle.color = prepareChartThemeColor(settings.yAxis.labelColor, darkMode, 'axis.label');
- yAxis.axisLabel.color = prepareChartThemeColor(settings.yAxis.tickLabelColor, darkMode, 'axis.tickLabel');
- yAxis.axisLine.lineStyle.color = prepareChartThemeColor(settings.yAxis.lineColor, darkMode, 'axis.line');
- yAxis.axisTick.lineStyle.color = prepareChartThemeColor(settings.yAxis.ticksColor, darkMode, 'axis.ticks');
- yAxis.splitLine.lineStyle.color = prepareChartThemeColor(settings.yAxis.splitLinesColor, darkMode, 'axis.splitLine');
+ for (let i = 0; i < options.yAxis.length; i++) {
+ const yAxis = options.yAxis[i];
+ const yAxisSettings = yAxisList[i].settings;
+ yAxis.nameTextStyle.color = prepareChartThemeColor(yAxisSettings.labelColor, darkMode, 'axis.label');
+ yAxis.axisLabel.color = prepareChartThemeColor(yAxisSettings.tickLabelColor, darkMode, 'axis.tickLabel');
+ yAxis.axisLine.lineStyle.color = prepareChartThemeColor(yAxisSettings.lineColor, darkMode, 'axis.line');
+ yAxis.axisTick.lineStyle.color = prepareChartThemeColor(yAxisSettings.ticksColor, darkMode, 'axis.ticks');
+ yAxis.splitLine.lineStyle.color = prepareChartThemeColor(yAxisSettings.splitLinesColor, darkMode, 'axis.splitLine');
}
}
if (Array.isArray(options.xAxis)) {
@@ -1032,7 +1151,6 @@ const createTimeSeriesChartSeries = (item: TimeSeriesChartDataItem,
emphasis: {
focus: 'series'
},
- animation: true,
dimensions: [
{name: 'intervalStart', type: 'number'},
{name: 'intervalEnd', type: 'number'}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
index 6d790d5439..abad3f79e8 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
@@ -19,7 +19,7 @@ import {
AxisPosition,
calculateThresholdsOffset,
createTimeSeriesXAxisOption,
- createTimeSeriesYAxis,
+ createTimeSeriesYAxis, defaultTimeSeriesChartYAxisSettings,
generateChartData,
parseThresholdData,
SeriesLabelPosition,
@@ -29,11 +29,11 @@ import {
TimeSeriesChartKeySettings,
TimeSeriesChartSeriesType,
TimeSeriesChartSettings,
- TimeSeriesChartShape,
+ TimeSeriesChartShape, TimeSeriesChartThreshold, timeSeriesChartThresholdDefaultSettings,
TimeSeriesChartThresholdItem,
TimeSeriesChartThresholdType,
TimeSeriesChartType,
- TimeSeriesChartYAxis,
+ TimeSeriesChartYAxis, TimeSeriesChartYAxisId, TimeSeriesChartYAxisSettings,
updateDarkMode
} from '@home/components/widget/lib/chart/time-series-chart.models';
import { ResizeObserver } from '@juggle/resize-observer';
@@ -63,6 +63,7 @@ import { AggregationType } from '@shared/models/time/time.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
import { DataKeySettingsFunction } from '@home/components/widget/config/data-keys.component.models';
+import { DeepPartial } from '@shared/models/common';
export class TbTimeSeriesChart {
@@ -94,9 +95,11 @@ export class TbTimeSeriesChart {
private readonly shapeResize$: ResizeObserver;
+ private readonly settings: TimeSeriesChartSettings;
+
+ private yAxisList: TimeSeriesChartYAxis[] = [];
private dataItems: TimeSeriesChartDataItem[] = [];
private thresholdItems: TimeSeriesChartThresholdItem[] = [];
- private yAxisList: TimeSeriesChartYAxis[] = [];
private timeSeriesChart: ECharts;
private timeSeriesChartOptions: EChartsOption;
@@ -120,13 +123,16 @@ export class TbTimeSeriesChart {
yMax$ = this.yMaxSubject.asObservable();
constructor(private ctx: WidgetContext,
- private readonly settings: TimeSeriesChartSettings,
+ private readonly inputSettings: DeepPartial,
private chartElement: HTMLElement,
private renderer: Renderer2,
private autoResize = true) {
- this.settings = mergeDeep({} as TimeSeriesChartSettings, timeSeriesChartDefaultSettings, this.settings);
+ this.settings = mergeDeep({} as TimeSeriesChartSettings,
+ timeSeriesChartDefaultSettings,
+ this.inputSettings as TimeSeriesChartSettings);
this.darkMode = this.settings.darkMode;
+ this.setupYAxes();
this.setupData();
this.setupThresholds();
if (this.settings.showTooltip && this.settings.tooltipShowDate) {
@@ -258,7 +264,8 @@ export class TbTimeSeriesChart {
if (this.darkMode !== darkMode) {
this.darkMode = darkMode;
if (this.timeSeriesChart) {
- this.timeSeriesChartOptions = updateDarkMode(this.timeSeriesChartOptions, this.settings, this.dataItems,
+ this.timeSeriesChartOptions = updateDarkMode(this.timeSeriesChartOptions,
+ this.settings, this.yAxisList, this.dataItems,
this.thresholdItems, darkMode);
this.timeSeriesChart.setOption(this.timeSeriesChartOptions);
}
@@ -287,11 +294,16 @@ export class TbTimeSeriesChart {
const units = dataKey.units && dataKey.units.length ? dataKey.units : this.ctx.units;
const decimals = isDefinedAndNotNull(dataKey.decimals) ? dataKey.decimals :
(isDefinedAndNotNull(this.ctx.decimals) ? this.ctx.decimals : 2);
+ let yAxisId = keySettings.yAxisId;
+ if (!Object.keys(this.settings.yAxes).includes(yAxisId)) {
+ yAxisId = 'default';
+ }
this.dataItems.push({
id: this.nextComponentId(),
units,
decimals,
- yAxisIndex: this.getYAxis(units, decimals),
+ yAxisId,
+ yAxisIndex: this.getYAxisIndex(yAxisId),
dataKey,
data: namedData,
enabled: !keySettings.dataHiddenByDefault
@@ -303,7 +315,9 @@ export class TbTimeSeriesChart {
private setupThresholds(): void {
const thresholdDatasources: Datasource[] = [];
- for (const threshold of this.settings.thresholds) {
+ for (const thresholdSettings of this.settings.thresholds) {
+ const threshold = mergeDeep({} as TimeSeriesChartThreshold,
+ timeSeriesChartThresholdDefaultSettings, thresholdSettings);
let latestDataKey: DataKey = null;
let entityDataKey: DataKey = null;
let value = null;
@@ -351,11 +365,16 @@ export class TbTimeSeriesChart {
const units = threshold.units && threshold.units.length ? threshold.units : this.ctx.units;
const decimals = isDefinedAndNotNull(threshold.decimals) ? threshold.decimals :
(isDefinedAndNotNull(this.ctx.decimals) ? this.ctx.decimals : 2);
+ let yAxisId = threshold.yAxisId;
+ if (!Object.keys(this.settings.yAxes).includes(yAxisId)) {
+ yAxisId = 'default';
+ }
const thresholdItem: TimeSeriesChartThresholdItem = {
id: this.nextComponentId(),
units,
decimals,
- yAxisIndex: this.getYAxis(units, decimals),
+ yAxisId,
+ yAxisIndex: this.getYAxisIndex(yAxisId),
value,
latestDataKey,
settings: threshold
@@ -368,17 +387,32 @@ export class TbTimeSeriesChart {
this.subscribeForEntityThresholds(thresholdDatasources);
}
+ private setupYAxes(): void {
+ const yAxisSettingsList = Object.values(this.settings.yAxes);
+ yAxisSettingsList.sort((a1, a2) => a1.order - a2.order);
+ for (const yAxisSettings of yAxisSettingsList) {
+ const axisSettings = mergeDeep({} as TimeSeriesChartYAxisSettings,
+ defaultTimeSeriesChartYAxisSettings, yAxisSettings);
+ const units = axisSettings.units && axisSettings.units.length ? axisSettings.units : this.ctx.units;
+ const decimals = isDefinedAndNotNull(axisSettings.decimals) ? axisSettings.decimals :
+ (isDefinedAndNotNull(this.ctx.decimals) ? this.ctx.decimals : 2);
+ const yAxis = createTimeSeriesYAxis(units, decimals, axisSettings, this.darkMode);
+ this.yAxisList.push(yAxis);
+ }
+ }
+
+
private nextComponentId(): string {
return (this.componentIndexCounter++) + '';
}
- private getYAxis(units: string, decimals: number): number {
- let yAxisIndex = this.yAxisList.findIndex(axis => axis.units === units);
+ private getYAxisIndex(id: TimeSeriesChartYAxisId): number {
+ let yAxisIndex = this.yAxisList.findIndex(axis => axis.id === id);
if (yAxisIndex === -1) {
- const yAxisId = this.yAxisList.length + '';
- const yAxis = createTimeSeriesYAxis(yAxisId, units, decimals, this.settings.yAxis, this.darkMode);
- this.yAxisList.push(yAxis);
- yAxisIndex = this.yAxisList.length - 1;
+ yAxisIndex = this.yAxisList.findIndex(axis => axis.id === 'default');
+ if (yAxisIndex === -1 && this.yAxisList.length) {
+ yAxisIndex = 0;
+ }
}
return yAxisIndex;
}
@@ -460,7 +494,15 @@ export class TbTimeSeriesChart {
realtime: true,
bottom: 10
}
- ]
+ ],
+ animation: this.settings.animation.animation,
+ animationThreshold: this.settings.animation.animationThreshold,
+ animationDuration: this.settings.animation.animationDuration,
+ animationEasing: this.settings.animation.animationEasing,
+ animationDelay: this.settings.animation.animationDelay,
+ animationDurationUpdate: this.settings.animation.animationDurationUpdate,
+ animationEasingUpdate: this.settings.animation.animationEasingUpdate,
+ animationDelayUpdate: this.settings.animation.animationDelayUpdate
};
this.timeSeriesChartOptions.xAxis[0].tbTimeWindow = this.ctx.defaultSubscription.timeWindow;
@@ -588,7 +630,7 @@ export class TbTimeSeriesChart {
result.offset += 5;
}
width = newWidth;
- const showLine = !!width && this.settings.yAxis.showLine;
+ const showLine = !!width && yAxis.settings.showLine;
if (yAxis.option.axisLine.show !== showLine) {
yAxis.option.axisLine.show = showLine;
result.changed = true;
@@ -597,7 +639,7 @@ export class TbTimeSeriesChart {
yAxis.option.offset = result.offset;
result.changed = true;
}
- if (this.settings.yAxis.label) {
+ if (yAxis.settings.label) {
if (!width) {
if (yAxis.option.name) {
yAxis.option.name = null;
@@ -605,7 +647,7 @@ export class TbTimeSeriesChart {
}
} else {
if (!yAxis.option.name) {
- yAxis.option.name = this.settings.yAxis.label;
+ yAxis.option.name = yAxis.settings.label;
result.changed = true;
}
const nameGap = width;
@@ -613,7 +655,7 @@ export class TbTimeSeriesChart {
yAxis.option.nameGap = nameGap;
result.changed = true;
}
- const nameWidth = measureYAxisNameWidth(this.timeSeriesChart, yAxis.id, this.settings.yAxis.label);
+ const nameWidth = measureYAxisNameWidth(this.timeSeriesChart, yAxis.id, yAxis.settings.label);
result.offset += nameWidth;
}
}
@@ -623,15 +665,25 @@ export class TbTimeSeriesChart {
}
private scaleYAxis(yAxis: TimeSeriesChartYAxis): boolean {
- const yAxisIndex = this.yAxisList.indexOf(yAxis);
- const axisBarDataItems = this.dataItems.filter(d => d.yAxisIndex === yAxisIndex && d.enabled &&
+ const axisBarDataItems = this.dataItems.filter(d => d.yAxisId === yAxis.id && d.enabled &&
d.data.length && d.dataKey.settings.type === TimeSeriesChartSeriesType.bar);
return !axisBarDataItems.length;
}
+ private yAxisEmpty(yAxis: TimeSeriesChartYAxis): boolean {
+ const axisDataItems = this.dataItems.filter(d => d.yAxisId === yAxis.id && d.enabled &&
+ d.data.length);
+ return !axisDataItems.length;
+ }
+
private calculateYAxisInterval(axisList: TimeSeriesChartYAxis[]): boolean {
let changed = false;
for (const yAxis of axisList) {
+ const minInterval = this.yAxisEmpty(yAxis) ? undefined : (1 / Math.pow(10, yAxis.decimals));
+ if (yAxis.option.minInterval !== minInterval) {
+ yAxis.option.minInterval = minInterval;
+ changed = true;
+ }
if (yAxis.intervalCalculator) {
const axis = getYAxis(this.timeSeriesChart, yAxis.id);
if (axis) {
@@ -649,8 +701,10 @@ export class TbTimeSeriesChart {
}
private minTopOffset(): number {
+ const showTickLabels =
+ !!this.yAxisList.find(yAxis => yAxis.settings.show && yAxis.settings.showTickLabels);
return (this.topPointLabels) ? 20 :
- ((this.settings.yAxis.show && this.settings.yAxis.showTickLabels) ? 10 : 5);
+ (showTickLabels ? 10 : 5);
}
private minBottomOffset(): number {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html
index 0d470703b6..5f0fbb9e37 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html
@@ -29,6 +29,18 @@
+