From 3a8796618b3a6b2dcf312aff76693d9987883f7d Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 4 Jul 2024 19:14:05 +0300 Subject: [PATCH] UI: Improve 'Cross pipe', 'Left/Right tee pipe' SCADA symbols. Improve SCADA symbol behavior settings. --- .../system/scada_symbols/bottom-tee-pipe.svg | 36 ++- .../json/system/scada_symbols/cross-pipe.svg | 295 ++++++++++++----- .../system/scada_symbols/left-tee-pipe.svg | 297 +++++++++++------- .../system/scada_symbols/right-tee-pipe.svg | 226 ++++++++----- .../system/scada_symbols/top-tee-pipe.svg | 42 ++- .../widget/lib/scada/scada-symbol.models.ts | 1 + .../common/action/action-settings-button.scss | 3 +- ...cada-symbol-object-settings.component.html | 92 ++++-- .../scada-symbol-object-settings.component.ts | 15 +- .../scada-symbol-object-settings.models.ts | 34 +- ...scada-symbol-behavior-panel.component.html | 6 + .../scada-symbol-behavior-panel.component.ts | 2 + .../assets/locale/locale.constant-en_US.json | 27 +- 13 files changed, 715 insertions(+), 361 deletions(-) diff --git a/application/src/main/data/json/system/scada_symbols/bottom-tee-pipe.svg b/application/src/main/data/json/system/scada_symbols/bottom-tee-pipe.svg index 92daad863f..55b7bb921c 100644 --- a/application/src/main/data/json/system/scada_symbols/bottom-tee-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/bottom-tee-pipe.svg @@ -43,8 +43,9 @@ "behavior": [ { "id": "horizontalFluid", - "name": "{i18n:scada.symbol.horizontal-fluid-presence}", - "hint": "{i18n:scada.symbol.horizontal-fluid-presence-hint}", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -57,8 +58,9 @@ }, { "id": "horizontalFlow", - "name": "{i18n:scada.symbol.horizontal-flow-presence}", - "hint": "{i18n:scada.symbol.horizontal-flow-presence-hint}", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -71,8 +73,9 @@ }, { "id": "horizontalFlowDirection", - "name": "{i18n:scada.symbol.horizontal-flow-direction}", - "hint": "{i18n:scada.symbol.horizontal-flow-direction-hint}", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -85,8 +88,9 @@ }, { "id": "horizontalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.horizontal-flow-animation-speed}", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -99,8 +103,9 @@ }, { "id": "verticalFluid", - "name": "{i18n:scada.symbol.vertical-fluid-presence}", - "hint": "{i18n:scada.symbol.vertical-fluid-presence-hint}", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -113,8 +118,9 @@ }, { "id": "verticalFlow", - "name": "{i18n:scada.symbol.vertical-flow-presence}", - "hint": "{i18n:scada.symbol.vertical-flow-presence-hint}", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -127,8 +133,9 @@ }, { "id": "verticalFlowDirection", - "name": "{i18n:scada.symbol.vertical-flow-direction}", - "hint": "{i18n:scada.symbol.vertical-flow-direction-hint}", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -141,8 +148,9 @@ }, { "id": "verticalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.vertical-flow-animation-speed}", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, diff --git a/application/src/main/data/json/system/scada_symbols/cross-pipe.svg b/application/src/main/data/json/system/scada_symbols/cross-pipe.svg index b114d812f1..b36b70b865 100644 --- a/application/src/main/data/json/system/scada_symbols/cross-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/cross-pipe.svg @@ -1,23 +1,23 @@ - + { "title": "Cross pipe", - "description": "Cross pipe with configurable horizontal and/or vertical fluid and leak visualizations.", + "description": "Cross pipe with configurable left/right/top/bottom fluid and leak visualizations.", "searchTags": [ "pipe", "cross" ], "widgetSizeX": 1, "widgetSizeY": 1, - "stateRenderFunction": "var horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nif (horizontalLiquidPattern) {\n var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\n var flow = ctx.values.horizontalFlow;\n var flowDirection = ctx.values.horizontalFlowDirection;\n var flowAnimationSpeed = ctx.values.horizontalFlowAnimationSpeed;\n \n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nif (verticalLiquidPattern) {\n var fluid = ctx.values.verticalFluid && !ctx.values.leak;\n var flow = ctx.values.verticalFlow;\n var flowDirection = ctx.values.verticalFlowDirection;\n var flowAnimationSpeed = ctx.values.verticalFlowAnimationSpeed;\n \n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", + "stateRenderFunction": "var leftLiquidPattern = prepareLiquidPattern('left-liquid', 'left-fluid');\nvar rightLiquidPattern = prepareLiquidPattern('right-liquid', 'right-fluid');\nvar topLiquidPattern = prepareLiquidPattern('top-liquid', 'top-fluid');\nvar bottomLiquidPattern = prepareLiquidPattern('bottom-liquid', 'bottom-fluid');\n\nvar genericLiquidPattern = ctx.svg.defs().findOne('pattern#liquid');\nif (genericLiquidPattern) {\n genericLiquidPattern.id(ctx.api.generateElementId());\n leftLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n rightLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n topLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n bottomLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n}\n\nupdateLiquidPatternAnimation(leftLiquidPattern, 'left');\nupdateLiquidPatternAnimation(rightLiquidPattern, 'right');\nupdateLiquidPatternAnimation(topLiquidPattern, 'top');\nupdateLiquidPatternAnimation(bottomLiquidPattern, 'bottom');\n\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, prefix) {\n if (liquidPattern) {\n var fluid = ctx.values[prefix + 'Fluid'] && !ctx.values.leak;\n var flow = ctx.values[prefix + 'Flow'];\n var flowDirection = ctx.values[prefix + 'FlowDirection'];\n var flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", "tags": [ { - "tag": "horizontal-fluid", - "stateRenderFunction": "var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "tag": "bottom-fluid", + "stateRenderFunction": "var fluid = ctx.values.bottomFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "horizontal-fluid-background", - "stateRenderFunction": "var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.horizontalFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "tag": "bottom-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.bottomFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.bottomFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { @@ -25,27 +25,168 @@ "stateRenderFunction": "var leak = ctx.values.leak;\nif (leak) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, + { + "tag": "left-fluid", + "stateRenderFunction": "var fluid = ctx.values.leftFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, + { + "tag": "left-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.leftFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.leftFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, { "tag": "overlay", - "stateRenderFunction": "var fluid = (ctx.values.horizontalFluid || ctx.values.verticalFluid) && !ctx.values.leak;\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "stateRenderFunction": "var fluid = (ctx.values.leftFluid || ctx.values.rightFluid ||\n ctx.values.topFluid || ctx.values.bottomFluid) && !ctx.values.leak;\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, + { + "tag": "right-fluid", + "stateRenderFunction": "var fluid = ctx.values.rightFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, + { + "tag": "right-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.rightFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.rightFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "vertical-fluid", - "stateRenderFunction": "var fluid = ctx.values.verticalFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "tag": "top-fluid", + "stateRenderFunction": "var fluid = ctx.values.topFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "vertical-fluid-background", - "stateRenderFunction": "var fluid = ctx.values.verticalFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.verticalFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "tag": "top-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.topFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.topFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null } ], "behavior": [ { - "id": "horizontalFluid", - "name": "{i18n:scada.symbol.horizontal-fluid-presence}", - "hint": "{i18n:scada.symbol.horizontal-fluid-presence-hint}", + "id": "leftFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.fluid-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "leftFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.flow-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "leftFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": true, + "trueLabel": "{i18n:scada.symbol.forward}", + "falseLabel": "{i18n:scada.symbol.reverse}", + "stateLabel": "{i18n:scada.symbol.forward}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "leftFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", + "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "DOUBLE", + "defaultValue": 1, + "trueLabel": null, + "falseLabel": null, + "stateLabel": null, + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.fluid-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.flow-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": true, + "trueLabel": "{i18n:scada.symbol.forward}", + "falseLabel": "{i18n:scada.symbol.reverse}", + "stateLabel": "{i18n:scada.symbol.forward}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", + "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "DOUBLE", + "defaultValue": 1, + "trueLabel": null, + "falseLabel": null, + "stateLabel": null, + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "topFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -57,9 +198,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlow", - "name": "{i18n:scada.symbol.horizontal-flow-presence}", - "hint": "{i18n:scada.symbol.horizontal-flow-presence-hint}", + "id": "topFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -71,9 +213,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlowDirection", - "name": "{i18n:scada.symbol.horizontal-flow-direction}", - "hint": "{i18n:scada.symbol.horizontal-flow-direction-hint}", + "id": "topFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -85,9 +228,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.horizontal-flow-animation-speed}", + "id": "topFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -99,9 +243,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFluid", - "name": "{i18n:scada.symbol.vertical-fluid-presence}", - "hint": "{i18n:scada.symbol.vertical-fluid-presence-hint}", + "id": "bottomFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -113,9 +258,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlow", - "name": "{i18n:scada.symbol.vertical-flow-presence}", - "hint": "{i18n:scada.symbol.vertical-flow-presence-hint}", + "id": "bottomFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -127,9 +273,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlowDirection", - "name": "{i18n:scada.symbol.vertical-flow-direction}", - "hint": "{i18n:scada.symbol.vertical-flow-direction-hint}", + "id": "bottomFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -141,9 +288,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.vertical-flow-animation-speed}", + "id": "bottomFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -171,8 +319,40 @@ ], "properties": [ { - "id": "horizontalFluidColor", - "name": "{i18n:scada.symbol.horizontal-fluid-color}", + "id": "leftFluidColor", + "name": "{i18n:scada.symbol.left-fluid-color}", + "type": "color", + "default": "#1EC1F480", + "required": null, + "subLabel": null, + "divider": null, + "fieldSuffix": null, + "disableOnProperty": null, + "rowClass": "", + "fieldClass": "", + "min": null, + "max": null, + "step": null + }, + { + "id": "rightFluidColor", + "name": "{i18n:scada.symbol.right-fluid-color}", + "type": "color", + "default": "#1EC1F480", + "required": null, + "subLabel": null, + "divider": null, + "fieldSuffix": null, + "disableOnProperty": null, + "rowClass": "", + "fieldClass": "", + "min": null, + "max": null, + "step": null + }, + { + "id": "topFluidColor", + "name": "{i18n:scada.symbol.top-fluid-color}", "type": "color", "default": "#1EC1F480", "required": null, @@ -187,8 +367,8 @@ "step": null }, { - "id": "verticalFluidColor", - "name": "{i18n:scada.symbol.vertical-fluid-color}", + "id": "bottomFluidColor", + "name": "{i18n:scada.symbol.bottom-fluid-color}", "type": "color", "default": "#1EC1F480", "required": null, @@ -255,7 +435,7 @@ <clipPath id="clip0_1245_66442"> <rect width="200" height="200" fill="#fff"/> </clipPath> - <pattern id="horizontal-liquid" width="172" height="72" patternTransform="translate(14,-8)" patternUnits="userSpaceOnUse"> + <pattern id="liquid" width="172" height="72" patternUnits="userSpaceOnUse"> <circle transform="rotate(-90)" cx="-15" cy="21" r="8" fill="url(#paint28_linear_1182_32781-5)"/> <circle transform="rotate(-90)" cx="-15" cy="150" r="8" fill="url(#paint29_linear_1182_32781-1)"/> <circle transform="rotate(-90)" cx="-16" cy="113" r="8" fill="url(#paint30_linear_1182_32781-7)"/> @@ -406,37 +586,6 @@ <stop stop-color="#727171" offset=".89138"/> <stop stop-color="#727171" offset="1"/> </linearGradient> - <pattern id="vertical-liquid" width="172" height="72" patternTransform="translate(14,8)" patternUnits="userSpaceOnUse"> - <circle transform="rotate(-90)" cx="-15" cy="21" r="8" fill="url(#paint28_linear_1182_32781-5)"/> - <circle transform="rotate(-90)" cx="-15" cy="150" r="8" fill="url(#paint29_linear_1182_32781-1)"/> - <circle transform="rotate(-90)" cx="-16" cy="113" r="8" fill="url(#paint30_linear_1182_32781-7)"/> - <circle transform="rotate(-90)" cx="-58" cy="34" r="8" fill="url(#paint31_linear_1182_32781-4)"/> - <circle transform="rotate(-90)" cx="-58" cy="155" r="8" fill="url(#paint32_linear_1182_32781-3)"/> - <circle transform="rotate(-90)" cx="-26" cy="33" r="5" fill="url(#paint33_linear_1182_32781-1)"/> - <circle transform="rotate(-90)" cx="-26" cy="162" r="5" fill="url(#paint34_linear_1182_32781-4)"/> - <circle transform="rotate(-90)" cx="-37" cy="5" r="5" fill="url(#paint35_linear_1182_32781-6)"/> - <circle transform="rotate(-90)" cx="-8" cy="94" r="4" fill="url(#paint36_linear_1182_32781-9)"/> - <circle transform="rotate(-90)" cx="-60" cy="72" r="4" fill="url(#paint37_linear_1182_32781-4)"/> - <circle transform="rotate(-90)" cx="-37" cy="112" r="5" fill="url(#paint38_linear_1182_32781-2)"/> - <circle transform="rotate(-90)" cx="-39" cy="59" r="5" fill="url(#paint39_linear_1182_32781-2)"/> - <circle transform="rotate(-90)" cx="-62" cy="115" r="5" fill="url(#paint40_linear_1182_32781-6)"/> - <circle transform="rotate(-90)" cx="-42" cy="139" r="5" fill="url(#paint41_linear_1182_32781-4)"/> - <circle transform="rotate(-90)" cx="-21" cy="76" r="5" fill="url(#paint42_linear_1182_32781-1)"/> - <circle transform="rotate(-90)" cx="-50.5" cy="126.5" r="2.5" fill="url(#paint43_linear_1182_32781-2)"/> - <circle transform="rotate(-90)" cx="-46.5" cy="169.5" r="2.5" fill="url(#paint44_linear_1182_32781-8)"/> - <circle transform="rotate(-90)" cx="-9.5" cy="57.5" r="2.5" fill="url(#paint45_linear_1182_32781-8)"/> - <circle transform="rotate(-90)" cx="-35.5" cy="96.5" r="2.5" fill="url(#paint46_linear_1182_32781-9)"/> - <circle transform="rotate(-90)" cx="-23.5" cy="91.5" r="2.5" fill="url(#paint47_linear_1182_32781-2)"/> - <circle transform="rotate(-90)" cx="-40.5" cy="22.5" r="2.5" fill="url(#paint48_linear_1182_32781-88)"/> - <circle transform="rotate(-90)" cx="-23.5" cy="124.5" r="2.5" fill="url(#paint49_linear_1182_32781-8)"/> - <circle transform="rotate(-90)" cx="-47.5" cy="86.5" r="2.5" fill="url(#paint50_linear_1182_32781-6)"/> - <circle transform="rotate(-90)" cx="-21.5" cy="51.5" r="2.5" fill="url(#paint51_linear_1182_32781-8)"/> - <circle transform="rotate(-90)" cx="-51.5" cy="48.5" r="2.5" fill="url(#paint52_linear_1182_32781-3)"/> - <circle transform="rotate(-90)" cx="-64" cy="14" r="4" fill="url(#paint53_linear_1182_32781-83)"/> - <circle transform="rotate(-90)" cx="-64" cy="135" r="4" fill="url(#paint54_linear_1182_32781-33)"/> - <circle transform="rotate(-90)" cx="-58.5" cy="95.5" r="9.5" fill="url(#paint55_linear_1182_32781-8)"/> - <path d="m0 0h172v72h-172z" fill="url(#paint84_linear_1182_32781-8)" stroke-width=".57735"/> - </pattern> <clipPath id="clipPath13372"> <rect width="200" height="200" fill="#fff"/> </clipPath> @@ -506,7 +655,11 @@ <stop stop-color="#727171" stop-opacity=".35" offset=".71855"/> <stop stop-color="#727171" offset="1"/> </linearGradient> - </defs><rect x="14" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid-background"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="vertical-fluid-background"/><rect transform="rotate(90)" x="136" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="vertical-fluid-background"/><rect x="136" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid-background"/><rect x="14" y="64" width="50" height="72" fill="url(#horizontal-liquid)" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid"/><rect x="136" y="64" width="50" height="72" fill="url(#horizontal-liquid)" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="url(#vertical-liquid)" stroke-width="0" style="display: none;" tb:tag="vertical-fluid"/><rect transform="rotate(90)" x="136" y="-136" width="50" height="72" fill="url(#vertical-liquid)" stroke-width="0" style="display: none;" tb:tag="vertical-fluid"/><g transform="translate(64 64)" style="display: none;" tb:tag="overlay"> + <pattern id="left-liquid" patternTransform="translate(14,-8)" patternUnits="userSpaceOnUse" xlink:href="#liquid"/> + <pattern id="right-liquid" patternTransform="translate(14,-8)" patternUnits="userSpaceOnUse" xlink:href="#liquid"/> + <pattern id="top-liquid" patternTransform="translate(14,8)" patternUnits="userSpaceOnUse" xlink:href="#liquid"/> + <pattern id="bottom-liquid" patternTransform="translate(14,8)" patternUnits="userSpaceOnUse" xlink:href="#liquid"/> + </defs><rect x="14" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="left-fluid-background"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="top-fluid-background"/><rect transform="rotate(90)" x="136" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="bottom-fluid-background"/><rect x="136" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="right-fluid-background"/><rect x="14" y="64" width="50" height="72" fill="url(#left-liquid)" stroke-width="0" style="display: none;" tb:tag="left-fluid"/><rect x="136" y="64" width="50" height="72" fill="url(#right-liquid)" stroke-width="0" style="display: none;" tb:tag="right-fluid"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="url(#top-liquid)" stroke-width="0" style="display: none;" tb:tag="top-fluid"/><rect transform="rotate(90)" x="136" y="-136" width="50" height="72" fill="url(#bottom-liquid)" stroke-width="0" style="display: none;" tb:tag="bottom-fluid"/><g transform="translate(64 64)" style="display: none;" tb:tag="overlay"> <path d="m0 72 36-36-36-36z" fill="#fff" style=""/> <path d="m0 72 36-36-36-36z" fill="url(#paint0_linear_1281_37969)" style="fill: url(&quot;#paint0_linear_1281_37969&quot;);"/> <path d="m1.5 3.6213v64.757l32.379-32.379z" stroke="#000" stroke-opacity=".12" stroke-width="3" style=""/> diff --git a/application/src/main/data/json/system/scada_symbols/left-tee-pipe.svg b/application/src/main/data/json/system/scada_symbols/left-tee-pipe.svg index 29bf2e48c2..43106f9791 100644 --- a/application/src/main/data/json/system/scada_symbols/left-tee-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/left-tee-pipe.svg @@ -1,22 +1,23 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"><tb:metadata xmlns=""><![CDATA[{ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"> +<tb:metadata xmlns=""><![CDATA[{ "title": "Left tee pipe", - "description": "Left tee pipe with configurable horizontal and/or vertical fluid and leak visualizations.", + "description": "Left tee pipe with configurable left/top/bottom fluid and leak visualizations.", "searchTags": [ "pipe", "tee" ], "widgetSizeX": 1, "widgetSizeY": 1, - "stateRenderFunction": "var horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nif (horizontalLiquidPattern) {\n var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\n var flow = ctx.values.horizontalFlow;\n var flowDirection = ctx.values.horizontalFlowDirection;\n var flowAnimationSpeed = ctx.values.horizontalFlowAnimationSpeed;\n \n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nif (verticalLiquidPattern) {\n var fluid = ctx.values.verticalFluid && !ctx.values.leak;\n var flow = ctx.values.verticalFlow;\n var flowDirection = ctx.values.verticalFlowDirection;\n var flowAnimationSpeed = ctx.values.verticalFlowAnimationSpeed;\n \n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", + "stateRenderFunction": "var leftLiquidPattern = prepareLiquidPattern('left-liquid', 'left-fluid');\nvar topLiquidPattern = prepareLiquidPattern('top-liquid', 'top-fluid');\nvar bottomLiquidPattern = prepareLiquidPattern('bottom-liquid', 'bottom-fluid');\n\nvar genericLiquidPattern = ctx.svg.defs().findOne('pattern#liquid');\nif (genericLiquidPattern) {\n genericLiquidPattern.id(ctx.api.generateElementId());\n leftLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n topLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n bottomLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n}\n\nupdateLiquidPatternAnimation(leftLiquidPattern, 'left');\nupdateLiquidPatternAnimation(topLiquidPattern, 'top');\nupdateLiquidPatternAnimation(bottomLiquidPattern, 'bottom');\n\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, prefix) {\n if (liquidPattern) {\n var fluid = ctx.values[prefix + 'Fluid'] && !ctx.values.leak;\n var flow = ctx.values[prefix + 'Flow'];\n var flowDirection = ctx.values[prefix + 'FlowDirection'];\n var flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", "tags": [ { - "tag": "horizontal-fluid", - "stateRenderFunction": "var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "tag": "bottom-fluid", + "stateRenderFunction": "var fluid = ctx.values.bottomFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "horizontal-fluid-background", - "stateRenderFunction": "var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.horizontalFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "tag": "bottom-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.bottomFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.bottomFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { @@ -24,27 +25,98 @@ "stateRenderFunction": "var leak = ctx.values.leak;\nif (leak) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, + { + "tag": "left-fluid", + "stateRenderFunction": "var fluid = ctx.values.leftFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, + { + "tag": "left-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.leftFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.leftFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, { "tag": "overlay", - "stateRenderFunction": "var fluid = (ctx.values.horizontalFluid || ctx.values.verticalFluid) && !ctx.values.leak;\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "stateRenderFunction": "var fluid = (ctx.values.leftFluid ||\n ctx.values.topFluid || ctx.values.bottomFluid) && !ctx.values.leak;\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "vertical-fluid", - "stateRenderFunction": "var fluid = ctx.values.verticalFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "tag": "top-fluid", + "stateRenderFunction": "var fluid = ctx.values.topFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "vertical-fluid-background", - "stateRenderFunction": "var fluid = ctx.values.verticalFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.verticalFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "tag": "top-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.topFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.topFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null } ], "behavior": [ { - "id": "horizontalFluid", - "name": "{i18n:scada.symbol.horizontal-fluid-presence}", - "hint": "{i18n:scada.symbol.horizontal-fluid-presence-hint}", + "id": "leftFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.fluid-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "leftFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.flow-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "leftFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": true, + "trueLabel": "{i18n:scada.symbol.forward}", + "falseLabel": "{i18n:scada.symbol.reverse}", + "stateLabel": "{i18n:scada.symbol.forward}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "leftFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", + "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.left-pipe}", + "type": "value", + "valueType": "DOUBLE", + "defaultValue": 1, + "trueLabel": null, + "falseLabel": null, + "stateLabel": null, + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "topFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -56,9 +128,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlow", - "name": "{i18n:scada.symbol.horizontal-flow-presence}", - "hint": "{i18n:scada.symbol.horizontal-flow-presence-hint}", + "id": "topFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -70,9 +143,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlowDirection", - "name": "{i18n:scada.symbol.horizontal-flow-direction}", - "hint": "{i18n:scada.symbol.horizontal-flow-direction-hint}", + "id": "topFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -84,9 +158,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.horizontal-flow-animation-speed}", + "id": "topFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -98,9 +173,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFluid", - "name": "{i18n:scada.symbol.vertical-fluid-presence}", - "hint": "{i18n:scada.symbol.vertical-fluid-presence-hint}", + "id": "bottomFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -112,9 +188,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlow", - "name": "{i18n:scada.symbol.vertical-flow-presence}", - "hint": "{i18n:scada.symbol.vertical-flow-presence-hint}", + "id": "bottomFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -126,9 +203,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlowDirection", - "name": "{i18n:scada.symbol.vertical-flow-direction}", - "hint": "{i18n:scada.symbol.vertical-flow-direction-hint}", + "id": "bottomFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -140,9 +218,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.vertical-flow-animation-speed}", + "id": "bottomFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -170,8 +249,8 @@ ], "properties": [ { - "id": "horizontalFluidColor", - "name": "{i18n:scada.symbol.horizontal-fluid-color}", + "id": "leftFluidColor", + "name": "{i18n:scada.symbol.left-fluid-color}", "type": "color", "default": "#1EC1F480", "required": null, @@ -186,8 +265,24 @@ "step": null }, { - "id": "verticalFluidColor", - "name": "{i18n:scada.symbol.vertical-fluid-color}", + "id": "topFluidColor", + "name": "{i18n:scada.symbol.top-fluid-color}", + "type": "color", + "default": "#1EC1F480", + "required": null, + "subLabel": null, + "divider": null, + "fieldSuffix": null, + "disableOnProperty": null, + "rowClass": "", + "fieldClass": "", + "min": null, + "max": null, + "step": null + }, + { + "id": "bottomFluidColor", + "name": "{i18n:scada.symbol.bottom-fluid-color}", "type": "color", "default": "#1EC1F480", "required": null, @@ -202,20 +297,18 @@ "step": null } ] -} - - - - - - - - - - - - - +}]]> + + + + + + + + + + + @@ -224,7 +317,7 @@ - + @@ -233,10 +326,7 @@ - - - - + @@ -387,37 +477,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -494,37 +559,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/src/main/data/json/system/scada_symbols/right-tee-pipe.svg b/application/src/main/data/json/system/scada_symbols/right-tee-pipe.svg index 1512ce3e67..05a8c3cc67 100644 --- a/application/src/main/data/json/system/scada_symbols/right-tee-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/right-tee-pipe.svg @@ -1,22 +1,23 @@ -{ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"> +<tb:metadata xmlns=""><![CDATA[{ "title": "Right tee pipe", - "description": "Right tee pipe with configurable horizontal and/or vertical fluid and leak visualizations.", + "description": "Right tee pipe with configurable right/top/bottom fluid and leak visualizations.", "searchTags": [ "pipe", "tee" ], "widgetSizeX": 1, "widgetSizeY": 1, - "stateRenderFunction": "var horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nif (horizontalLiquidPattern) {\n var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\n var flow = ctx.values.horizontalFlow;\n var flowDirection = ctx.values.horizontalFlowDirection;\n var flowAnimationSpeed = ctx.values.horizontalFlowAnimationSpeed;\n \n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nif (verticalLiquidPattern) {\n var fluid = ctx.values.verticalFluid && !ctx.values.leak;\n var flow = ctx.values.verticalFlow;\n var flowDirection = ctx.values.verticalFlowDirection;\n var flowAnimationSpeed = ctx.values.verticalFlowAnimationSpeed;\n \n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", + "stateRenderFunction": "var rightLiquidPattern = prepareLiquidPattern('right-liquid', 'right-fluid');\nvar topLiquidPattern = prepareLiquidPattern('top-liquid', 'top-fluid');\nvar bottomLiquidPattern = prepareLiquidPattern('bottom-liquid', 'bottom-fluid');\n\nvar genericLiquidPattern = ctx.svg.defs().findOne('pattern#liquid');\nif (genericLiquidPattern) {\n genericLiquidPattern.id(ctx.api.generateElementId());\n rightLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n topLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n bottomLiquidPattern.attr({'xlink:href': '#'+genericLiquidPattern.id()});\n}\n\nupdateLiquidPatternAnimation(rightLiquidPattern, 'right');\nupdateLiquidPatternAnimation(topLiquidPattern, 'top');\nupdateLiquidPatternAnimation(bottomLiquidPattern, 'bottom');\n\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, prefix) {\n if (liquidPattern) {\n var fluid = ctx.values[prefix + 'Fluid'] && !ctx.values.leak;\n var flow = ctx.values[prefix + 'Flow'];\n var flowDirection = ctx.values[prefix + 'FlowDirection'];\n var flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", "tags": [ { - "tag": "horizontal-fluid", - "stateRenderFunction": "var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "tag": "bottom-fluid", + "stateRenderFunction": "var fluid = ctx.values.bottomFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "horizontal-fluid-background", - "stateRenderFunction": "var fluid = ctx.values.horizontalFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.horizontalFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "tag": "bottom-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.bottomFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.bottomFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { @@ -26,25 +27,96 @@ }, { "tag": "overlay", - "stateRenderFunction": "var fluid = (ctx.values.horizontalFluid || ctx.values.verticalFluid) && !ctx.values.leak;\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "stateRenderFunction": "var fluid = (ctx.values.rightFluid ||\n ctx.values.topFluid || ctx.values.bottomFluid) && !ctx.values.leak;\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "vertical-fluid", - "stateRenderFunction": "var fluid = ctx.values.verticalFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "tag": "right-fluid", + "stateRenderFunction": "var fluid = ctx.values.rightFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", "actions": null }, { - "tag": "vertical-fluid-background", - "stateRenderFunction": "var fluid = ctx.values.verticalFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.verticalFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "tag": "right-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.rightFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.rightFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, + { + "tag": "top-fluid", + "stateRenderFunction": "var fluid = ctx.values.topFluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}", + "actions": null + }, + { + "tag": "top-fluid-background", + "stateRenderFunction": "var fluid = ctx.values.topFluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.topFluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", "actions": null } ], "behavior": [ { - "id": "horizontalFluid", - "name": "{i18n:scada.symbol.horizontal-fluid-presence}", - "hint": "{i18n:scada.symbol.horizontal-fluid-presence-hint}", + "id": "rightFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.fluid-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": false, + "trueLabel": "{i18n:scada.symbol.present}", + "falseLabel": "{i18n:scada.symbol.absent}", + "stateLabel": "{i18n:scada.symbol.flow-present}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "BOOLEAN", + "defaultValue": true, + "trueLabel": "{i18n:scada.symbol.forward}", + "falseLabel": "{i18n:scada.symbol.reverse}", + "stateLabel": "{i18n:scada.symbol.forward}", + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "rightFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", + "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.right-pipe}", + "type": "value", + "valueType": "DOUBLE", + "defaultValue": 1, + "trueLabel": null, + "falseLabel": null, + "stateLabel": null, + "valueToDataType": "CONSTANT", + "constantValue": false, + "valueToDataFunction": "" + }, + { + "id": "topFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -56,9 +128,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlow", - "name": "{i18n:scada.symbol.horizontal-flow-presence}", - "hint": "{i18n:scada.symbol.horizontal-flow-presence-hint}", + "id": "topFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -70,9 +143,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlowDirection", - "name": "{i18n:scada.symbol.horizontal-flow-direction}", - "hint": "{i18n:scada.symbol.horizontal-flow-direction-hint}", + "id": "topFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -84,9 +158,10 @@ "valueToDataFunction": "" }, { - "id": "horizontalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.horizontal-flow-animation-speed}", + "id": "topFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.top-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -98,9 +173,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFluid", - "name": "{i18n:scada.symbol.vertical-fluid-presence}", - "hint": "{i18n:scada.symbol.vertical-fluid-presence-hint}", + "id": "bottomFluid", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -112,9 +188,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlow", - "name": "{i18n:scada.symbol.vertical-flow-presence}", - "hint": "{i18n:scada.symbol.vertical-flow-presence-hint}", + "id": "bottomFlow", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -126,9 +203,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlowDirection", - "name": "{i18n:scada.symbol.vertical-flow-direction}", - "hint": "{i18n:scada.symbol.vertical-flow-direction-hint}", + "id": "bottomFlowDirection", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -140,9 +218,10 @@ "valueToDataFunction": "" }, { - "id": "verticalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.vertical-flow-animation-speed}", + "id": "bottomFlowAnimationSpeed", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.bottom-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -170,8 +249,8 @@ ], "properties": [ { - "id": "horizontalFluidColor", - "name": "{i18n:scada.symbol.horizontal-fluid-color}", + "id": "rightFluidColor", + "name": "{i18n:scada.symbol.right-fluid-color}", "type": "color", "default": "#1EC1F480", "required": null, @@ -186,8 +265,24 @@ "step": null }, { - "id": "verticalFluidColor", - "name": "{i18n:scada.symbol.vertical-fluid-color}", + "id": "topFluidColor", + "name": "{i18n:scada.symbol.top-fluid-color}", + "type": "color", + "default": "#1EC1F480", + "required": null, + "subLabel": null, + "divider": null, + "fieldSuffix": null, + "disableOnProperty": null, + "rowClass": "", + "fieldClass": "", + "min": null, + "max": null, + "step": null + }, + { + "id": "bottomFluidColor", + "name": "{i18n:scada.symbol.bottom-fluid-color}", "type": "color", "default": "#1EC1F480", "required": null, @@ -202,22 +297,18 @@ "step": null } ] -} - +}]]> - + - + - - - - + @@ -226,7 +317,7 @@ - + @@ -235,7 +326,7 @@ - + @@ -386,37 +477,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -481,7 +547,7 @@ - + diff --git a/application/src/main/data/json/system/scada_symbols/top-tee-pipe.svg b/application/src/main/data/json/system/scada_symbols/top-tee-pipe.svg index 96256e7105..497a9ba9a2 100644 --- a/application/src/main/data/json/system/scada_symbols/top-tee-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/top-tee-pipe.svg @@ -1,4 +1,5 @@ -{ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"> +<tb:metadata xmlns=""><![CDATA[{ "title": "Top tee pipe", "description": "Top tee pipe with configurable horizontal and/or vertical fluid and leak visualizations.", "searchTags": [ @@ -43,8 +44,9 @@ "behavior": [ { "id": "horizontalFluid", - "name": "{i18n:scada.symbol.horizontal-fluid-presence}", - "hint": "{i18n:scada.symbol.horizontal-fluid-presence-hint}", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -57,8 +59,9 @@ }, { "id": "horizontalFlow", - "name": "{i18n:scada.symbol.horizontal-flow-presence}", - "hint": "{i18n:scada.symbol.horizontal-flow-presence-hint}", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -71,8 +74,9 @@ }, { "id": "horizontalFlowDirection", - "name": "{i18n:scada.symbol.horizontal-flow-direction}", - "hint": "{i18n:scada.symbol.horizontal-flow-direction-hint}", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -85,8 +89,9 @@ }, { "id": "horizontalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.horizontal-flow-animation-speed}", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.horizontal-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -99,8 +104,9 @@ }, { "id": "verticalFluid", - "name": "{i18n:scada.symbol.vertical-fluid-presence}", - "hint": "{i18n:scada.symbol.vertical-fluid-presence-hint}", + "name": "{i18n:scada.symbol.fluid-presence}", + "hint": "{i18n:scada.symbol.fluid-presence-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -113,8 +119,9 @@ }, { "id": "verticalFlow", - "name": "{i18n:scada.symbol.vertical-flow-presence}", - "hint": "{i18n:scada.symbol.vertical-flow-presence-hint}", + "name": "{i18n:scada.symbol.flow-presence}", + "hint": "{i18n:scada.symbol.flow-presence-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": false, @@ -127,8 +134,9 @@ }, { "id": "verticalFlowDirection", - "name": "{i18n:scada.symbol.vertical-flow-direction}", - "hint": "{i18n:scada.symbol.vertical-flow-direction-hint}", + "name": "{i18n:scada.symbol.flow-direction}", + "hint": "{i18n:scada.symbol.flow-direction-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "BOOLEAN", "defaultValue": true, @@ -141,8 +149,9 @@ }, { "id": "verticalFlowAnimationSpeed", - "name": "{i18n:scada.symbol.vertical-flow-animation-speed}", + "name": "{i18n:scada.symbol.flow-animation-speed}", "hint": "{i18n:scada.symbol.flow-animation-speed-hint}", + "group": "{i18n:scada.symbol.vertical-pipe}", "type": "value", "valueType": "DOUBLE", "defaultValue": 1, @@ -202,8 +211,7 @@ "step": null } ] -} - +}]]> diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts index 47de450351..a3810d4f3b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts @@ -106,6 +106,7 @@ export interface ScadaSymbolBehaviorBase { id: string; name: string; hint?: string; + group?: string; type: ScadaSymbolBehaviorType; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.scss index 683b2320f4..2aa2b28bfe 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.scss @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -.mdc-button.tb-action-settings-button { +.mdc-button.mat-mdc-outlined-button.mat-mdc-button-base.tb-action-settings-button { width: 100%; + height: 40px; .mdc-button__label { width: 100%; & > div { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.html index 1271f8b4bb..53d021ccf4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.html @@ -16,39 +16,25 @@ --> -
+
scada.behavior.behavior
-
-
{{ behavior.name | customTranslate }}
- - - - - - -
+ +
+ + + +
{{ behaviorGroup.title | customTranslate }}
+
+
+ + + +
+
+ + + +
widget-config.appearance
@@ -99,3 +85,45 @@
+ + + + + + + + + +
+
{{ behavior.name | customTranslate }}
+ + + + + + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.ts index 80f2ef8a74..b521f1af89 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.component.ts @@ -14,16 +14,7 @@ /// limitations under the License. /// -import { - ChangeDetectorRef, - Component, - forwardRef, - Input, - OnChanges, - OnInit, - SimpleChanges, - ViewEncapsulation -} from '@angular/core'; +import { ChangeDetectorRef, Component, forwardRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { ControlValueAccessor, NG_VALIDATORS, @@ -49,7 +40,9 @@ import { IAliasController } from '@core/api/widget-api.models'; import { TargetDevice, widgetType } from '@shared/models/widget.models'; import { isDefinedAndNotNull, mergeDeep } from '@core/utils'; import { + ScadaSymbolBehaviorGroup, ScadaSymbolPropertyRow, + toBehaviorGroups, toPropertyRows } from '@home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.models'; import { merge, Observable, of, Subscription } from 'rxjs'; @@ -114,6 +107,7 @@ export class ScadaSymbolObjectSettingsComponent implements OnInit, OnChanges, Co public scadaSymbolObjectSettingsFormGroup: UntypedFormGroup; metadata: ScadaSymbolMetadata; + behaviorGroups: ScadaSymbolBehaviorGroup[]; propertyRows: ScadaSymbolPropertyRow[]; constructor(protected store: Store, @@ -201,6 +195,7 @@ export class ScadaSymbolObjectSettingsComponent implements OnInit, OnChanges, Co metadata$.subscribe( (metadata) => { this.metadata = metadata; + this.behaviorGroups = toBehaviorGroups(this.metadata.behavior); this.propertyRows = toPropertyRows(this.metadata.properties); const behaviorFormGroup = this.scadaSymbolObjectSettingsFormGroup.get('behavior') as UntypedFormGroup; for (const control of Object.keys(behaviorFormGroup.controls)) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.models.ts index 60cef4fe95..b884166cd2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/scada/scada-symbol-object-settings.models.ts @@ -14,7 +14,16 @@ /// limitations under the License. /// -import { ScadaSymbolProperty, ScadaSymbolPropertyType } from '@home/components/widget/lib/scada/scada-symbol.models'; +import { + ScadaSymbolBehavior, + ScadaSymbolProperty, + ScadaSymbolPropertyType +} from '@home/components/widget/lib/scada/scada-symbol.models'; + +export interface ScadaSymbolBehaviorGroup { + title?: string; + behaviors: ScadaSymbolBehavior[]; +} export interface ScadaSymbolPropertyRow { label: string; @@ -23,6 +32,29 @@ export interface ScadaSymbolPropertyRow { rowClass?: string; } +export const toBehaviorGroups = (behaviors: ScadaSymbolBehavior[]): ScadaSymbolBehaviorGroup[] => { + const result: ScadaSymbolBehaviorGroup[] = []; + for (const behavior of behaviors) { + if (!behavior.group) { + result.push({ + title: null, + behaviors: [behavior] + }); + } else { + let behaviorGroup = result.find(g => g.title === behavior.group); + if (!behaviorGroup) { + behaviorGroup = { + title: behavior.group, + behaviors: [] + }; + result.push(behaviorGroup); + } + behaviorGroup.behaviors.push(behavior); + } + } + return result; +}; + export const toPropertyRows = (properties: ScadaSymbolProperty[]): ScadaSymbolPropertyRow[] => { const result: ScadaSymbolPropertyRow[] = []; for (const property of properties) { diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.html b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.html index c0c1ab328f..749b6cf362 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.html +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.html @@ -36,6 +36,12 @@ +
+
scada.behavior.group-title
+ + + +
scada.behavior.type
diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.ts b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.ts index 9d21620ed4..500cd4a454 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.ts +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-panel.component.ts @@ -81,6 +81,7 @@ export class ScadaSymbolBehaviorPanelComponent implements OnInit { id: [this.behavior.id, [Validators.required]], name: [this.behavior.name, [Validators.required]], hint: [this.behavior.hint, []], + group: [this.behavior.group, []], type: [this.behavior.type, [Validators.required]], valueType: [this.behavior.valueType, [Validators.required]], defaultValue: [this.behavior.defaultValue, [Validators.required]], @@ -122,6 +123,7 @@ export class ScadaSymbolBehaviorPanelComponent implements OnInit { this.behaviorFormGroup.get('name').enable({emitEvent: false}); this.behaviorFormGroup.get('type').enable({emitEvent: false}); this.behaviorFormGroup.get('hint').enable({emitEvent: false}); + this.behaviorFormGroup.get('group').enable({emitEvent: false}); switch (type) { case ScadaSymbolBehaviorType.value: this.behaviorFormGroup.get('valueType').enable({emitEvent: false}); diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index f0b4c3af9a..966923bb87 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3506,6 +3506,7 @@ "behavior-settings": "Behavior settings", "remove-behavior": "Remove behavior", "hint": "Hint", + "group-title": "Group title", "value-type": "Value type", "default-value": "Default value", "true-label": "True label", @@ -3565,22 +3566,18 @@ "leak-hint": "Indicates whether is leak present in pipe.", "leak-present": "Leak present", "fluid-color": "Fluid color", - "horizontal-fluid-presence": "Horizontal fluid presence", - "horizontal-fluid-presence-hint": "Indicates whether fluid is present in horizontal pipe.", - "horizontal-flow-presence": "Horizontal flow presence", - "horizontal-flow-presence-hint": "Indicates whether fluid is flowing in horizontal pipe.", - "horizontal-flow-direction": "Horizontal flow direction", - "horizontal-flow-direction-hint": "Indicates fluid flow direction in horizontal pipe.", - "horizontal-flow-animation-speed": "Horizontal flow animation speed", - "vertical-fluid-presence": "Vertical fluid presence", - "vertical-fluid-presence-hint": "Indicates whether fluid is present in vertical pipe.", - "vertical-flow-presence": "Vertical flow presence", - "vertical-flow-presence-hint": "Indicates whether fluid is flowing in vertical pipe.", - "vertical-flow-direction": "Vertical flow direction", - "vertical-flow-direction-hint": "Indicates fluid flow direction in vertical pipe.", - "vertical-flow-animation-speed": "Vertical flow animation speed", + "horizontal-pipe": "Horizontal pipe", + "vertical-pipe": "Vertical pipe", "horizontal-fluid-color": "Horizontal fluid color", - "vertical-fluid-color": "Vertical fluid color" + "vertical-fluid-color": "Vertical fluid color", + "left-pipe": "Left pipe", + "right-pipe": "Right pipe", + "top-pipe": "Top pipe", + "bottom-pipe": "Bottom pipe", + "left-fluid-color": "Left fluid color", + "right-fluid-color": "Right fluid color", + "top-fluid-color": "Top fluid color", + "bottom-fluid-color": "Bottom fluid color" } }, "item": {