Merge pull request #3140 from ChantsovaEkaterina/feature/flot-attributes-usage-in-labels
[3.0] Flot: attributes usage in labels
This commit is contained in:
commit
31aca73e39
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
import { DataKey, Datasource, DatasourceData, JsonSettingsSchema } from '@shared/models/widget.models';
|
import { DataKey, Datasource, DatasourceData, JsonSettingsSchema } from '@shared/models/widget.models';
|
||||||
import * as moment_ from 'moment';
|
import * as moment_ from 'moment';
|
||||||
|
import { DataKeyType } from "@shared/models/telemetry/telemetry.models";
|
||||||
|
|
||||||
export declare type ChartType = 'line' | 'pie' | 'bar' | 'state' | 'graph';
|
export declare type ChartType = 'line' | 'pie' | 'bar' | 'state' | 'graph';
|
||||||
|
|
||||||
@ -149,13 +150,23 @@ export interface TbFlotThresholdsSettings {
|
|||||||
thresholdsLineWidth: number;
|
thresholdsLineWidth: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TbFlotGraphSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings {
|
export interface TbFlotCustomLegendSettings {
|
||||||
|
customLegendEnabled: boolean;
|
||||||
|
dataKeysListForLabels: Array<TbFlotLabelPatternSettings>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TbFlotLabelPatternSettings {
|
||||||
|
name: string;
|
||||||
|
type: DataKeyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TbFlotGraphSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings, TbFlotCustomLegendSettings {
|
||||||
smoothLines: boolean;
|
smoothLines: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare type BarAlignment = 'left' | 'right' | 'center';
|
export declare type BarAlignment = 'left' | 'right' | 'center';
|
||||||
|
|
||||||
export interface TbFlotBarSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings {
|
export interface TbFlotBarSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings, TbFlotCustomLegendSettings {
|
||||||
defaultBarWidth: number;
|
defaultBarWidth: number;
|
||||||
barAlignment: BarAlignment;
|
barAlignment: BarAlignment;
|
||||||
}
|
}
|
||||||
@ -503,13 +514,17 @@ export function flotSettingsSchema(chartType: ChartType): JsonSettingsSchema {
|
|||||||
GroupTitle: 'Common Settings'
|
GroupTitle: 'Common Settings'
|
||||||
}];
|
}];
|
||||||
schema.form = [schema.form];
|
schema.form = [schema.form];
|
||||||
schema.schema.properties = {...schema.schema.properties, ...chartSettingsSchemaForComparison.schema.properties};
|
schema.schema.properties = {...schema.schema.properties, ...chartSettingsSchemaForComparison.schema.properties, ...chartSettingsSchemaForCustomLegend.schema.properties};
|
||||||
schema.schema.required = schema.schema.required.concat(chartSettingsSchemaForComparison.schema.required);
|
schema.schema.required = schema.schema.required.concat(chartSettingsSchemaForComparison.schema.required, chartSettingsSchemaForCustomLegend.schema.required);
|
||||||
schema.form.push(chartSettingsSchemaForComparison.form);
|
schema.form.push(chartSettingsSchemaForComparison.form, chartSettingsSchemaForCustomLegend.form);
|
||||||
schema.groupInfoes.push({
|
schema.groupInfoes.push({
|
||||||
formIndex: schema.groupInfoes.length,
|
formIndex: schema.groupInfoes.length,
|
||||||
GroupTitle:'Comparison Settings'
|
GroupTitle:'Comparison Settings'
|
||||||
});
|
});
|
||||||
|
schema.groupInfoes.push({
|
||||||
|
formIndex: schema.groupInfoes.length,
|
||||||
|
GroupTitle:'Custom Legend Settings'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
@ -603,6 +618,67 @@ const chartSettingsSchemaForComparison: JsonSettingsSchema = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const chartSettingsSchemaForCustomLegend: JsonSettingsSchema = {
|
||||||
|
schema: {
|
||||||
|
title: 'Custom Legend Settings',
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
customLegendEnabled: {
|
||||||
|
title: 'Enable custom legend (this will allow you to use attribute/timeseries values in key labels)',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
dataKeysListForLabels: {
|
||||||
|
title: 'Datakeys list to use in labels',
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
title: 'Key name',
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
title: 'Key type',
|
||||||
|
type: 'string',
|
||||||
|
default: 'attribute'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: [
|
||||||
|
'name'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: []
|
||||||
|
},
|
||||||
|
form: [
|
||||||
|
'customLegendEnabled',
|
||||||
|
{
|
||||||
|
key: 'dataKeysListForLabels',
|
||||||
|
condition: 'model.customLegendEnabled === true',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
key: 'dataKeysListForLabels[].type',
|
||||||
|
type: 'rc-select',
|
||||||
|
multiple: false,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
value: 'attribute',
|
||||||
|
label: 'Attribute'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'timeseries',
|
||||||
|
label: 'Timeseries'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'dataKeysListForLabels[].name'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
export const flotPieSettingsSchema: JsonSettingsSchema = {
|
export const flotPieSettingsSchema: JsonSettingsSchema = {
|
||||||
schema: {
|
schema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
|||||||
@ -16,7 +16,15 @@
|
|||||||
|
|
||||||
|
|
||||||
import { WidgetContext } from '@home/models/widget-component.models';
|
import { WidgetContext } from '@home/models/widget-component.models';
|
||||||
import { deepClone, isDefined, isEqual, isNumber, isUndefined } from '@app/core/utils';
|
import {
|
||||||
|
createLabelFromDatasource,
|
||||||
|
deepClone,
|
||||||
|
insertVariable,
|
||||||
|
isDefined,
|
||||||
|
isEqual,
|
||||||
|
isNumber,
|
||||||
|
isUndefined
|
||||||
|
} from '@app/core/utils';
|
||||||
import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
||||||
import {
|
import {
|
||||||
DataKey,
|
DataKey,
|
||||||
@ -88,6 +96,9 @@ export class TbFlot {
|
|||||||
private thresholdsSourcesSubscription: IWidgetSubscription;
|
private thresholdsSourcesSubscription: IWidgetSubscription;
|
||||||
private predefinedThresholds: TbFlotThresholdMarking[];
|
private predefinedThresholds: TbFlotThresholdMarking[];
|
||||||
|
|
||||||
|
private labelPatternsSourcesSubscription: IWidgetSubscription;
|
||||||
|
private labelPatternsSourcesData: DatasourceData[];
|
||||||
|
|
||||||
private plotInited = false;
|
private plotInited = false;
|
||||||
private plot: JQueryPlot;
|
private plot: JQueryPlot;
|
||||||
|
|
||||||
@ -369,6 +380,20 @@ export class TbFlot {
|
|||||||
const yaxesMap: {[units: string]: TbFlotAxisOptions} = {};
|
const yaxesMap: {[units: string]: TbFlotAxisOptions} = {};
|
||||||
const predefinedThresholds: TbFlotThresholdMarking[] = [];
|
const predefinedThresholds: TbFlotThresholdMarking[] = [];
|
||||||
const thresholdsDatasources: Datasource[] = [];
|
const thresholdsDatasources: Datasource[] = [];
|
||||||
|
if (this.settings.customLegendEnabled) {
|
||||||
|
this.labelPatternsSourcesData = [];
|
||||||
|
const labelPatternsDatasources: Datasource[] = [];
|
||||||
|
subscription.datasources.forEach((item) => {
|
||||||
|
let datasource: Datasource = {
|
||||||
|
type: item.type,
|
||||||
|
entityType: item.entityType,
|
||||||
|
entityId: item.entityId,
|
||||||
|
dataKeys: this.settings.dataKeysListForLabels
|
||||||
|
};
|
||||||
|
labelPatternsDatasources.push(datasource);
|
||||||
|
});
|
||||||
|
this.subscribeForLabelPatternsSources(labelPatternsDatasources);
|
||||||
|
}
|
||||||
|
|
||||||
let tooltipValueFormatFunction: TooltipValueFormatFunction = null;
|
let tooltipValueFormatFunction: TooltipValueFormatFunction = null;
|
||||||
if (this.settings.tooltipValueFormatter && this.settings.tooltipValueFormatter.length) {
|
if (this.settings.tooltipValueFormatter && this.settings.tooltipValueFormatter.length) {
|
||||||
@ -506,6 +531,9 @@ export class TbFlot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.labelPatternsSourcesData?.length) {
|
||||||
|
this.substituteLabelPatterns(series, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.subscribeForThresholdsAttributes(thresholdsDatasources);
|
this.subscribeForThresholdsAttributes(thresholdsDatasources);
|
||||||
@ -569,6 +597,10 @@ export class TbFlot {
|
|||||||
this.yaxes[yaxisIndex].keysInfo[i].hidden = series.dataKey.hidden;
|
this.yaxes[yaxisIndex].keysInfo[i].hidden = series.dataKey.hidden;
|
||||||
axisVisibilityChanged = true;
|
axisVisibilityChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.labelPatternsSourcesData?.length) {
|
||||||
|
this.substituteLabelPatterns(series, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (axisVisibilityChanged) {
|
if (axisVisibilityChanged) {
|
||||||
this.options.yaxes.length = 0;
|
this.options.yaxes.length = 0;
|
||||||
@ -849,6 +881,60 @@ export class TbFlot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private subscribeForLabelPatternsSources(datasources: Datasource[]) {
|
||||||
|
const labelPatternsSourcesSubscriptionOptions: WidgetSubscriptionOptions = {
|
||||||
|
datasources,
|
||||||
|
useDashboardTimewindow: false,
|
||||||
|
type: widgetType.latest,
|
||||||
|
callbacks: {
|
||||||
|
onDataUpdated: (subscription) => {
|
||||||
|
this.labelPatternsParamsDataUpdated(subscription.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.ctx.subscriptionApi.createSubscription(labelPatternsSourcesSubscriptionOptions, true).subscribe(
|
||||||
|
(subscription) => {
|
||||||
|
this.labelPatternsSourcesSubscription = subscription;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private labelPatternsParamsDataUpdated(data: DatasourceData[]) {
|
||||||
|
this.labelPatternsSourcesData = data;
|
||||||
|
for (let i = 0; i < this.subscription.data.length; i++) {
|
||||||
|
const series = this.subscription.data[i] as TbFlotSeries;
|
||||||
|
this.substituteLabelPatterns(series, i);
|
||||||
|
}
|
||||||
|
this.updateData();
|
||||||
|
this.ctx.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private substituteLabelPatterns(series: TbFlotSeries, seriesIndex: number) {
|
||||||
|
let seriesLabelPatternsSourcesData = this.labelPatternsSourcesData.filter((item) => {
|
||||||
|
return item.datasource.entityId === series.datasource.entityId;
|
||||||
|
});
|
||||||
|
let label = createLabelFromDatasource(series.datasource, series.dataKey.pattern);
|
||||||
|
for (let i = 0; i < seriesLabelPatternsSourcesData.length; i++) {
|
||||||
|
let keyData = seriesLabelPatternsSourcesData[i];
|
||||||
|
if (keyData && keyData.data && keyData.data[0]) {
|
||||||
|
let attrValue = keyData.data[0][1];
|
||||||
|
let attrName = keyData.dataKey.name;
|
||||||
|
if (isDefined(attrValue) && (attrValue !== null)) {
|
||||||
|
label = insertVariable(label, attrName, attrValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isDefined(this.subscription.legendData)) {
|
||||||
|
let targetLegendKeyIndex = this.subscription.legendData.keys.findIndex((key) => {
|
||||||
|
return key.dataIndex === seriesIndex;
|
||||||
|
});
|
||||||
|
if (targetLegendKeyIndex !== -1) {
|
||||||
|
this.subscription.legendData.keys[targetLegendKeyIndex].dataKey.label = label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
series.dataKey.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
private seriesInfoDiv(label: string, color: string, value: any,
|
private seriesInfoDiv(label: string, color: string, value: any,
|
||||||
units: string, trackDecimals: number, active: boolean,
|
units: string, trackDecimals: number, active: boolean,
|
||||||
percent: number, valueFormatFunction: TooltipValueFormatFunction): JQuery<HTMLElement> {
|
percent: number, valueFormatFunction: TooltipValueFormatFunction): JQuery<HTMLElement> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user