Browse Source

UI: Introduce new SCADA symbol property type 'icon'.

pull/11634/head
Igor Kulikov 2 years ago
parent
commit
70de7f4412
  1. 58
      application/src/main/data/json/system/scada_symbols/left-analog-water-level-meter.svg
  2. 60
      application/src/main/data/json/system/scada_symbols/right-analog-water-level-meter.svg
  3. 5
      ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol-widget.component.ts
  4. 72
      ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts
  5. 4
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.html
  6. 4
      ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-property-panel.component.html
  7. 2
      ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-property-row.component.ts
  8. 48
      ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol-editor.models.ts
  9. 1
      ui-ngx/src/assets/locale/locale.constant-en_US.json

58
application/src/main/data/json/system/scada_symbols/left-analog-water-level-meter.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 56 KiB

60
application/src/main/data/json/system/scada_symbols/right-analog-water-level-meter.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 56 KiB

5
ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol-widget.component.ts

@ -40,6 +40,7 @@ import { WidgetComponent } from '@home/components/widget/widget.component';
import { isDefinedAndNotNull, mergeDeep } from '@core/utils';
import { WidgetContext } from '@home/models/widget-component.models';
import { catchError, share } from 'rxjs/operators';
import { MatIconRegistry } from '@angular/material/icon';
@Component({
selector: 'tb-scada-symbol-widget',
@ -75,6 +76,7 @@ export class ScadaSymbolWidgetComponent implements OnInit, AfterViewInit, OnDest
protected imagePipe: ImagePipe,
protected sanitizer: DomSanitizer,
private imageService: ImageService,
private iconRegistry: MatIconRegistry,
protected cd: ChangeDetectorRef) {
}
@ -138,7 +140,8 @@ export class ScadaSymbolWidgetComponent implements OnInit, AfterViewInit, OnDest
this.noScadaSymbol = true;
this.cd.markForCheck();
} else {
this.scadaSymbolObject = new ScadaSymbolObject(rootElement, this.ctx, content,
this.scadaSymbolObject = new ScadaSymbolObject(rootElement, this.ctx, this.iconRegistry,
content,
this.settings.scadaSymbolObjectSettings, this, simulated);
}
}

72
ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts

@ -34,7 +34,7 @@ import {
mergeDeep,
parseFunction
} from '@core/utils';
import { BehaviorSubject, forkJoin, Observable, Observer, Subject } from 'rxjs';
import { BehaviorSubject, forkJoin, Observable, Observer, of, Subject } from 'rxjs';
import { ValueAction, ValueGetter, ValueSetter } from '@home/components/widget/lib/action/action-widget.models';
import { WidgetContext } from '@home/models/widget-component.models';
import { ColorProcessor, constantColor, Font } from '@shared/models/widget-settings.models';
@ -42,13 +42,16 @@ import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
import { UtilsService } from '@core/services/utils.service';
import { WidgetAction, WidgetActionType, widgetActionTypeTranslationMap } from '@shared/models/widget.models';
import { ResizeObserver } from '@juggle/resize-observer';
import { takeUntil } from 'rxjs/operators';
import { catchError, map, take, takeUntil } from 'rxjs/operators';
import { isSvgIcon, splitIconName } from '@shared/models/icon.models';
import { MatIconRegistry } from '@angular/material/icon';
export interface ScadaSymbolApi {
generateElementId: () => string;
formatValue: (value: any, dec?: number, units?: string, showZeroDecimals?: boolean) => string | undefined;
text: (element: Element | Element[], text: string) => void;
font: (element: Element | Element[], font: Font, color: string) => void;
icon: (element: Element | Element[], icon: string, size?: number, color?: string, center?: boolean) => void;
animate: (element: Element, duration: number) => Runner;
resetAnimation: (element: Element) => void;
finishAnimation: (element: Element) => void;
@ -133,7 +136,8 @@ export enum ScadaSymbolPropertyType {
color = 'color',
color_settings = 'color_settings',
font = 'font',
units = 'units'
units = 'units',
icon = 'icon'
}
export const scadaSymbolPropertyTypes = Object.keys(ScadaSymbolPropertyType) as ScadaSymbolPropertyType[];
@ -146,7 +150,8 @@ export const scadaSymbolPropertyTypeTranslations = new Map<ScadaSymbolPropertyTy
[ScadaSymbolPropertyType.color, 'scada.property.type-color'],
[ScadaSymbolPropertyType.color_settings, 'scada.property.type-color-settings'],
[ScadaSymbolPropertyType.font, 'scada.property.type-font'],
[ScadaSymbolPropertyType.units, 'scada.property.type-units']
[ScadaSymbolPropertyType.units, 'scada.property.type-units'],
[ScadaSymbolPropertyType.icon, 'scada.property.type-icon']
]
);
@ -506,6 +511,7 @@ export class ScadaSymbolObject {
constructor(private rootElement: HTMLElement,
private ctx: WidgetContext,
private iconRegistry: MatIconRegistry,
private svgContent: string,
private inputSettings: ScadaSymbolObjectSettings,
private callbacks: ScadaSymbolObjectCallbacks,
@ -609,6 +615,7 @@ export class ScadaSymbolObject {
formatValue,
text: this.setElementText.bind(this),
font: this.setElementFont.bind(this),
icon: this.setElementIcon.bind(this),
animate: this.animate.bind(this),
resetAnimation: this.resetAnimation.bind(this),
finishAnimation: this.finishAnimation.bind(this),
@ -869,6 +876,63 @@ export class ScadaSymbolObject {
});
}
private setElementIcon(e: Element | Element[],
icon: string,
size = 12,
color = '#0000008A',
center = true) {
this.elements(e).forEach(element => {
if (element.type === 'g') {
element.clear();
this.createIconElement(icon, size, color).subscribe((iconElement) => {
if (iconElement) {
element.add(iconElement);
if (center) {
const box = iconElement.bbox();
iconElement.translate(-box.cx, -box.cy);
}
}
});
}
});
}
private createIconElement(icon: string, size: number, color: string): Observable<Element> {
const isSvg = isSvgIcon(icon);
if (isSvg) {
const [namespace, iconName] = splitIconName(icon);
return this.iconRegistry
.getNamedSvgIcon(iconName, namespace)
.pipe(
take(1),
map((svgElement) => {
const element = new Element(svgElement.firstChild);
const box = element.bbox();
const scale = size / box.height;
element.scale(scale);
element.fill(color);
return element;
}),
catchError(() => of(null)
));
} else {
const iconName = splitIconName(icon)[1];
const textElement = this.svgShape.text(iconName);
const fontSetClasses = (
this.iconRegistry.getDefaultFontSetClass()
).filter(className => className.length > 0);
fontSetClasses.forEach(className => textElement.addClass(className));
textElement.font({size});
textElement.attr({
'text-anchor': 'start',
'dominant-baseline': 'hanging',
style: `font-size: ${size}px`
});
textElement.fill(color);
return of(textElement);
}
}
private animate(element: Element, duration: number): Runner {
this.finishAnimation(element);
return element.animate(duration, 0, 'now');

4
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.html

@ -79,6 +79,10 @@
[class]="property.fieldClass"
[required]="property.required"
formControlName="{{ property.id }}"></tb-unit-input>
<tb-material-icon-select *ngIf="property.type === ScadaSymbolPropertyType.icon"
asBoxInput
formControlName="{{ property.id }}">
</tb-material-icon-select>
<mat-divider *ngIf="property.divider" vertical></mat-divider>
</ng-container>
</div>

4
ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-property-panel.component.html

@ -76,6 +76,10 @@
<tb-value-input *ngIf="propertyFormGroup.get('type').value === ScadaSymbolPropertyType.switch"
[valueType]="ValueType.BOOLEAN"
formControlName="default"></tb-value-input>
<tb-material-icon-select *ngIf="propertyFormGroup.get('type').value === ScadaSymbolPropertyType.icon"
asBoxInput
formControlName="default">
</tb-material-icon-select>
</div>
<div *ngIf="propertyFormGroup.get('type').value === ScadaSymbolPropertyType.number" class="tb-form-row space-between">
<div translate>scada.property.number-settings</div>

2
ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-property-row.component.ts

@ -81,6 +81,8 @@ export const defaultPropertyValue = (type: ScadaSymbolPropertyType): any => {
} as Font;
case ScadaSymbolPropertyType.units:
return '';
case ScadaSymbolPropertyType.icon:
return 'star';
}
};

48
ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol-editor.models.ts

@ -491,17 +491,6 @@ export class ScadaSymbolElement {
element.show();
}
this.box = element.rbox(this.editObject.svgShape);
/* if (element.visible()) {
this.box = element.rbox(this.editObject.svgShape);
if (parentGroup && parentGroup.invisible) {
this.invisible = true;
}
} else {
element.show();
this.box = element.rbox(this.editObject.svgShape);
element.hide();
this.invisible = true;
}*/
}
public init() {
@ -1297,6 +1286,41 @@ export const scadaSymbolContextCompletion = (metadata: ScadaSymbolMetadata, tags
}
]
},
icon: {
meta: 'function',
description: 'Draws icon inside element(s). Only applicable for elements of type ' +
'<a href="https://svgjs.dev/docs/3.2/container-elements/#svg-g">SVG.G</a>.',
args: [
{
name: 'element',
description: 'SVG element or an array of SVG elements',
type: 'Element | Array&lt;Element&gt;'
},
{
name: 'icon',
description: 'Icon to draw',
type: 'string'
},
{
name: 'size',
description: 'Optional icon size in pixels. Default 12 pixels.',
type: 'number',
optional: true
},
{
name: 'color',
description: 'Optional icon color. Default #0000008A.',
type: 'string',
optional: true
},
{
name: 'center',
description: 'Whether to center icon inside group element. Default true.',
type: 'boolean',
optional: true
}
]
},
disable: {
meta: 'function',
description: 'Disables element(s). Disabled element doesn\'t accept any user interaction. ' +
@ -1417,6 +1441,8 @@ const scadaSymbolPropertyCompletionType = (type: ScadaSymbolPropertyType): strin
return 'Font';
case ScadaSymbolPropertyType.units:
return 'units string';
case ScadaSymbolPropertyType.icon:
return 'icon string';
}
};

1
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -3746,6 +3746,7 @@
"type-color-settings": "Color settings",
"type-font": "Font",
"type-units": "Units",
"type-icon": "Icon",
"no-properties": "No properties configured",
"add-property": "Add property",
"property-settings": "Property settings",

Loading…
Cancel
Save