|
|
@ -1,10 +1,9 @@ |
|
|
<svg width="400" height="200" fill="none" version="1.1" viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg"> |
|
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" width="400" height="200" fill="none" version="1.1" viewBox="0 0 400 200"><tb:metadata xmlns=""><![CDATA[{ |
|
|
<tb:metadata><![CDATA[{ |
|
|
|
|
|
"title": "HP Long horizontal connector", |
|
|
"title": "HP Long horizontal connector", |
|
|
"description": "Long horizontal connector with an optional directional arrow to visually indicate flow.", |
|
|
"description": "Long horizontal connector with an optional directional arrow to visually indicate flow.", |
|
|
"widgetSizeX": 2, |
|
|
"widgetSizeX": 2, |
|
|
"widgetSizeY": 1, |
|
|
"widgetSizeY": 1, |
|
|
"stateRenderFunction": "const {\n flowAnimation,\n arrowDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst animation = ctx.tags.animationGroup[0];\nconst offset = Date.now() % 1000;\nconst duration = 1 / flowAnimationSpeed;\n\nconst prevFlowAnimation = animation.remember('flowAnimation');\nconst prevFlowDirection = animation.remember('flowDirection');\nconst prevFlowDuration = animation.remember('flowDuration');\n\nif (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n} else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n}\n\nfunction animateFlow(offset, flowDirection) {\n animation.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n animation.add(`<path style=\"stroke-dasharray: ${dashArray}; stroke-linecap: ${dashCap}; stroke-dashoffset: 0;\" d=\"${line}\" stroke-miterlimit=\"10\" fill=\"none\" stroke=\"${lineColor}\" stroke-width=\"${lineWidth}\"><animate attributeName=\"stroke-dashoffset\" values=\"${value};0\" dur=\"${duration}s\" begin=\"-${offset}ms\" calcMode=\"linear\" repeatCount=\"indefinite\" /></path>`);\n}\n", |
|
|
"stateRenderFunction": "const {\n flowAnimation,\n arrowDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst lineReversed = 'M 400,100 H 0';\nconst animation = ctx.tags.animationGroup[0];\nconst duration = 1 / flowAnimationSpeed;\n\nlet animateFlow = ctx.api.connectorAnimation(animation);\n\nif (flowAnimation) {\n if (!animateFlow) {\n animateFlow = ctx.api.connectorAnimate(animation, line, lineReversed).flowAppearance(lineWidth, lineColor, dashCap, dashWidth, dashGap).duration(duration).direction(flowDirection).play();\n } else {\n animateFlow.duration(duration).direction(flowDirection).play();\n }\n} else {\n if (animateFlow) {\n animateFlow.finish();\n }\n}\n", |
|
|
"tags": [ |
|
|
"tags": [ |
|
|
{ |
|
|
{ |
|
|
"tag": "arrow", |
|
|
"tag": "arrow", |
|
|
@ -13,7 +12,7 @@ |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"tag": "line", |
|
|
"tag": "line", |
|
|
"stateRenderFunction": "element.stroke(ctx.properties.lineColor);\nif (ctx.properties.mainLine) {\n element.attr({'stroke-width': ctx.properties.mainLineSize});\n} else {\n element.attr({'stroke-width': ctx.properties.secondaryLineSize});\n}", |
|
|
"stateRenderFunction": "element.stroke(ctx.properties.lineColor);\nelement.attr({'stroke-width': ctx.properties.mainLineSize});", |
|
|
"actions": null |
|
|
"actions": null |
|
|
} |
|
|
} |
|
|
], |
|
|
], |
|
|
@ -54,18 +53,18 @@ |
|
|
"defaultWidgetActionSettings": null |
|
|
"defaultWidgetActionSettings": null |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "arrowDirection", |
|
|
"id": "flowAnimation", |
|
|
"name": "{i18n:scada.symbol.arrow-direction}", |
|
|
"name": "{i18n:scada.symbol.flow-animation}", |
|
|
"hint": "{i18n:scada.symbol.arrow-direction-hint}", |
|
|
"hint": "{i18n:scada.symbol.flow-animation-hint}", |
|
|
"group": null, |
|
|
"group": null, |
|
|
"type": "value", |
|
|
"type": "value", |
|
|
"valueType": "BOOLEAN", |
|
|
"valueType": "BOOLEAN", |
|
|
"trueLabel": "{i18n:scada.symbol.forward}", |
|
|
"trueLabel": "{i18n:scada.symbol.present}", |
|
|
"falseLabel": "{i18n:scada.symbol.reverse}", |
|
|
"falseLabel": "{i18n:scada.symbol.absent}", |
|
|
"stateLabel": "{i18n:scada.symbol.forward}", |
|
|
"stateLabel": "{i18n:scada.symbol.flow-present}", |
|
|
"defaultGetValueSettings": { |
|
|
"defaultGetValueSettings": { |
|
|
"action": "DO_NOTHING", |
|
|
"action": "DO_NOTHING", |
|
|
"defaultValue": true, |
|
|
"defaultValue": false, |
|
|
"executeRpc": { |
|
|
"executeRpc": { |
|
|
"method": "getState", |
|
|
"method": "getState", |
|
|
"requestTimeout": 5000, |
|
|
"requestTimeout": 5000, |
|
|
@ -73,34 +72,38 @@ |
|
|
"persistentPollingInterval": 1000 |
|
|
"persistentPollingInterval": 1000 |
|
|
}, |
|
|
}, |
|
|
"getAttribute": { |
|
|
"getAttribute": { |
|
|
"scope": null, |
|
|
"key": "state", |
|
|
"key": "state" |
|
|
"scope": null |
|
|
}, |
|
|
}, |
|
|
"getTimeSeries": { |
|
|
"getTimeSeries": { |
|
|
"key": "state" |
|
|
"key": "state" |
|
|
}, |
|
|
}, |
|
|
|
|
|
"getAlarmStatus": { |
|
|
|
|
|
"severityList": null, |
|
|
|
|
|
"typeList": null |
|
|
|
|
|
}, |
|
|
"dataToValue": { |
|
|
"dataToValue": { |
|
|
"type": "NONE", |
|
|
"type": "NONE", |
|
|
"dataToValueFunction": "/* Should return boolean value */\nreturn data;", |
|
|
"compareToValue": true, |
|
|
"compareToValue": true |
|
|
"dataToValueFunction": "/* Should return boolean value */\nreturn data;" |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
"defaultSetValueSettings": null, |
|
|
"defaultSetValueSettings": null, |
|
|
"defaultWidgetActionSettings": null |
|
|
"defaultWidgetActionSettings": null |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "flowAnimation", |
|
|
"id": "arrowDirection", |
|
|
"name": "{i18n:scada.symbol.flow-animation}", |
|
|
"name": "{i18n:scada.symbol.arrow-direction}", |
|
|
"hint": "{i18n:scada.symbol.flow-animation-hint}", |
|
|
"hint": "{i18n:scada.symbol.arrow-direction-hint}", |
|
|
"group": null, |
|
|
"group": null, |
|
|
"type": "value", |
|
|
"type": "value", |
|
|
"valueType": "BOOLEAN", |
|
|
"valueType": "BOOLEAN", |
|
|
"trueLabel": "{i18n:scada.symbol.present}", |
|
|
"trueLabel": "{i18n:scada.symbol.forward}", |
|
|
"falseLabel": "{i18n:scada.symbol.absent}", |
|
|
"falseLabel": "{i18n:scada.symbol.reverse}", |
|
|
"stateLabel": "{i18n:scada.symbol.flow-present}", |
|
|
"stateLabel": "{i18n:scada.symbol.forward}", |
|
|
"defaultGetValueSettings": { |
|
|
"defaultGetValueSettings": { |
|
|
"action": "DO_NOTHING", |
|
|
"action": "DO_NOTHING", |
|
|
"defaultValue": false, |
|
|
"defaultValue": true, |
|
|
"executeRpc": { |
|
|
"executeRpc": { |
|
|
"method": "getState", |
|
|
"method": "getState", |
|
|
"requestTimeout": 5000, |
|
|
"requestTimeout": 5000, |
|
|
@ -108,20 +111,16 @@ |
|
|
"persistentPollingInterval": 1000 |
|
|
"persistentPollingInterval": 1000 |
|
|
}, |
|
|
}, |
|
|
"getAttribute": { |
|
|
"getAttribute": { |
|
|
"key": "state", |
|
|
"scope": null, |
|
|
"scope": null |
|
|
"key": "state" |
|
|
}, |
|
|
}, |
|
|
"getTimeSeries": { |
|
|
"getTimeSeries": { |
|
|
"key": "state" |
|
|
"key": "state" |
|
|
}, |
|
|
}, |
|
|
"getAlarmStatus": { |
|
|
|
|
|
"severityList": null, |
|
|
|
|
|
"typeList": null |
|
|
|
|
|
}, |
|
|
|
|
|
"dataToValue": { |
|
|
"dataToValue": { |
|
|
"type": "NONE", |
|
|
"type": "NONE", |
|
|
"compareToValue": true, |
|
|
"dataToValueFunction": "/* Should return boolean value */\nreturn data;", |
|
|
"dataToValueFunction": "/* Should return boolean value */\nreturn data;" |
|
|
"compareToValue": true |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
"defaultSetValueSettings": null, |
|
|
"defaultSetValueSettings": null, |
|
|
@ -167,36 +166,13 @@ |
|
|
} |
|
|
} |
|
|
], |
|
|
], |
|
|
"properties": [ |
|
|
"properties": [ |
|
|
{ |
|
|
|
|
|
"id": "mainLine", |
|
|
|
|
|
"name": "{i18n:scada.symbol.main-line}", |
|
|
|
|
|
"type": "switch", |
|
|
|
|
|
"default": true, |
|
|
|
|
|
"disabled": false, |
|
|
|
|
|
"visible": true |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
{ |
|
|
"id": "mainLineSize", |
|
|
"id": "mainLineSize", |
|
|
"name": "{i18n:scada.symbol.line}", |
|
|
"name": "{i18n:scada.symbol.line}", |
|
|
"type": "number", |
|
|
"type": "number", |
|
|
"default": 6, |
|
|
"default": 6, |
|
|
"required": true, |
|
|
"required": true, |
|
|
"subLabel": "Main", |
|
|
"divider": false, |
|
|
"divider": true, |
|
|
|
|
|
"fieldSuffix": "px", |
|
|
|
|
|
"min": 0, |
|
|
|
|
|
"max": 99, |
|
|
|
|
|
"step": 1, |
|
|
|
|
|
"disabled": false, |
|
|
|
|
|
"visible": true |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
"id": "secondaryLineSize", |
|
|
|
|
|
"name": "{i18n:scada.symbol.line}", |
|
|
|
|
|
"type": "number", |
|
|
|
|
|
"default": 2, |
|
|
|
|
|
"required": true, |
|
|
|
|
|
"subLabel": "Secondary", |
|
|
|
|
|
"fieldSuffix": "px", |
|
|
"fieldSuffix": "px", |
|
|
"min": 0, |
|
|
"min": 0, |
|
|
"max": 99, |
|
|
"max": 99, |
|
|
@ -206,7 +182,7 @@ |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "lineColor", |
|
|
"id": "lineColor", |
|
|
"name": "{i18n:scada.symbol.line-color}", |
|
|
"name": "{i18n:scada.symbol.line}", |
|
|
"type": "color", |
|
|
"type": "color", |
|
|
"default": "#1A1A1A", |
|
|
"default": "#1A1A1A", |
|
|
"disabled": false, |
|
|
"disabled": false, |
|
|
@ -214,11 +190,11 @@ |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "flowAnimationWidth", |
|
|
"id": "flowAnimationWidth", |
|
|
"name": "{i18n:scada.symbol.flow}", |
|
|
"name": "{i18n:scada.symbol.flow-line}", |
|
|
"group": "{i18n:scada.symbol.animation}", |
|
|
"group": "{i18n:scada.symbol.flow}", |
|
|
"type": "number", |
|
|
"type": "number", |
|
|
"default": 4, |
|
|
"default": 4, |
|
|
"subLabel": "Width", |
|
|
"divider": false, |
|
|
"fieldSuffix": "px", |
|
|
"fieldSuffix": "px", |
|
|
"min": 1, |
|
|
"min": 1, |
|
|
"step": 1, |
|
|
"step": 1, |
|
|
@ -227,20 +203,23 @@ |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "flowAnimationColor", |
|
|
"id": "flowAnimationColor", |
|
|
"name": "{i18n:scada.symbol.flow}", |
|
|
"name": "{i18n:scada.symbol.flow-line}", |
|
|
"group": "{i18n:scada.symbol.animation}", |
|
|
"group": "{i18n:scada.symbol.flow}", |
|
|
"type": "color", |
|
|
"type": "color", |
|
|
"default": "#C8DFF7" |
|
|
"default": "#C8DFF7", |
|
|
|
|
|
"disabled": false, |
|
|
|
|
|
"visible": true |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "flowStyleDash", |
|
|
"id": "flowStyleDash", |
|
|
"name": "{i18n:scada.symbol.flow-style}", |
|
|
"name": "{i18n:scada.symbol.flow-line-style}", |
|
|
"group": "{i18n:scada.symbol.animation}", |
|
|
"hint": "{i18n:scada.symbol.flow-style-hint}", |
|
|
|
|
|
"group": "{i18n:scada.symbol.flow}", |
|
|
"type": "number", |
|
|
"type": "number", |
|
|
"default": 10, |
|
|
"default": 10, |
|
|
"required": true, |
|
|
"required": true, |
|
|
"subLabel": "{i18n:scada.symbol.dash}", |
|
|
"subLabel": "{i18n:scada.symbol.dash}", |
|
|
"divider": true, |
|
|
"divider": false, |
|
|
"fieldSuffix": "px", |
|
|
"fieldSuffix": "px", |
|
|
"min": 0, |
|
|
"min": 0, |
|
|
"step": 1, |
|
|
"step": 1, |
|
|
@ -249,13 +228,14 @@ |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
"id": "flowStyleGap", |
|
|
"id": "flowStyleGap", |
|
|
"name": "{i18n:scada.symbol.flow-style}", |
|
|
"name": "{i18n:scada.symbol.flow-line-style}", |
|
|
"group": "{i18n:scada.symbol.animation}", |
|
|
"hint": "{i18n:scada.symbol.flow-style-hint}", |
|
|
|
|
|
"group": "{i18n:scada.symbol.flow}", |
|
|
"type": "number", |
|
|
"type": "number", |
|
|
"default": 10, |
|
|
"default": 10, |
|
|
"subLabel": "{i18n:scada.symbol.gap}", |
|
|
"subLabel": "{i18n:scada.symbol.gap}", |
|
|
"fieldSuffix": "px", |
|
|
"fieldSuffix": "px", |
|
|
"min": 1, |
|
|
"min": 0, |
|
|
"step": 1, |
|
|
"step": 1, |
|
|
"disabled": false, |
|
|
"disabled": false, |
|
|
"visible": true |
|
|
"visible": true |
|
|
@ -263,7 +243,7 @@ |
|
|
{ |
|
|
{ |
|
|
"id": "flowDashCap", |
|
|
"id": "flowDashCap", |
|
|
"name": "{i18n:scada.symbol.flow-dash-cap}", |
|
|
"name": "{i18n:scada.symbol.flow-dash-cap}", |
|
|
"group": "{i18n:scada.symbol.animation}", |
|
|
"group": "{i18n:scada.symbol.flow}", |
|
|
"type": "select", |
|
|
"type": "select", |
|
|
"default": "butt", |
|
|
"default": "butt", |
|
|
"items": [ |
|
|
"items": [ |
|
|
@ -285,5 +265,5 @@ |
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
|
}]]></tb:metadata> |
|
|
}]]></tb:metadata> |
|
|
<path d="m0 100h400" stroke="#1A1A1A" stroke-width="6" tb:tag="line"/><path d="m229 100-58 29v-58z" fill="#1a1a1a" tb:tag="arrow"/><g tb:tag="animationGroup"/> |
|
|
<path d="M0 100H400" stroke="#1A1A1A" stroke-width="6" tb:tag="line"/><path d="m229 100-58 29v-58z" fill="#1a1a1a" tb:tag="arrow"/><g tb:tag="animationGroup"/> |
|
|
</svg> |
|
|
</svg> |