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 * as moment_ from 'moment';
|
||||
import { DataKeyType } from "@shared/models/telemetry/telemetry.models";
|
||||
|
||||
export declare type ChartType = 'line' | 'pie' | 'bar' | 'state' | 'graph';
|
||||
|
||||
@ -149,13 +150,23 @@ export interface TbFlotThresholdsSettings {
|
||||
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;
|
||||
}
|
||||
|
||||
export declare type BarAlignment = 'left' | 'right' | 'center';
|
||||
|
||||
export interface TbFlotBarSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings {
|
||||
export interface TbFlotBarSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings, TbFlotCustomLegendSettings {
|
||||
defaultBarWidth: number;
|
||||
barAlignment: BarAlignment;
|
||||
}
|
||||
@ -503,13 +514,17 @@ export function flotSettingsSchema(chartType: ChartType): JsonSettingsSchema {
|
||||
GroupTitle: 'Common Settings'
|
||||
}];
|
||||
schema.form = [schema.form];
|
||||
schema.schema.properties = {...schema.schema.properties, ...chartSettingsSchemaForComparison.schema.properties};
|
||||
schema.schema.required = schema.schema.required.concat(chartSettingsSchemaForComparison.schema.required);
|
||||
schema.form.push(chartSettingsSchemaForComparison.form);
|
||||
schema.schema.properties = {...schema.schema.properties, ...chartSettingsSchemaForComparison.schema.properties, ...chartSettingsSchemaForCustomLegend.schema.properties};
|
||||
schema.schema.required = schema.schema.required.concat(chartSettingsSchemaForComparison.schema.required, chartSettingsSchemaForCustomLegend.schema.required);
|
||||
schema.form.push(chartSettingsSchemaForComparison.form, chartSettingsSchemaForCustomLegend.form);
|
||||
schema.groupInfoes.push({
|
||||
formIndex: schema.groupInfoes.length,
|
||||
GroupTitle:'Comparison Settings'
|
||||
});
|
||||
schema.groupInfoes.push({
|
||||
formIndex: schema.groupInfoes.length,
|
||||
GroupTitle:'Custom Legend Settings'
|
||||
});
|
||||
}
|
||||
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 = {
|
||||
schema: {
|
||||
type: 'object',
|
||||
|
||||
@ -16,7 +16,15 @@
|
||||
|
||||
|
||||
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 {
|
||||
DataKey,
|
||||
@ -88,6 +96,9 @@ export class TbFlot {
|
||||
private thresholdsSourcesSubscription: IWidgetSubscription;
|
||||
private predefinedThresholds: TbFlotThresholdMarking[];
|
||||
|
||||
private labelPatternsSourcesSubscription: IWidgetSubscription;
|
||||
private labelPatternsSourcesData: DatasourceData[];
|
||||
|
||||
private plotInited = false;
|
||||
private plot: JQueryPlot;
|
||||
|
||||
@ -369,6 +380,20 @@ export class TbFlot {
|
||||
const yaxesMap: {[units: string]: TbFlotAxisOptions} = {};
|
||||
const predefinedThresholds: TbFlotThresholdMarking[] = [];
|
||||
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;
|
||||
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);
|
||||
@ -569,6 +597,10 @@ export class TbFlot {
|
||||
this.yaxes[yaxisIndex].keysInfo[i].hidden = series.dataKey.hidden;
|
||||
axisVisibilityChanged = true;
|
||||
}
|
||||
|
||||
if (this.labelPatternsSourcesData?.length) {
|
||||
this.substituteLabelPatterns(series, i);
|
||||
}
|
||||
}
|
||||
if (axisVisibilityChanged) {
|
||||
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,
|
||||
units: string, trackDecimals: number, active: boolean,
|
||||
percent: number, valueFormatFunction: TooltipValueFormatFunction): JQuery<HTMLElement> {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user