Browse Source

Merge pull request #9485 from ArtemDzhereleiko/AD/imp/settings/radial-gauge

Improvement for gauge widgets settings
pull/9548/head
Igor Kulikov 3 years ago
committed by GitHub
parent
commit
26f99d54e0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      application/src/main/data/json/system/widget_types/compass.json
  2. 8
      application/src/main/data/json/system/widget_types/radial_gauge.json
  3. 8
      application/src/main/data/json/system/widget_types/speed_gauge.json
  4. 8
      application/src/main/data/json/system/widget_types/temperature_radial_gauge.json
  5. 8
      application/src/main/data/json/system/widget_types/thermometer_scale.json
  6. 18
      ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts
  7. 182
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.html
  8. 187
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.ts
  9. 154
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.html
  10. 171
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.ts
  11. 45
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/radial-gauge-basic-config.component.ts
  12. 59
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/thermometer-scale-gauge-basic-config.component.ts
  13. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.html
  14. 291
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.html
  15. 42
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.ts
  16. 614
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component.html
  17. 70
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component.ts
  18. 61
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.html
  19. 40
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.scss
  20. 116
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.ts
  21. 3
      ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts
  22. 39
      ui-ngx/src/assets/locale/locale.constant-en_US.json

8
application/src/main/data/json/system/widget_types/compass.json

@ -11,11 +11,11 @@
"resources": [], "resources": [],
"templateHtml": "<canvas id=\"compass\"></canvas>", "templateHtml": "<canvas id=\"compass\"></canvas>",
"templateCss": "", "templateCss": "",
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueCompass(self.ctx, 'compass');\n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueCompass(self.ctx, 'compass');\n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'direction', label: 'Direction', type: 'timeseries' }];\n }\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "settingsSchema": "{}",
"settingsSchema": "{}",
"dataKeySettingsSchema": "{}\n", "dataKeySettingsSchema": "{}\n",
"settingsDirective": "tb-analogue-compass-widget-settings", "settingsDirective": "tb-analogue-compass-widget-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"minorTicks\":22,\"needleCircleSize\":15,\"showBorder\":true,\"borderOuterWidth\":10,\"colorPlate\":\"#222\",\"colorMajorTicks\":\"#f5f5f5\",\"colorMinorTicks\":\"#ddd\",\"colorNeedle\":\"#f08080\",\"colorNeedleCircle\":\"#e8e8e8\",\"colorBorder\":\"#ccc\",\"majorTickFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#ccc\"},\"animation\":true,\"animationDuration\":500,\"animationRule\":\"cycle\",\"animationTarget\":\"needle\",\"majorTicks\":[\"N\",\"NE\",\"E\",\"SE\",\"S\",\"SW\",\"W\",\"NW\"]},\"title\":\"Compass\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\"}" "hasBasicMode": true,
}, "basicModeDirective": "tb-compass-gauge-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"minorTicks\":22,\"needleCircleSize\":15,\"showBorder\":true,\"borderOuterWidth\":10,\"colorPlate\":\"#222\",\"colorMajorTicks\":\"#f5f5f5\",\"colorMinorTicks\":\"#ddd\",\"colorNeedle\":\"#f08080\",\"colorNeedleCircle\":\"#e8e8e8\",\"colorBorder\":\"#ccc\",\"majorTickFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#ccc\"},\"animation\":true,\"animationDuration\":500,\"animationRule\":\"cycle\",\"animationTarget\":\"needle\",\"majorTicks\":[\"N\",\"NE\",\"E\",\"SE\",\"S\",\"SW\",\"W\",\"NW\"]},\"title\":\"Compass\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\"}" },
"externalId": null "externalId": null
} }

8
application/src/main/data/json/system/widget_types/radial_gauge.json

@ -11,11 +11,11 @@
"resources": [], "resources": [],
"templateHtml": "<canvas id=\"radialGauge\"></canvas>\n", "templateHtml": "<canvas id=\"radialGauge\"></canvas>\n",
"templateCss": "", "templateCss": "",
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'temperature', label: 'Temperature', type: 'timeseries' }];\n }\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "settingsSchema": "{}",
"settingsSchema": "{}",
"dataKeySettingsSchema": "{}\n", "dataKeySettingsSchema": "{}\n",
"settingsDirective": "tb-analogue-radial-gauge-widget-settings", "settingsDirective": "tb-analogue-radial-gauge-widget-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < -100) {\\n\\tvalue = -100;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":100,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":true,\"defaultColor\":\"#e65100\",\"needleCircleSize\":10,\"highlights\":[],\"showUnitTitle\":true,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":10,\"valueInt\":3,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":500,\"animationRule\":\"cycle\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"numbersFont\":{\"family\":\"Roboto\",\"size\":18,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"size\":36,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\"},\"minValue\":-100,\"colorNeedleShadowDown\":\"rgba(188,143,143,0.45)\",\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Radial gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\"}" "hasBasicMode": true,
}, "basicModeDirective": "tb-radial-gauge-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < -100) {\\n\\tvalue = -100;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":100,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":true,\"defaultColor\":\"#e65100\",\"needleCircleSize\":10,\"highlights\":[],\"showUnitTitle\":true,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":10,\"valueInt\":3,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":500,\"animationRule\":\"cycle\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"numbersFont\":{\"family\":\"Roboto\",\"size\":18,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"size\":36,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\"},\"minValue\":-100,\"colorNeedleShadowDown\":\"rgba(188,143,143,0.45)\",\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Radial gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\"}" },
"externalId": null "externalId": null
} }

8
application/src/main/data/json/system/widget_types/speed_gauge.json

@ -11,11 +11,11 @@
"resources": [], "resources": [],
"templateHtml": "<canvas id=\"radialGauge\"></canvas>\n", "templateHtml": "<canvas id=\"radialGauge\"></canvas>\n",
"templateCss": "", "templateCss": "",
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'speed', label: 'Speed', type: 'timeseries' }];\n }\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "settingsSchema": "{}",
"settingsSchema": "{}",
"dataKeySettingsSchema": "{}\n", "dataKeySettingsSchema": "{}\n",
"settingsDirective": "tb-analogue-radial-gauge-widget-settings", "settingsDirective": "tb-analogue-radial-gauge-widget-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 220) {\\n\\tvalue = 220;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":180,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":false,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":80,\"to\":120,\"color\":\"#fdd835\"},{\"color\":\"#e57373\",\"from\":120,\"to\":180}],\"showUnitTitle\":false,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"minValue\":0,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"MPH\",\"majorTicksCount\":9,\"numbersFont\":{\"family\":\"Roboto\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"size\":32,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\",\"family\":\"Segment7Standard\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Speed gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\"}" "hasBasicMode": true,
}, "basicModeDirective": "tb-radial-gauge-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 220) {\\n\\tvalue = 220;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":180,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":false,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":80,\"to\":120,\"color\":\"#fdd835\"},{\"color\":\"#e57373\",\"from\":120,\"to\":180}],\"showUnitTitle\":false,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"minValue\":0,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"MPH\",\"majorTicksCount\":9,\"numbersFont\":{\"family\":\"Roboto\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"size\":32,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\",\"family\":\"Segment7Standard\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Speed gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\"}" },
"externalId": null "externalId": null
} }

8
application/src/main/data/json/system/widget_types/temperature_radial_gauge.json

@ -11,11 +11,11 @@
"resources": [], "resources": [],
"templateHtml": "<canvas id=\"radialGauge\"></canvas>\n", "templateHtml": "<canvas id=\"radialGauge\"></canvas>\n",
"templateCss": "", "templateCss": "",
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'temperature', label: 'Temperature', type: 'timeseries' }];\n }\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "settingsSchema": "{}",
"settingsSchema": "{}",
"dataKeySettingsSchema": "{}\n", "dataKeySettingsSchema": "{}\n",
"settingsDirective": "tb-analogue-radial-gauge-widget-settings", "settingsDirective": "tb-analogue-radial-gauge-widget-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":60,\"startAngle\":67.5,\"ticksAngle\":225,\"showBorder\":true,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":-60,\"to\":-50,\"color\":\"#42a5f5\"},{\"from\":-50,\"to\":-40,\"color\":\"rgba(66, 165, 245, 0.83)\"},{\"from\":-40,\"to\":-30,\"color\":\"rgba(66, 165, 245, 0.66)\"},{\"from\":-30,\"to\":-20,\"color\":\"rgba(66, 165, 245, 0.5)\"},{\"from\":-20,\"to\":-10,\"color\":\"rgba(66, 165, 245, 0.33)\"},{\"from\":-10,\"to\":0,\"color\":\"rgba(66, 165, 245, 0.16)\"},{\"from\":0,\"to\":10,\"color\":\"rgba(229, 115, 115, 0.16)\"},{\"from\":10,\"to\":20,\"color\":\"rgba(229, 115, 115, 0.33)\"},{\"from\":20,\"to\":30,\"color\":\"rgba(229, 115, 115, 0.5)\"},{\"from\":30,\"to\":40,\"color\":\"rgba(229, 115, 115, 0.66)\"},{\"from\":40,\"to\":50,\"color\":\"rgba(229, 115, 115, 0.83)\"},{\"from\":50,\"to\":60,\"color\":\"#e57373\"}],\"showUnitTitle\":true,\"colorPlate\":\"#cfd8dc\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"valueDec\":1,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1000,\"animationRule\":\"bounce\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"°C\",\"majorTicksCount\":12,\"numbersFont\":{\"family\":\"Roboto\",\"size\":20,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"size\":30,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\",\"unitTitle\":\"Temperature\",\"minValue\":-60},\"title\":\"Temperature radial gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\"}" "hasBasicMode": true,
}, "basicModeDirective": "tb-radial-gauge-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":60,\"startAngle\":67.5,\"ticksAngle\":225,\"showBorder\":true,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":-60,\"to\":-50,\"color\":\"#42a5f5\"},{\"from\":-50,\"to\":-40,\"color\":\"rgba(66, 165, 245, 0.83)\"},{\"from\":-40,\"to\":-30,\"color\":\"rgba(66, 165, 245, 0.66)\"},{\"from\":-30,\"to\":-20,\"color\":\"rgba(66, 165, 245, 0.5)\"},{\"from\":-20,\"to\":-10,\"color\":\"rgba(66, 165, 245, 0.33)\"},{\"from\":-10,\"to\":0,\"color\":\"rgba(66, 165, 245, 0.16)\"},{\"from\":0,\"to\":10,\"color\":\"rgba(229, 115, 115, 0.16)\"},{\"from\":10,\"to\":20,\"color\":\"rgba(229, 115, 115, 0.33)\"},{\"from\":20,\"to\":30,\"color\":\"rgba(229, 115, 115, 0.5)\"},{\"from\":30,\"to\":40,\"color\":\"rgba(229, 115, 115, 0.66)\"},{\"from\":40,\"to\":50,\"color\":\"rgba(229, 115, 115, 0.83)\"},{\"from\":50,\"to\":60,\"color\":\"#e57373\"}],\"showUnitTitle\":true,\"colorPlate\":\"#cfd8dc\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"valueDec\":1,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1000,\"animationRule\":\"bounce\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"°C\",\"majorTicksCount\":12,\"numbersFont\":{\"family\":\"Roboto\",\"size\":20,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"size\":30,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\",\"unitTitle\":\"Temperature\",\"minValue\":-60},\"title\":\"Temperature radial gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\"}" },
"externalId": null "externalId": null
} }

8
application/src/main/data/json/system/widget_types/thermometer_scale.json

@ -11,11 +11,11 @@
"resources": [], "resources": [],
"templateHtml": "<canvas id=\"linearGauge\"></canvas>\n", "templateHtml": "<canvas id=\"linearGauge\"></canvas>\n",
"templateCss": "", "templateCss": "",
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueLinearGauge(self.ctx, 'linearGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueLinearGauge(self.ctx, 'linearGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'temperature', label: 'Temperature', type: 'timeseries' }];\n }\n };\n}\n\nself.onDestroy = function() {\n self.ctx.gauge.destroy();\n}\n", "settingsSchema": "{}",
"settingsSchema": "{}",
"dataKeySettingsSchema": "{}\n", "dataKeySettingsSchema": "{}\n",
"settingsDirective": "tb-analogue-linear-gauge-widget-settings", "settingsDirective": "tb-analogue-linear-gauge-widget-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 30 - 15;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":100,\"defaultColor\":\"#e64a19\",\"barStrokeWidth\":2.5,\"colorBar\":\"rgba(255, 255, 255, 0.4)\",\"colorBarEnd\":\"rgba(221, 221, 221, 0.38)\",\"showUnitTitle\":true,\"minorTicks\":2,\"valueBox\":true,\"valueInt\":3,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"colorNeedleShadowUp\":\"rgba(2,255,255,0.2)\",\"colorNeedleShadowDown\":\"rgba(188,143,143,0.45)\",\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\",\"highlightsWidth\":10,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"showBorder\":false,\"majorTicksCount\":8,\"numbersFont\":{\"family\":\"Arial\",\"size\":18,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#78909c\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":26,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#37474f\"},\"valueFont\":{\"family\":\"Roboto\",\"size\":40,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#444\",\"shadowColor\":\"rgba(0,0,0,0.3)\"},\"minValue\":-60,\"highlights\":[{\"from\":-60,\"to\":-40,\"color\":\"#90caf9\"},{\"from\":-40,\"to\":-20,\"color\":\"rgba(144, 202, 249, 0.66)\"},{\"from\":-20,\"to\":0,\"color\":\"rgba(144, 202, 249, 0.33)\"},{\"from\":0,\"to\":20,\"color\":\"rgba(244, 67, 54, 0.2)\"},{\"from\":20,\"to\":40,\"color\":\"rgba(244, 67, 54, 0.4)\"},{\"from\":40,\"to\":60,\"color\":\"rgba(244, 67, 54, 0.6)\"},{\"from\":60,\"to\":80,\"color\":\"rgba(244, 67, 54, 0.8)\"},{\"from\":80,\"to\":100,\"color\":\"#f44336\"}],\"unitTitle\":\"Temperature\",\"units\":\"°C\",\"colorBarProgress\":\"#90caf9\",\"colorBarProgressEnd\":\"#f44336\",\"colorBarStroke\":\"#b0bec5\",\"valueDec\":1},\"title\":\"Thermometer scale\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\"}" "hasBasicMode": true,
}, "basicModeDirective": "tb-thermometer-scale-gauge-basic-config",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 30 - 15;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":100,\"defaultColor\":\"#e64a19\",\"barStrokeWidth\":2.5,\"colorBar\":\"rgba(255, 255, 255, 0.4)\",\"colorBarEnd\":\"rgba(221, 221, 221, 0.38)\",\"showUnitTitle\":true,\"minorTicks\":2,\"valueBox\":true,\"valueInt\":3,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"colorNeedleShadowUp\":\"rgba(2,255,255,0.2)\",\"colorNeedleShadowDown\":\"rgba(188,143,143,0.45)\",\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\",\"highlightsWidth\":10,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"showBorder\":false,\"majorTicksCount\":8,\"numbersFont\":{\"family\":\"Arial\",\"size\":18,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#78909c\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":26,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#37474f\"},\"valueFont\":{\"family\":\"Roboto\",\"size\":40,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#444\",\"shadowColor\":\"rgba(0,0,0,0.3)\"},\"minValue\":-60,\"highlights\":[{\"from\":-60,\"to\":-40,\"color\":\"#90caf9\"},{\"from\":-40,\"to\":-20,\"color\":\"rgba(144, 202, 249, 0.66)\"},{\"from\":-20,\"to\":0,\"color\":\"rgba(144, 202, 249, 0.33)\"},{\"from\":0,\"to\":20,\"color\":\"rgba(244, 67, 54, 0.2)\"},{\"from\":20,\"to\":40,\"color\":\"rgba(244, 67, 54, 0.4)\"},{\"from\":40,\"to\":60,\"color\":\"rgba(244, 67, 54, 0.6)\"},{\"from\":60,\"to\":80,\"color\":\"rgba(244, 67, 54, 0.8)\"},{\"from\":80,\"to\":100,\"color\":\"#f44336\"}],\"unitTitle\":\"Temperature\",\"units\":\"°C\",\"colorBarProgress\":\"#90caf9\",\"colorBarProgressEnd\":\"#f44336\",\"colorBarStroke\":\"#b0bec5\",\"valueDec\":1},\"title\":\"Thermometer scale\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"decimals\":0,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\"}" },
"externalId": null "externalId": null
} }

18
ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts

@ -70,6 +70,15 @@ import {
import { import {
ProgressBarBasicConfigComponent ProgressBarBasicConfigComponent
} from '@home/components/widget/config/basic/cards/progress-bar-basic-config.component'; } from '@home/components/widget/config/basic/cards/progress-bar-basic-config.component';
import {
RadialGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/radial-gauge-basic-config.component';
import {
ThermometerScaleGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/thermometer-scale-gauge-basic-config.component';
import {
CompassGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/compass-gauge-basic-config.component';
import { import {
LiquidLevelCardBasicConfigComponent LiquidLevelCardBasicConfigComponent
} from '@home/components/widget/config/basic/indicator/liquid-level-card-basic-config.component'; } from '@home/components/widget/config/basic/indicator/liquid-level-card-basic-config.component';
@ -95,6 +104,9 @@ import {
SignalStrengthBasicConfigComponent, SignalStrengthBasicConfigComponent,
ValueChartCardBasicConfigComponent, ValueChartCardBasicConfigComponent,
ProgressBarBasicConfigComponent, ProgressBarBasicConfigComponent,
RadialGaugeBasicConfigComponent,
ThermometerScaleGaugeBasicConfigComponent,
CompassGaugeBasicConfigComponent,
LiquidLevelCardBasicConfigComponent LiquidLevelCardBasicConfigComponent
], ],
imports: [ imports: [
@ -122,6 +134,9 @@ import {
SignalStrengthBasicConfigComponent, SignalStrengthBasicConfigComponent,
ValueChartCardBasicConfigComponent, ValueChartCardBasicConfigComponent,
ProgressBarBasicConfigComponent, ProgressBarBasicConfigComponent,
RadialGaugeBasicConfigComponent,
ThermometerScaleGaugeBasicConfigComponent,
CompassGaugeBasicConfigComponent,
LiquidLevelCardBasicConfigComponent LiquidLevelCardBasicConfigComponent
] ]
}) })
@ -143,5 +158,8 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type<IBasicWidgetCo
'tb-signal-strength-basic-config': SignalStrengthBasicConfigComponent, 'tb-signal-strength-basic-config': SignalStrengthBasicConfigComponent,
'tb-value-chart-card-basic-config': ValueChartCardBasicConfigComponent, 'tb-value-chart-card-basic-config': ValueChartCardBasicConfigComponent,
'tb-progress-bar-basic-config': ProgressBarBasicConfigComponent, 'tb-progress-bar-basic-config': ProgressBarBasicConfigComponent,
'tb-radial-gauge-basic-config': RadialGaugeBasicConfigComponent,
'tb-thermometer-scale-gauge-basic-config': ThermometerScaleGaugeBasicConfigComponent,
'tb-compass-gauge-basic-config': CompassGaugeBasicConfigComponent,
'tb-liquid-level-card-basic-config': LiquidLevelCardBasicConfigComponent 'tb-liquid-level-card-basic-config': LiquidLevelCardBasicConfigComponent
}; };

182
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.html

@ -0,0 +1,182 @@
<!--
Copyright © 2016-2023 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ng-container [formGroup]="radialGaugeWidgetConfigForm">
<tb-timewindow-config-panel *ngIf="displayTimewindowConfig"
[onlyHistoryTimewindow]="onlyHistoryTimewindow()"
formControlName="timewindowConfig">
</tb-timewindow-config-panel>
<tb-datasources
[configMode]="basicMode"
hideDataKeyLabel
hideDataKeyColor
hideDataKeyUnits
hideDataKeyDecimals
formControlName="datasources">
</tb-datasources>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.gauge-appearance</div>
<div class="tb-form-row column-xs">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showUnitTitle">
{{ 'widgets.gauge.units-title' | translate }}
</mat-slide-toggle>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="unitTitle" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-font-settings formControlName="titleFont"
disabledLineHeight
[previewText]="radialGaugeWidgetConfigForm.get('unitTitle').value">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="titleColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widget-config.units-short</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-unit-input
formControlName="units">
</tb-unit-input>
<tb-font-settings formControlName="unitsFont"
disabledLineHeight
[previewText]="radialGaugeWidgetConfigForm.get('units').value">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="unitsColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="valueBox">
{{ 'widgets.gauge.value' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field appearance="outline" class="flex number" subscriptSizing="dynamic">
<input matInput formControlName="valueInt" type="number" min="0" max="15" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<div matSuffix fxHide.lt-md translate>widget-config.decimals-suffix</div>
</mat-form-field>
<tb-font-settings formControlName="valueFont"
disabledLineHeight
[previewText]="valuePreviewFn">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="valueColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.gauge.ticks</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<div class="tb-small-label" translate>widgets.gauge.min-value-short</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="minValue" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<div class="tb-small-label" translate>widgets.gauge.max-value-short</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="maxValue" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-font-settings formControlName="numbersFont"
disabledLineHeight
[previewText]="valuePreviewFn">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="numbersColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.arrow-and-scale-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="defaultColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.plate-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorPlate">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.scale-color</div>
<tb-color-range-settings formControlName="highlights">
</tb-color-range-settings>
</div>
<div class="tb-form-panel" *ngIf="gaugeType === 'linear'">
<div class="tb-form-panel-title" translate>widgets.gauge.progress-bar</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.progress-bar-color-start</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBarProgress">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.progress-bar-color-end</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBarProgressEnd">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.bar-stroke-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBarStroke">
</tb-color-input>
</div>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.card-appearance</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="backgroundColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between column-lt-md">
<div translate>widget-config.show-card-buttons</div>
<mat-chip-listbox multiple formControlName="cardButtons">
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.card-border-radius' | translate }}</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="borderRadius" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
</div>
<tb-widget-actions-panel
formControlName="actions">
</tb-widget-actions-panel>
</ng-container>

187
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.ts

@ -0,0 +1,187 @@
///
/// Copyright © 2016-2023 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
import {
datasourcesHasAggregation,
datasourcesHasOnlyComparisonAggregation,
WidgetConfig,
} from '@shared/models/widget.models';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import {
getTimewindowConfig,
setTimewindowConfig
} from '@home/components/widget/config/timewindow-config-panel.component';
import { formatValue, isUndefined } from '@core/utils';
import { ColorType } from '@shared/models/widget-settings.models';
export class GaugeBasicConfigComponent extends BasicWidgetConfigComponent {
public get displayTimewindowConfig(): boolean {
const datasources = this.radialGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasAggregation(datasources);
}
public onlyHistoryTimewindow(): boolean {
const datasources = this.radialGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasOnlyComparisonAggregation(datasources);
}
colorType = ColorType;
radialGaugeWidgetConfigForm: UntypedFormGroup;
valuePreviewFn = this._valuePreviewFn.bind(this);
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent);
}
protected configForm(): UntypedFormGroup {
return this.radialGaugeWidgetConfigForm;
}
protected setupDefaults(configData: WidgetConfigComponentData) {
super.setupDefaults(configData);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
this.radialGaugeWidgetConfigForm = this.fb.group({
timewindowConfig: [getTimewindowConfig(configData.config), []],
datasources: [configData.config.datasources, []],
showUnitTitle: [configData.config.settings?.showUnitTitle, []],
unitTitle: [configData.config.settings?.unitTitle, []],
titleFont: [configData.config.settings?.titleFont, []],
titleColor: [configData.config.settings?.titleFont?.color, []],
units: [configData.config.units, []],
unitsFont: [configData.config.settings?.unitsFont, []],
unitsColor: [configData.config.settings?.unitsFont?.color, []],
valueBox: [configData.config.settings?.valueBox, []],
valueInt: [configData.config.settings?.valueInt, []],
valueFont: [configData.config.settings?.valueFont, []],
valueColor: [configData.config.settings?.valueFont?.color, []],
minValue: [configData.config.settings?.minValue, []],
maxValue: [configData.config.settings?.maxValue, []],
numbersFont: [configData.config.settings?.numbersFont, []],
numbersColor: [configData.config.settings?.numbersFont?.color, []],
colorBarStroke: [configData.config.settings?.colorBarStroke, []],
defaultColor: [configData.config.settings?.defaultColor, []],
colorPlate: [configData.config.settings?.colorPlate, []],
highlights: [configData.config.settings?.highlights, []],
cardButtons: [this.getCardButtons(configData.config), []],
borderRadius: [configData.config.borderRadius, []],
backgroundColor: [configData.config.backgroundColor, []],
actions: [configData.config.actions || {}, []]
});
}
protected prepareOutputConfig(config: any): WidgetConfigComponentData {
setTimewindowConfig(this.widgetConfig.config, config.timewindowConfig);
this.widgetConfig.config.datasources = config.datasources;
this.widgetConfig.config.actions = config.actions;
this.widgetConfig.config.settings = this.widgetConfig.config.settings || {};
this.setCardButtons(config.cardButtons, this.widgetConfig.config);
this.widgetConfig.config.backgroundColor = config.backgroundColor;
this.widgetConfig.config.settings.showUnitTitle = config.showUnitTitle;
this.widgetConfig.config.settings.unitTitle = config.unitTitle;
this.widgetConfig.config.settings.titleFont = config.titleFont;
this.widgetConfig.config.settings.titleFont.color = config.titleColor;
this.widgetConfig.config.units = config.units;
this.widgetConfig.config.settings.unitsFont = config.unitsFont;
this.widgetConfig.config.settings.unitsFont.color = config.unitsColor;
this.widgetConfig.config.settings.valueBox = config.valueBox;
this.widgetConfig.config.settings.valueInt = config.valueInt;
this.widgetConfig.config.settings.valueFont = config.valueFont;
this.widgetConfig.config.settings.valueFont.color = config.valueColor;
this.widgetConfig.config.settings.minValue = config.minValue;
this.widgetConfig.config.settings.maxValue = config.maxValue;
this.widgetConfig.config.settings.numbersFont = config.numbersFont;
this.widgetConfig.config.settings.numbersFont.color = config.numbersColor;
this.widgetConfig.config.settings.defaultColor = config.defaultColor;
this.widgetConfig.config.settings.colorPlate = config.colorPlate;
this.widgetConfig.config.settings.highlights = config.highlights.rangeList;
return this.widgetConfig;
}
protected validatorTriggers(): string[] {
return ['showUnitTitle', 'valueBox'];
}
protected updateValidators(emitEvent: boolean, trigger?: string) {
const showUnitTitle: boolean = this.radialGaugeWidgetConfigForm.get('showUnitTitle').value;
const valueBox: boolean = this.radialGaugeWidgetConfigForm.get('valueBox').value;
if (showUnitTitle) {
this.radialGaugeWidgetConfigForm.get('unitTitle').enable();
this.radialGaugeWidgetConfigForm.get('titleFont').enable();
this.radialGaugeWidgetConfigForm.get('titleColor').enable();
} else {
this.radialGaugeWidgetConfigForm.get('unitTitle').disable();
this.radialGaugeWidgetConfigForm.get('titleFont').disable();
this.radialGaugeWidgetConfigForm.get('titleColor').disable();
}
if (valueBox) {
this.radialGaugeWidgetConfigForm.get('valueInt').enable();
this.radialGaugeWidgetConfigForm.get('valueFont').enable();
this.radialGaugeWidgetConfigForm.get('valueColor').enable();
} else {
this.radialGaugeWidgetConfigForm.get('valueInt').disable();
this.radialGaugeWidgetConfigForm.get('valueFont').disable();
this.radialGaugeWidgetConfigForm.get('valueColor').disable();
}
this.radialGaugeWidgetConfigForm.get('unitTitle').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('titleFont').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('titleColor').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('valueInt').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('valueFont').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('valueColor').updateValueAndValidity({emitEvent});
}
private getCardButtons(config: WidgetConfig): string[] {
const buttons: string[] = [];
if (isUndefined(config.enableFullscreen) || config.enableFullscreen) {
buttons.push('fullscreen');
}
return buttons;
}
private setCardButtons(buttons: string[], config: WidgetConfig) {
config.enableFullscreen = buttons.includes('fullscreen');
}
private _valuePreviewFn(): string {
const units: string = this.radialGaugeWidgetConfigForm.get('units').value;
return formatValue(22, 0, units, true);
}
}

154
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.html

@ -0,0 +1,154 @@
<!--
Copyright © 2016-2023 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ng-container [formGroup]="compassGaugeWidgetConfigForm">
<tb-timewindow-config-panel *ngIf="displayTimewindowConfig"
[onlyHistoryTimewindow]="onlyHistoryTimewindow()"
formControlName="timewindowConfig">
</tb-timewindow-config-panel>
<tb-datasources
[configMode]="basicMode"
hideDataKeyLabel
hideDataKeyColor
hideDataKeyUnits
hideDataKeyDecimals
formControlName="datasources">
</tb-datasources>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.appearance</div>
<div class="tb-form-row column-xs">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showTitle">
{{ 'widget-config.title' | translate }}
</mat-slide-toggle>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-font-settings formControlName="titleFont"
clearButton
[previewText]="compassGaugeWidgetConfigForm.get('title').value"
[initialPreviewStyle]="widgetConfig.config.titleStyle">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="titleColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
iconClearButton
[color]="compassGaugeWidgetConfigForm.get('iconColor').value"
formControlName="titleIcon">
</tb-material-icon-select>
<tb-color-input asBoxInput
colorClearButton
formControlName="iconColor">
</tb-color-input>
</div>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.compass-appearance</div>
<div class="tb-form-row">
<div class="fixed-title-width" translate>widgets.gauge.labels</div>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-string-items-list
style="display: flex"
fxFlex
appearance="outline"
subscriptSizing="dynamic"
editable
formControlName="majorTicks">
</tb-string-items-list>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.label-style</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-font-settings formControlName="majorTickFont"
disabledLineHeight>
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="majorTickColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.major-ticks-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorMajorTicks">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.minor-ticks-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorMinorTicks">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.needle-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorNeedle">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.plate-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorPlate">
</tb-color-input>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.card-appearance</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="backgroundColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between column-lt-md">
<div translate>widget-config.show-card-buttons</div>
<mat-chip-listbox multiple formControlName="cardButtons">
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.card-border-radius' | translate }}</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="borderRadius" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
</div>
<tb-widget-actions-panel
formControlName="actions">
</tb-widget-actions-panel>
</ng-container>

171
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.ts

@ -0,0 +1,171 @@
///
/// Copyright © 2016-2023 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
import {
datasourcesHasAggregation,
datasourcesHasOnlyComparisonAggregation,
WidgetConfig,
} from '@shared/models/widget.models';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import {
getTimewindowConfig,
setTimewindowConfig
} from '@home/components/widget/config/timewindow-config-panel.component';
import { isUndefined } from '@core/utils';
@Component({
selector: 'tb-compass-gauge-basic-config',
templateUrl: './compass-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class CompassGaugeBasicConfigComponent extends BasicWidgetConfigComponent {
public get displayTimewindowConfig(): boolean {
const datasources = this.compassGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasAggregation(datasources);
}
public onlyHistoryTimewindow(): boolean {
const datasources = this.compassGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasOnlyComparisonAggregation(datasources);
}
compassGaugeWidgetConfigForm: UntypedFormGroup;
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent);
}
protected configForm(): UntypedFormGroup {
return this.compassGaugeWidgetConfigForm;
}
protected setupDefaults(configData: WidgetConfigComponentData) {
super.setupDefaults(configData);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
this.compassGaugeWidgetConfigForm = this.fb.group({
timewindowConfig: [getTimewindowConfig(configData.config), []],
datasources: [configData.config.datasources, []],
showTitle: [configData.config.showTitle, []],
title: [configData.config.title, []],
titleFont: [configData.config.titleFont, []],
titleColor: [configData.config.titleColor, []],
showTitleIcon: [configData.config.showTitleIcon, []],
titleIcon: [configData.config.titleIcon, []],
iconColor: [configData.config.iconColor, []],
majorTicks: [configData.config.settings?.majorTicks, []],
majorTickFont: [configData.config.settings?.majorTickFont, []],
majorTickColor: [configData.config.settings?.majorTickFont.color, []],
colorMajorTicks: [configData.config.settings?.colorMajorTicks, []],
colorMinorTicks: [configData.config.settings?.colorMinorTicks, []],
colorPlate: [configData.config.settings?.colorPlate, []],
colorNeedle: [configData.config.settings?.colorNeedle, []],
cardButtons: [this.getCardButtons(configData.config), []],
borderRadius: [configData.config.borderRadius, []],
backgroundColor: [configData.config.backgroundColor, []],
actions: [configData.config.actions || {}, []]
});
}
protected prepareOutputConfig(config: any): WidgetConfigComponentData {
setTimewindowConfig(this.widgetConfig.config, config.timewindowConfig);
this.widgetConfig.config.datasources = config.datasources;
this.widgetConfig.config.actions = config.actions;
this.widgetConfig.config.showTitle = config.showTitle;
this.widgetConfig.config.title = config.title;
this.widgetConfig.config.titleFont = config.titleFont;
this.widgetConfig.config.titleColor = config.titleColor;
this.widgetConfig.config.showTitleIcon = config.showTitleIcon;
this.widgetConfig.config.titleIcon = config.titleIcon;
this.widgetConfig.config.iconColor = config.iconColor;
this.widgetConfig.config.settings = this.widgetConfig.config.settings || {};
this.setCardButtons(config.cardButtons, this.widgetConfig.config);
this.widgetConfig.config.backgroundColor = config.backgroundColor;
this.widgetConfig.config.settings.majorTicks = config.majorTicks;
this.widgetConfig.config.settings.majorTickFont = config.majorTickFont;
this.widgetConfig.config.settings.majorTickFont.color = config.majorTickColor;
this.widgetConfig.config.settings.colorMajorTicks = config.colorMajorTicks;
this.widgetConfig.config.settings.colorMinorTicks = config.colorMinorTicks;
this.widgetConfig.config.settings.colorPlate = config.colorPlate;
this.widgetConfig.config.settings.colorNeedle = config.colorNeedle;
return this.widgetConfig;
}
protected validatorTriggers(): string[] {
return ['showTitle', 'showTitleIcon'];
}
protected updateValidators(emitEvent: boolean, trigger?: string) {
const showTitle: boolean = this.compassGaugeWidgetConfigForm.get('showTitle').value;
const showTitleIcon: boolean = this.compassGaugeWidgetConfigForm.get('showTitleIcon').value;
if (showTitle) {
this.compassGaugeWidgetConfigForm.get('title').enable();
this.compassGaugeWidgetConfigForm.get('titleFont').enable();
this.compassGaugeWidgetConfigForm.get('titleColor').enable();
this.compassGaugeWidgetConfigForm.get('showTitleIcon').enable({emitEvent: false});
if (showTitleIcon) {
this.compassGaugeWidgetConfigForm.get('titleIcon').enable();
this.compassGaugeWidgetConfigForm.get('iconColor').enable();
} else {
this.compassGaugeWidgetConfigForm.get('titleIcon').disable();
this.compassGaugeWidgetConfigForm.get('iconColor').disable();
}
} else {
this.compassGaugeWidgetConfigForm.get('title').disable();
this.compassGaugeWidgetConfigForm.get('titleFont').disable();
this.compassGaugeWidgetConfigForm.get('titleColor').disable();
this.compassGaugeWidgetConfigForm.get('showTitleIcon').disable({emitEvent: false});
this.compassGaugeWidgetConfigForm.get('titleIcon').disable();
this.compassGaugeWidgetConfigForm.get('iconColor').disable();
}
this.compassGaugeWidgetConfigForm.get('title').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('titleFont').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('titleColor').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('showTitleIcon').updateValueAndValidity({emitEvent: false});
this.compassGaugeWidgetConfigForm.get('titleIcon').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('iconColor').updateValueAndValidity({emitEvent});
}
private getCardButtons(config: WidgetConfig): string[] {
const buttons: string[] = [];
if (isUndefined(config.enableFullscreen) || config.enableFullscreen) {
buttons.push('fullscreen');
}
return buttons;
}
private setCardButtons(buttons: string[], config: WidgetConfig) {
config.enableFullscreen = buttons.includes('fullscreen');
}
}

45
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/radial-gauge-basic-config.component.ts

@ -0,0 +1,45 @@
///
/// Copyright © 2016-2023 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { UntypedFormBuilder } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
GaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/analog-gauge-basic-config.component';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
@Component({
selector: 'tb-radial-gauge-basic-config',
templateUrl: './analog-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class RadialGaugeBasicConfigComponent extends GaugeBasicConfigComponent {
gaugeType = 'radial';
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent, fb);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
super.onConfigSet(configData);
}
}

59
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/thermometer-scale-gauge-basic-config.component.ts

@ -0,0 +1,59 @@
///
/// Copyright © 2016-2023 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { UntypedFormBuilder } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
GaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/analog-gauge-basic-config.component';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
@Component({
selector: 'tb-thermometer-scale-gauge-basic-config',
templateUrl: './analog-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class ThermometerScaleGaugeBasicConfigComponent extends GaugeBasicConfigComponent {
gaugeType = 'linear';
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent, fb);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
super.onConfigSet(configData);
this.radialGaugeWidgetConfigForm.addControl('colorBarStroke',
this.fb.control(configData.config.settings?.colorBarStroke, []));
this.radialGaugeWidgetConfigForm.addControl('colorBarProgress',
this.fb.control(configData.config.settings?.colorBarProgress, []));
this.radialGaugeWidgetConfigForm.addControl('colorBarProgressEnd',
this.fb.control(configData.config.settings?.colorBarProgressEnd, []));
}
protected prepareOutputConfig(config): WidgetConfigComponentData {
const outputConfig = super.prepareOutputConfig(config);
this.widgetConfig.config.settings.colorBarStroke = config.colorBarStroke;
this.widgetConfig.config.settings.colorBarProgress = config.colorBarProgress;
this.widgetConfig.config.settings.colorBarProgressEnd = config.colorBarProgressEnd;
return outputConfig;
}
}

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.html

@ -73,7 +73,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="tb-form-row no-border no-padding" [fxHide]="disabledLineHeight"> <div class="tb-form-row no-border no-padding" *ngIf="!disabledLineHeight">
<div class="fixed-title-width" translate>widgets.widget-font.line-height</div> <div class="fixed-title-width" translate>widgets.widget-font.line-height</div>
<mat-form-field *ngIf="!autoScale" fxFlex appearance="outline" subscriptSizing="dynamic"> <mat-form-field *ngIf="!autoScale" fxFlex appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="lineHeight" placeholder="{{ 'widget-config.set' | translate }}"> <input matInput formControlName="lineHeight" placeholder="{{ 'widget-config.set' | translate }}">

291
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.html

@ -15,153 +15,127 @@
limitations under the License. limitations under the License.
--> -->
<section class="tb-widget-settings" [formGroup]="analogueCompassWidgetSettingsForm" fxLayout="column"> <ng-container [formGroup]="analogueCompassWidgetSettingsForm">
<fieldset class="fields-group"> <div class="tb-form-panel">
<legend class="group-title" translate>widgets.gauge.ticks-settings</legend> <div class="tb-form-panel-title" translate>widgets.gauge.ticks-settings</div>
<mat-form-field fxFlex class="mat-block" floatLabel="always"> <div class="tb-form-row">
<mat-label translate>widgets.gauge.major-ticks-names</mat-label> <div class="fixed-title-width" translate>widgets.gauge.labels</div>
<mat-chip-grid class="tb-drop-list" <div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
#majorTicksNamesChipList <tb-string-items-list
cdkDropList style="display: flex"
cdkDropListOrientation="horizontal" fxFlex
(cdkDropListDropped)="majorTickNameDrop($event)" appearance="outline"
formControlName="majorTicks"> subscriptSizing="dynamic"
<mat-chip-row class="tb-draggable" cdkDrag *ngFor="let tickName of majorTicksNamesList()" editable
[removable]="true" (removed)="removeMajorTickName(tickName)"> formControlName="majorTicks">
{{tickName}} </tb-string-items-list>
<mat-icon matChipRemove>cancel</mat-icon> </div>
</mat-chip-row> </div>
<input [matChipInputFor]="majorTicksNamesChipList" <div class="tb-form-row space-between">
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" <div translate>widgets.gauge.label-style</div>
matChipInputAddOnBlur <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
(matChipInputTokenEnd)="addMajorTickName($event)"> <tb-font-settings formControlName="majorTickFont"
</mat-chip-grid> disabledLineHeight>
</mat-form-field> </tb-font-settings>
<tb-color-input fxFlex <tb-color-input asBoxInput
formControlName="colorMajorTicks" colorClearButton
icon="format_color_fill" formControlName="majorTickColor">
label="{{ 'widgets.gauge.major-ticks-color' | translate }}" openOnInput colorClearButton> </tb-color-input>
</tb-color-input> </div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center"> </div>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.gauge.minor-ticks-count</mat-label> <div class="tb-form-row space-between">
<input matInput type="number" min="0" formControlName="minorTicks"> <div translate>widgets.gauge.major-ticks</div>
</mat-form-field> <tb-color-input asBoxInput
<tb-color-input fxFlex colorClearButton
formControlName="colorMinorTicks" formControlName="colorMajorTicks">
icon="format_color_fill"
label="{{ 'widgets.gauge.minor-ticks-color' | translate }}" openOnInput colorClearButton>
</tb-color-input>
</section>
<mat-slide-toggle formControlName="showStrokeTicks" class="slide-block">
{{ 'widgets.gauge.show-stroke-ticks' | translate }}
</mat-slide-toggle>
<fieldset class="fields-group">
<legend class="group-title" translate>widgets.gauge.major-ticks-font</legend>
<tb-widget-font formControlName="majorTickFont"></tb-widget-font>
</fieldset>
</fieldset>
<fieldset class="fields-group">
<legend class="group-title" translate>widgets.gauge.plate-settings</legend>
<tb-color-input fxFlex
formControlName="colorPlate"
icon="format_color_fill"
label="{{ 'widgets.gauge.plate-color' | translate }}" openOnInput colorClearButton>
</tb-color-input>
<mat-slide-toggle formControlName="showBorder" class="slide-block">
{{ 'widgets.gauge.show-plate-border' | translate }}
</mat-slide-toggle>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center">
<tb-color-input fxFlex
formControlName="colorBorder"
icon="format_color_fill"
label="{{ 'widgets.gauge.border-color' | translate }}" openOnInput colorClearButton>
</tb-color-input> </tb-color-input>
<mat-form-field fxFlex class="mat-block"> </div>
<mat-label translate>widgets.gauge.border-width</mat-label> <div class="tb-form-row space-between">
<input matInput type="number" min="0" formControlName="borderOuterWidth"> <div translate>widgets.gauge.minor-ticks</div>
</mat-form-field> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
</section> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
</fieldset> <input matInput type="number" min="0" formControlName="minorTicks">
<fieldset class="fields-group"> </mat-form-field>
<legend class="group-title" translate>widgets.gauge.needle-settings</legend> <tb-color-input asBoxInput
<mat-form-field fxFlex class="mat-block"> colorClearButton
<mat-label translate>widgets.gauge.needle-circle-size</mat-label> formControlName="colorMinorTicks">
<input matInput type="number" min="0" formControlName="needleCircleSize"> </tb-color-input>
</mat-form-field> </div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center"> </div>
<tb-color-input fxFlex
formControlName="colorNeedle" <div class="tb-form-row">
icon="format_color_fill" <mat-slide-toggle class="mat-slide" formControlName="showStrokeTicks">
label="{{ 'widgets.gauge.needle-color' | translate }}" openOnInput colorClearButton> {{ 'widgets.gauge.show-stroke-ticks' | translate }}
</mat-slide-toggle>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.plate-settings</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.plate-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorPlate">
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorNeedleCircle" <div class="tb-form-row space-between column-xs">
icon="format_color_fill" <mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showBorder">
label="{{ 'widgets.gauge.needle-circle-color' | translate }}" openOnInput colorClearButton> {{ 'widgets.gauge.show-plate-border' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field class="number" appearance="outline" subscriptSizing="dynamic">
<input matInput min="0" formControlName="borderOuterWidth" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBorder">
</tb-color-input>
</div>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.needle-settings</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.gauge.needle-circle</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field class="number" appearance="outline" subscriptSizing="dynamic">
<input matInput min="0" formControlName="needleCircleSize" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorNeedleCircle">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.needle-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorNeedle">
</tb-color-input> </tb-color-input>
</section> </div>
</fieldset> </div>
<fieldset class="fields-group fields-group-slider">
<legend class="group-title" translate>widgets.gauge.animation-settings</legend> <div class="tb-form-panel tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="analogueCompassWidgetSettingsForm.get('animation').value"> <mat-expansion-panel class="tb-settings" [expanded]="analogueCompassWidgetSettingsForm.get('animation').value">
<mat-expansion-panel-header fxLayout="row wrap"> <mat-expansion-panel-header fxLayout="row wrap">
<mat-panel-title> <mat-panel-title>
<mat-slide-toggle formControlName="animation" (click)="$event.stopPropagation()" <mat-slide-toggle class="mat-slide" formControlName="animation" (click)="$event.stopPropagation()"
fxLayoutAlign="center"> fxLayoutAlign="center">
{{ 'widgets.gauge.enable-animation' | translate }} {{ 'widgets.gauge.enable-animation' | translate }}
</mat-slide-toggle> </mat-slide-toggle>
</mat-panel-title> </mat-panel-title>
<mat-panel-description fxLayoutAlign="end center" fxHide.xs translate> <mat-panel-description fxFlex="40" fxLayoutAlign="end center" fxHide.xs translate>
widget-config.advanced-settings widget-config.advanced-settings
</mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<section fxLayout="column"> <div class="tb-form-row">
<mat-form-field fxFlex class="mat-block"> <div class="fixed-title-width" translate>widgets.gauge.animation-target</div>
<mat-label translate>widgets.gauge.animation-duration</mat-label> <mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" formControlName="animationDuration">
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.gauge.animation-rule</mat-label>
<mat-select formControlName="animationRule">
<mat-option [value]="'linear'">
{{ 'widgets.gauge.animation-linear' | translate }}
</mat-option>
<mat-option [value]="'quad'">
{{ 'widgets.gauge.animation-quad' | translate }}
</mat-option>
<mat-option [value]="'quint'">
{{ 'widgets.gauge.animation-quint' | translate }}
</mat-option>
<mat-option [value]="'cycle'">
{{ 'widgets.gauge.animation-cycle' | translate }}
</mat-option>
<mat-option [value]="'bounce'">
{{ 'widgets.gauge.animation-bounce' | translate }}
</mat-option>
<mat-option [value]="'elastic'">
{{ 'widgets.gauge.animation-elastic' | translate }}
</mat-option>
<mat-option [value]="'dequad'">
{{ 'widgets.gauge.animation-dequad' | translate }}
</mat-option>
<mat-option [value]="'dequint'">
{{ 'widgets.gauge.animation-dequint' | translate }}
</mat-option>
<mat-option [value]="'decycle'">
{{ 'widgets.gauge.animation-decycle' | translate }}
</mat-option>
<mat-option [value]="'debounce'">
{{ 'widgets.gauge.animation-debounce' | translate }}
</mat-option>
<mat-option [value]="'delastic'">
{{ 'widgets.gauge.animation-delastic' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.gauge.animation-target</mat-label>
<mat-select formControlName="animationTarget"> <mat-select formControlName="animationTarget">
<mat-option [value]="'needle'"> <mat-option [value]="'needle'">
{{ 'widgets.gauge.animation-target-needle' | translate }} {{ 'widgets.gauge.animation-target-needle' | translate }}
@ -171,8 +145,53 @@
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</section> </div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.animation-duration-rule</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput type="number" min="0" formControlName="animationDuration" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="animationRule">
<mat-option [value]="'linear'">
{{ 'widgets.gauge.animation-linear' | translate }}
</mat-option>
<mat-option [value]="'quad'">
{{ 'widgets.gauge.animation-quad' | translate }}
</mat-option>
<mat-option [value]="'quint'">
{{ 'widgets.gauge.animation-quint' | translate }}
</mat-option>
<mat-option [value]="'cycle'">
{{ 'widgets.gauge.animation-cycle' | translate }}
</mat-option>
<mat-option [value]="'bounce'">
{{ 'widgets.gauge.animation-bounce' | translate }}
</mat-option>
<mat-option [value]="'elastic'">
{{ 'widgets.gauge.animation-elastic' | translate }}
</mat-option>
<mat-option [value]="'dequad'">
{{ 'widgets.gauge.animation-dequad' | translate }}
</mat-option>
<mat-option [value]="'dequint'">
{{ 'widgets.gauge.animation-dequint' | translate }}
</mat-option>
<mat-option [value]="'decycle'">
{{ 'widgets.gauge.animation-decycle' | translate }}
</mat-option>
<mat-option [value]="'debounce'">
{{ 'widgets.gauge.animation-debounce' | translate }}
</mat-option>
<mat-option [value]="'delastic'">
{{ 'widgets.gauge.animation-delastic' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
</fieldset> </div>
</section> </ng-container>

42
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.ts

@ -19,9 +19,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { MatChipInputEvent } from '@angular/material/chips';
import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({ @Component({
selector: 'tb-analogue-compass-widget-settings', selector: 'tb-analogue-compass-widget-settings',
@ -81,6 +79,7 @@ export class AnalogueCompassWidgetSettingsComponent extends WidgetSettingsCompon
colorMinorTicks: [settings.colorMinorTicks, []], colorMinorTicks: [settings.colorMinorTicks, []],
showStrokeTicks: [settings.showStrokeTicks, []], showStrokeTicks: [settings.showStrokeTicks, []],
majorTickFont: [settings.majorTickFont, []], majorTickFont: [settings.majorTickFont, []],
majorTickColor: [settings.majorTickFont.color, []],
// Plate settings // Plate settings
colorPlate: [settings.colorPlate, []], colorPlate: [settings.colorPlate, []],
@ -131,41 +130,8 @@ export class AnalogueCompassWidgetSettingsComponent extends WidgetSettingsCompon
this.analogueCompassWidgetSettingsForm.get('animationTarget').updateValueAndValidity({emitEvent}); this.analogueCompassWidgetSettingsForm.get('animationTarget').updateValueAndValidity({emitEvent});
} }
majorTicksNamesList(): string[] { protected prepareOutputSettings(settings) {
return this.analogueCompassWidgetSettingsForm.get('majorTicks').value; settings.majorTickFont.color = this.analogueCompassWidgetSettingsForm.get('majorTickColor').value;
} return settings;
removeMajorTickName(tickName: string): void {
const tickNames: string[] = this.analogueCompassWidgetSettingsForm.get('majorTicks').value;
const index = tickNames.indexOf(tickName);
if (index >= 0) {
tickNames.splice(index, 1);
this.analogueCompassWidgetSettingsForm.get('majorTicks').setValue(tickNames);
this.analogueCompassWidgetSettingsForm.get('majorTicks').markAsDirty();
}
}
addMajorTickName(event: MatChipInputEvent): void {
const input = event.chipInput.inputElement;
const value = event.value;
const tickNames: string[] = this.analogueCompassWidgetSettingsForm.get('majorTicks').value;
if ((value || '').trim()) {
tickNames.push(value.trim());
this.analogueCompassWidgetSettingsForm.get('majorTicks').setValue(tickNames);
this.analogueCompassWidgetSettingsForm.get('majorTicks').markAsDirty();
}
if (input) {
input.value = '';
}
}
majorTickNameDrop(event: CdkDragDrop<string[]>): void {
const tickNames: string[] = this.analogueCompassWidgetSettingsForm.get('majorTicks').value;
moveItemInArray(tickNames, event.previousIndex, event.currentIndex);
this.analogueCompassWidgetSettingsForm.get('majorTicks').setValue(tickNames);
this.analogueCompassWidgetSettingsForm.get('majorTicks').markAsDirty();
} }
} }

614
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component.html

@ -15,7 +15,7 @@
limitations under the License. limitations under the License.
--> -->
<section class="tb-widget-settings" [formGroup]="analogueGaugeWidgetSettingsForm" fxLayout="column"> <ng-container [formGroup]="analogueGaugeWidgetSettingsForm">
<ng-container [ngSwitch]="gaugeType"> <ng-container [ngSwitch]="gaugeType">
<ng-container *ngSwitchCase="'radial'"> <ng-container *ngSwitchCase="'radial'">
<ng-container *ngTemplateOutlet="radialGauge; context: ctx "></ng-container> <ng-container *ngTemplateOutlet="radialGauge; context: ctx "></ng-container>
@ -24,330 +24,382 @@
<ng-container *ngTemplateOutlet="linearGauge; context: ctx "></ng-container> <ng-container *ngTemplateOutlet="linearGauge; context: ctx "></ng-container>
</ng-container> </ng-container>
</ng-container> </ng-container>
<tb-color-input
formControlName="defaultColor" <div class="tb-form-panel">
icon="format_color_fill" <div class="tb-form-panel-title" translate>widgets.gauge.ticks-settings</div>
label="{{ 'widgets.gauge.default-color' | translate }}" openOnInput colorClearButton> <div class="tb-form-row space-between column-xs">
</tb-color-input> <div translate>widgets.gauge.ticks</div>
<fieldset class="fields-group"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<legend class="group-title" translate>widgets.gauge.ticks-settings</legend> <div class="tb-small-label" translate>widgets.gauge.min-value-short</div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<mat-form-field fxFlex class="mat-block"> <input matInput formControlName="minValue" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<mat-label translate>widgets.gauge.min-value</mat-label> </mat-form-field>
<input matInput type="number" formControlName="minValue"> <div class="tb-small-label" translate>widgets.gauge.max-value-short</div>
</mat-form-field> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<mat-form-field fxFlex class="mat-block"> <input matInput formControlName="maxValue" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<mat-label translate>widgets.gauge.max-value</mat-label> </mat-form-field>
<input matInput type="number" formControlName="maxValue"> <tb-font-settings formControlName="numbersFont"
</mat-form-field> disabledLineHeight>
</section> </tb-font-settings>
<section fxLayout="column" fxLayout.gt-xs="row" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center"> <tb-color-input asBoxInput
<mat-form-field fxFlex class="mat-block"> colorClearButton
<mat-label translate>widgets.gauge.major-ticks-count</mat-label> formControlName="numbersColor">
<input matInput type="number" min="0" formControlName="majorTicksCount"> </tb-color-input>
</mat-form-field> </div>
<tb-color-input fxFlex </div>
formControlName="colorMajorTicks"
icon="format_color_fill" <div class="tb-form-row space-between column-xs">
label="{{ 'widgets.gauge.major-ticks-color' | translate }}" openOnInput colorClearButton> <div translate>widgets.gauge.major-ticks-count</div>
</tb-color-input> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
</section> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<section fxLayout="column" fxLayout.gt-xs="row" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center"> <input matInput formControlName="majorTicksCount" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
<mat-form-field fxFlex class="mat-block"> </mat-form-field>
<mat-label translate>widgets.gauge.minor-ticks-count</mat-label> <tb-color-input asBoxInput
<input matInput type="number" min="0" formControlName="minorTicks"> colorClearButton
</mat-form-field> formControlName="colorMajorTicks">
<tb-color-input fxFlex </tb-color-input>
formControlName="colorMinorTicks" </div>
icon="format_color_fill" </div>
label="{{ 'widgets.gauge.minor-ticks-color' | translate }}" openOnInput colorClearButton>
</tb-color-input> <div class="tb-form-row space-between column-xs">
</section> <div translate>widgets.gauge.minor-ticks-count</div>
<fieldset class="fields-group"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<legend class="group-title" translate>widgets.gauge.tick-numbers-font</legend> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<tb-widget-font formControlName="numbersFont"></tb-widget-font> <input matInput formControlName="minorTicks" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
</fieldset> </mat-form-field>
</fieldset> <tb-color-input asBoxInput
<fieldset class="fields-group fields-group-slider"> colorClearButton
<legend class="group-title" translate>widgets.gauge.unit-title-settings</legend> formControlName="colorMinorTicks">
<mat-expansion-panel class="tb-settings" [expanded]="analogueGaugeWidgetSettingsForm.get('showUnitTitle').value"> </tb-color-input>
<mat-expansion-panel-header fxLayout="row wrap"> </div>
<mat-panel-title> </div>
<mat-slide-toggle formControlName="showUnitTitle" (click)="$event.stopPropagation()" </div>
fxLayoutAlign="center">
{{ 'widgets.gauge.show-unit-title' | translate }} <div class="tb-form-panel">
</mat-slide-toggle> <div class="tb-form-panel-title" translate>widgets.gauge.units-settings</div>
</mat-panel-title> <div class="tb-form-row column-xs">
<mat-panel-description fxLayoutAlign="end center" fxHide.xs translate> <mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showUnitTitle">
widget-config.advanced-settings {{ 'widgets.gauge.units-title' | translate }}
</mat-panel-description> </mat-slide-toggle>
</mat-expansion-panel-header> <div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<ng-template matExpansionPanelContent> <mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
<section fxLayout="column"> <input matInput formControlName="unitTitle" placeholder="{{ 'widget-config.set' | translate }}">
<mat-form-field fxFlex class="mat-block"> </mat-form-field>
<mat-label translate>widgets.gauge.unit-title</mat-label> <tb-font-settings formControlName="titleFont"
<input matInput formControlName="unitTitle"> disabledLineHeight
</mat-form-field> [previewText]="analogueGaugeWidgetSettingsForm.get('unitTitle').value">
<fieldset class="fields-group"> </tb-font-settings>
<legend class="group-title" translate>widgets.gauge.title-font</legend> <tb-color-input asBoxInput
<tb-widget-font formControlName="titleFont"></tb-widget-font> colorClearButton
</fieldset> formControlName="titleColor">
</section> </tb-color-input>
</ng-template> </div>
</mat-expansion-panel> </div>
</fieldset>
<fieldset class="fields-group"> <div class="tb-form-row space-between">
<legend class="group-title" translate>widgets.gauge.units-settings</legend> <div translate>widget-config.units-short</div>
<fieldset class="fields-group"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<legend class="group-title" translate>widgets.gauge.units-font</legend> <tb-font-settings formControlName="unitsFont"
<tb-widget-font formControlName="unitsFont"></tb-widget-font> disabledLineHeight>
</fieldset> </tb-font-settings>
</fieldset> <tb-color-input asBoxInput
<fieldset class="fields-group fields-group-slider"> colorClearButton
<legend class="group-title" translate>widgets.gauge.value-box-settings</legend> formControlName="unitsColor">
</tb-color-input>
</div>
</div>
</div>
<div class="tb-form-panel tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="analogueGaugeWidgetSettingsForm.get('valueBox').value"> <mat-expansion-panel class="tb-settings" [expanded]="analogueGaugeWidgetSettingsForm.get('valueBox').value">
<mat-expansion-panel-header fxLayout="row wrap"> <mat-expansion-panel-header fxLayout="row wrap">
<mat-panel-title> <mat-panel-title>
<mat-slide-toggle formControlName="valueBox" (click)="$event.stopPropagation()" <mat-slide-toggle class="mat-slide" formControlName="valueBox" (click)="$event.stopPropagation()"
fxLayoutAlign="center"> fxLayoutAlign="center">
{{ 'widgets.gauge.show-value-box' | translate }} {{ 'widgets.gauge.value-box' | translate }}
</mat-slide-toggle> </mat-slide-toggle>
</mat-panel-title> </mat-panel-title>
<mat-panel-description fxLayoutAlign="end center" fxHide.xs translate> <mat-panel-description fxFlex="40" fxLayoutAlign="end center" fxHide.xs translate>
widget-config.advanced-settings widget-config.advanced-settings
</mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<section fxLayout="column"> <div class="tb-form-row space-between">
<mat-form-field fxFlex class="mat-block"> <div translate>widgets.gauge.value-int</div>
<mat-label translate>widgets.gauge.value-int</mat-label> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput type="number" min="0" step="1" formControlName="valueInt"> <input matInput type="number" min="0" step="1" formControlName="valueInt" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field> </mat-form-field>
<fieldset class="fields-group"> </div>
<legend class="group-title" translate>widgets.gauge.value-font</legend> <div class="tb-form-panel">
<tb-widget-font formControlName="valueFont" [hasShadowColor]="true"></tb-widget-font> <div class="tb-form-panel-title" translate>widgets.gauge.value-text</div>
</fieldset> <div class="tb-form-row space-between">
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> <div translate>widgets.gauge.value-text</div>
<tb-color-input fxFlex <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
formControlName="colorValueBoxRect" <tb-font-settings formControlName="valueFont"
icon="format_color_fill" disabledLineHeight>
label="{{ 'widgets.gauge.value-box-rect-stroke-color' | translate }}" openOnInput colorClearButton> </tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="valueColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.value-text-shadow</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="valueColorShadow">
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorValueBoxRectEnd" </div>
icon="format_color_fill" <div class="tb-form-panel">
label="{{ 'widgets.gauge.value-box-rect-stroke-color-end' | translate }}" openOnInput colorClearButton> <div class="tb-form-panel-title" translate>widgets.gauge.value-box</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.rect-stroke-color-start</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorValueBoxRect">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.rect-stroke-color-end</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorValueBoxRectEnd">
</tb-color-input> </tb-color-input>
</section> </div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
<tb-color-input fxFlex <div class="tb-form-row space-between">
formControlName="colorValueBoxBackground" <div translate>widgets.gauge.background-color</div>
icon="format_color_fill" <tb-color-input asBoxInput
label="{{ 'widgets.gauge.value-box-background-color' | translate }}" openOnInput colorClearButton> colorClearButton
formControlName="colorValueBoxBackground">
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorValueBoxShadow"
icon="format_color_fill" <div class="tb-form-row space-between">
label="{{ 'widgets.gauge.value-box-shadow-color' | translate }}" openOnInput colorClearButton> <div translate>widgets.gauge.shadow-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorValueBoxShadow">
</tb-color-input> </tb-color-input>
</section> </div>
</section> </div>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
</fieldset> </div>
<fieldset class="fields-group">
<legend class="group-title" translate>widgets.gauge.plate-settings</legend> <div class="tb-form-panel">
<tb-color-input fxFlex <div class="tb-form-panel-title" translate>widgets.gauge.plate-settings</div>
formControlName="colorPlate" <div class="tb-form-row space-between">
icon="format_color_fill" <div translate>widgets.gauge.plate-color</div>
label="{{ 'widgets.gauge.plate-color' | translate }}" openOnInput colorClearButton> <tb-color-input asBoxInput
</tb-color-input> colorClearButton
<mat-slide-toggle formControlName="showBorder"> formControlName="colorPlate">
{{ 'widgets.gauge.show-plate-border' | translate }}
</mat-slide-toggle>
</fieldset>
<fieldset class="fields-group">
<legend class="group-title" translate>widgets.gauge.needle-settings</legend>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
<tb-color-input fxFlex
formControlName="colorNeedle"
icon="format_color_fill"
label="{{ 'widgets.gauge.needle-color' | translate }}" openOnInput colorClearButton>
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorNeedleEnd" <div class="tb-form-row">
icon="format_color_fill" <mat-slide-toggle class="mat-slide" formControlName="showBorder">
label="{{ 'widgets.gauge.needle-color-end' | translate }}" openOnInput colorClearButton> {{ 'widgets.gauge.show-plate-border' | translate }}
</mat-slide-toggle>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.needle-settings</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.needle-color-start</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorNeedle">
</tb-color-input> </tb-color-input>
</section> </div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
<tb-color-input fxFlex <div class="tb-form-row space-between">
formControlName="colorNeedleShadowUp" <div translate>widgets.gauge.needle-color-end</div>
icon="format_color_fill" <tb-color-input asBoxInput
label="{{ 'widgets.gauge.needle-color-shadow-up' | translate }}" openOnInput colorClearButton> colorClearButton
formControlName="colorNeedleEnd">
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorNeedleShadowDown"
icon="format_color_fill" <div class="tb-form-row space-between">
label="{{ 'widgets.gauge.needle-color-shadow-down' | translate }}" openOnInput colorClearButton> <div translate>widgets.gauge.needle-color-shadow-up</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorNeedleShadowUp">
</tb-color-input> </tb-color-input>
</section> </div>
</fieldset>
<fieldset class="fields-group"> <div class="tb-form-row space-between">
<legend class="group-title" translate>widgets.gauge.highlights-settings</legend> <div translate>widgets.gauge.needle-color-shadow-down</div>
<mat-form-field fxFlex class="mat-block"> <tb-color-input asBoxInput
<mat-label translate>widgets.gauge.highlights-width</mat-label> colorClearButton
<input matInput type="number" min="0" formControlName="highlightsWidth"> formControlName="colorNeedleShadowDown">
</mat-form-field> </tb-color-input>
<fieldset class="fields-group"> </div>
<legend class="group-title" translate>widgets.gauge.highlights</legend> </div>
<div fxLayout="column">
<div class="tb-control-list tb-drop-list" cdkDropList cdkDropListOrientation="vertical" <div class="tb-form-panel">
(cdkDropListDropped)="highlightDrop($event)"> <div class="tb-form-panel-title" translate>widgets.gauge.scale-settings</div>
<div cdkDrag class="tb-draggable" *ngFor="let highlightControl of highlightsFormArray().controls; trackBy: trackByHighlightControl; <div class="tb-form-row space-between">
let $index = index; last as isLast;" <div translate>widgets.gauge.scale</div>
fxLayout="column" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-gauge-highlight [formControl]="highlightControl" <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
[expanded]="highlightControl.new" <input matInput type="number" min="0" formControlName="highlightsWidth">
(removeHighlight)="removeHighlight($index)"> </mat-form-field>
</tb-gauge-highlight> <tb-color-range-settings formControlName="highlights">
</div> </tb-color-range-settings>
</div>
<div *ngIf="!highlightsFormArray().controls.length">
<span translate fxLayoutAlign="center center"
class="tb-prompt">widgets.gauge.no-highlights</span>
</div>
<div style="padding-top: 16px;">
<button mat-raised-button color="primary"
type="button"
(click)="addHighlight()">
<span translate>widgets.gauge.add-highlight</span>
</button>
</div>
</div> </div>
</fieldset> </div>
</fieldset> </div>
<fieldset class="fields-group fields-group-slider">
<legend class="group-title" translate>widgets.gauge.animation-settings</legend> <div class="tb-form-panel tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="analogueGaugeWidgetSettingsForm.get('animation').value"> <mat-expansion-panel class="tb-settings" [expanded]="analogueGaugeWidgetSettingsForm.get('animation').value">
<mat-expansion-panel-header fxLayout="row wrap"> <mat-expansion-panel-header fxLayout="row wrap">
<mat-panel-title> <mat-panel-title>
<mat-slide-toggle formControlName="animation" (click)="$event.stopPropagation()" <mat-slide-toggle class="mat-slide" formControlName="animation" (click)="$event.stopPropagation()"
fxLayoutAlign="center"> fxLayoutAlign="center">
{{ 'widgets.gauge.enable-animation' | translate }} {{ 'widgets.gauge.enable-animation' | translate }}
</mat-slide-toggle> </mat-slide-toggle>
</mat-panel-title> </mat-panel-title>
<mat-panel-description fxLayoutAlign="end center" fxHide.xs translate> <mat-panel-description fxFlex="40" fxLayoutAlign="end center" fxHide.xs translate>
widget-config.advanced-settings widget-config.advanced-settings
</mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<section fxLayout="column"> <div class="tb-form-row space-between">
<mat-form-field fxFlex class="mat-block"> <div translate>widgets.gauge.animation-duration-rule</div>
<mat-label translate>widgets.gauge.animation-duration</mat-label> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<input matInput type="number" min="0" formControlName="animationDuration"> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
</mat-form-field> <input matInput type="number" min="0" formControlName="animationDuration" placeholder="{{ 'widget-config.set' | translate }}">
<mat-form-field fxFlex class="mat-block"> </mat-form-field>
<mat-label translate>widgets.gauge.animation-rule</mat-label> <mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="animationRule"> <mat-select formControlName="animationRule">
<mat-option [value]="'linear'"> <mat-option [value]="'linear'">
{{ 'widgets.gauge.animation-linear' | translate }} {{ 'widgets.gauge.animation-linear' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'quad'"> <mat-option [value]="'quad'">
{{ 'widgets.gauge.animation-quad' | translate }} {{ 'widgets.gauge.animation-quad' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'quint'"> <mat-option [value]="'quint'">
{{ 'widgets.gauge.animation-quint' | translate }} {{ 'widgets.gauge.animation-quint' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'cycle'"> <mat-option [value]="'cycle'">
{{ 'widgets.gauge.animation-cycle' | translate }} {{ 'widgets.gauge.animation-cycle' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'bounce'"> <mat-option [value]="'bounce'">
{{ 'widgets.gauge.animation-bounce' | translate }} {{ 'widgets.gauge.animation-bounce' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'elastic'"> <mat-option [value]="'elastic'">
{{ 'widgets.gauge.animation-elastic' | translate }} {{ 'widgets.gauge.animation-elastic' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'dequad'"> <mat-option [value]="'dequad'">
{{ 'widgets.gauge.animation-dequad' | translate }} {{ 'widgets.gauge.animation-dequad' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'dequint'"> <mat-option [value]="'dequint'">
{{ 'widgets.gauge.animation-dequint' | translate }} {{ 'widgets.gauge.animation-dequint' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'decycle'"> <mat-option [value]="'decycle'">
{{ 'widgets.gauge.animation-decycle' | translate }} {{ 'widgets.gauge.animation-decycle' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'debounce'"> <mat-option [value]="'debounce'">
{{ 'widgets.gauge.animation-debounce' | translate }} {{ 'widgets.gauge.animation-debounce' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'delastic'"> <mat-option [value]="'delastic'">
{{ 'widgets.gauge.animation-delastic' | translate }} {{ 'widgets.gauge.animation-delastic' | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</section> </div>
</div>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
</fieldset> </div>
</section> </ng-container>
<ng-template #radialGauge let-settingsForm="settingsForm"> <ng-template #radialGauge let-settingsForm="settingsForm">
<fieldset class="fields-group" [formGroup]="settingsForm"> <div class="tb-form-panel" [formGroup]="settingsForm">
<legend class="group-title" translate>widgets.gauge.radial-gauge-settings</legend> <div class="tb-form-panel-title" translate>widgets.gauge.radial-gauge-settings</div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center"> <div class="tb-form-row space-between">
<mat-form-field fxFlex class="mat-block"> <div translate>widgets.gauge.start-ticks-angle</div>
<mat-label translate>widgets.gauge.start-ticks-angle</mat-label> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput type="number" min="0" max="360" formControlName="startAngle"> <input matInput formControlName="startAngle" type="number" min="0" max="360" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.ticks-angle</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="ticksAngle" type="number" min="0" max="360" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex class="mat-block"> </div>
<mat-label translate>widgets.gauge.ticks-angle</mat-label> <div class="tb-form-row space-between">
<input matInput type="number" min="0" max="360" formControlName="ticksAngle"> <div translate>widgets.gauge.needle-circle-size</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="needleCircleSize" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field> </mat-form-field>
</section> </div>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.gauge.needle-circle-size</mat-label> <ng-container *ngTemplateOutlet="arrowScaleDefaultColor"></ng-container>
<input matInput type="number" min="0" formControlName="needleCircleSize"> </div>
</mat-form-field>
</fieldset>
</ng-template> </ng-template>
<ng-template #linearGauge let-settingsForm="settingsForm"> <ng-template #linearGauge let-settingsForm="settingsForm">
<fieldset class="fields-group" [formGroup]="settingsForm"> <div class="tb-form-panel" [formGroup]="settingsForm">
<legend class="group-title" translate>widgets.gauge.linear-gauge-settings</legend> <div class="tb-form-panel-title" translate>widgets.gauge.linear-gauge-settings</div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> <div class="tb-form-row space-between">
<mat-form-field fxFlex class="mat-block"> <div translate>widgets.gauge.bar-stroke</div>
<mat-label translate>widgets.gauge.bar-stroke-width</mat-label> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<input matInput type="number" min="0" formControlName="barStrokeWidth"> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
</mat-form-field> <input matInput type="number" min="0" formControlName="barStrokeWidth" placeholder="{{ 'widget-config.set' | translate }}">
<tb-color-input fxFlex </mat-form-field>
formControlName="colorBarStroke" <tb-color-input asBoxInput
icon="format_color_fill" colorClearButton
label="{{ 'widgets.gauge.bar-stroke-color' | translate }}" openOnInput colorClearButton> formControlName="colorBar">
</tb-color-input> </tb-color-input>
</section> </div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> </div>
<tb-color-input fxFlex
formControlName="colorBar" <div class="tb-form-row space-between">
icon="format_color_fill" <div translate>widgets.gauge.bar-background-color</div>
label="{{ 'widgets.gauge.bar-background-color' | translate }}" openOnInput colorClearButton> <tb-color-input asBoxInput
colorClearButton
formControlName="colorBar">
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorBarEnd" <div class="tb-form-row space-between">
icon="format_color_fill" <div translate>widgets.gauge.bar-background-color-end</div>
label="{{ 'widgets.gauge.bar-background-color-end' | translate }}" openOnInput colorClearButton> <tb-color-input asBoxInput
colorClearButton
formControlName="colorBarEnd">
</tb-color-input> </tb-color-input>
</section> </div>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
<tb-color-input fxFlex <div class="tb-form-row space-between">
formControlName="colorBarProgress" <div translate>widgets.gauge.progress-bar-color-start</div>
icon="format_color_fill" <tb-color-input asBoxInput
label="{{ 'widgets.gauge.progress-bar-color' | translate }}" openOnInput colorClearButton> colorClearButton
formControlName="colorBarProgress">
</tb-color-input> </tb-color-input>
<tb-color-input fxFlex </div>
formControlName="colorBarProgressEnd" <div class="tb-form-row space-between">
icon="format_color_fill" <div translate>widgets.gauge.progress-bar-color-end</div>
label="{{ 'widgets.gauge.progress-bar-color-end' | translate }}" openOnInput colorClearButton> <tb-color-input asBoxInput
colorClearButton
formControlName="colorBarProgressEnd">
</tb-color-input> </tb-color-input>
</section> </div>
</fieldset> <ng-container *ngTemplateOutlet="arrowScaleDefaultColor"></ng-container>
</div>
</ng-template>
<ng-template #arrowScaleDefaultColor>
<div class="tb-form-row space-between" [formGroup]="analogueGaugeWidgetSettingsForm">
<div>{{ 'widgets.gauge.arrow-and-scale-color' | translate }}</div>
<tb-color-input asBoxInput
formControlName="defaultColor">
</tb-color-input>
</div>
</ng-template> </ng-template>

70
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component.ts

@ -15,11 +15,9 @@
/// ///
import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { GaugeHighlight } from '@home/components/widget/lib/settings/gauge/gauge-highlight.component';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponent { export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponent {
@ -119,19 +117,24 @@ export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponen
minorTicks: [settings.majorTicksCount, [Validators.min(0)]], minorTicks: [settings.majorTicksCount, [Validators.min(0)]],
colorMinorTicks: [settings.colorMinorTicks, []], colorMinorTicks: [settings.colorMinorTicks, []],
numbersFont: [settings.numbersFont, []], numbersFont: [settings.numbersFont, []],
numbersColor: [settings.numbersFont.color, []],
// Unit title settings // Unit title settings
showUnitTitle: [settings.showUnitTitle, []], showUnitTitle: [settings.showUnitTitle, []],
unitTitle: [settings.unitTitle, []], unitTitle: [settings.unitTitle, []],
titleFont: [settings.titleFont, []], titleFont: [settings.titleFont, []],
titleColor: [settings.titleFont.color, []],
// Units settings // Units settings
unitsFont: [settings.unitsFont, []], unitsFont: [settings.unitsFont, []],
unitsColor: [settings.unitsFont.color, []],
// Value box settings // Value box settings
valueBox: [settings.valueBox, []], valueBox: [settings.valueBox, []],
valueInt: [settings.valueInt, [Validators.min(0)]], valueInt: [settings.valueInt, [Validators.min(0)]],
valueFont: [settings.valueFont, []], valueFont: [settings.valueFont, []],
valueColor: [settings.valueFont.color, []],
valueColorShadow: [settings.valueFont.shadowColor, []],
colorValueBoxRect: [settings.colorValueBoxRect, []], colorValueBoxRect: [settings.colorValueBoxRect, []],
colorValueBoxRectEnd: [settings.colorValueBoxRectEnd, []], colorValueBoxRectEnd: [settings.colorValueBoxRectEnd, []],
colorValueBoxBackground: [settings.colorValueBoxBackground, []], colorValueBoxBackground: [settings.colorValueBoxBackground, []],
@ -149,7 +152,7 @@ export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponen
// Highlights settings // Highlights settings
highlightsWidth: [settings.highlightsWidth, [Validators.min(0)]], highlightsWidth: [settings.highlightsWidth, [Validators.min(0)]],
highlights: this.prepareHighlightsFormArray(settings.highlights), highlights: [settings.highlights, []],
// Animation settings // Animation settings
animation: [settings.animation, []], animation: [settings.animation, []],
@ -170,13 +173,16 @@ export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponen
if (showUnitTitle) { if (showUnitTitle) {
this.analogueGaugeWidgetSettingsForm.get('unitTitle').enable(); this.analogueGaugeWidgetSettingsForm.get('unitTitle').enable();
this.analogueGaugeWidgetSettingsForm.get('titleFont').enable(); this.analogueGaugeWidgetSettingsForm.get('titleFont').enable();
this.analogueGaugeWidgetSettingsForm.get('titleColor').enable();
} else { } else {
this.analogueGaugeWidgetSettingsForm.get('unitTitle').disable(); this.analogueGaugeWidgetSettingsForm.get('unitTitle').disable();
this.analogueGaugeWidgetSettingsForm.get('titleFont').disable(); this.analogueGaugeWidgetSettingsForm.get('titleFont').disable();
this.analogueGaugeWidgetSettingsForm.get('titleColor').disable();
} }
if (valueBox) { if (valueBox) {
this.analogueGaugeWidgetSettingsForm.get('valueInt').enable(); this.analogueGaugeWidgetSettingsForm.get('valueInt').enable();
this.analogueGaugeWidgetSettingsForm.get('valueFont').enable(); this.analogueGaugeWidgetSettingsForm.get('valueFont').enable();
this.analogueGaugeWidgetSettingsForm.get('valueColor').enable();
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRect').enable(); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRect').enable();
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRectEnd').enable(); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRectEnd').enable();
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxBackground').enable(); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxBackground').enable();
@ -184,6 +190,7 @@ export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponen
} else { } else {
this.analogueGaugeWidgetSettingsForm.get('valueInt').disable(); this.analogueGaugeWidgetSettingsForm.get('valueInt').disable();
this.analogueGaugeWidgetSettingsForm.get('valueFont').disable(); this.analogueGaugeWidgetSettingsForm.get('valueFont').disable();
this.analogueGaugeWidgetSettingsForm.get('valueColor').disable();
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRect').disable(); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRect').disable();
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRectEnd').disable(); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRectEnd').disable();
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxBackground').disable(); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxBackground').disable();
@ -198,8 +205,10 @@ export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponen
} }
this.analogueGaugeWidgetSettingsForm.get('unitTitle').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('unitTitle').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('titleFont').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('titleFont').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('titleColor').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('valueInt').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('valueInt').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('valueFont').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('valueFont').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('valueColor').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRect').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRect').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRectEnd').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxRectEnd').updateValueAndValidity({emitEvent});
this.analogueGaugeWidgetSettingsForm.get('colorValueBoxBackground').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('colorValueBoxBackground').updateValueAndValidity({emitEvent});
@ -208,50 +217,17 @@ export class AnalogueGaugeWidgetSettingsComponent extends WidgetSettingsComponen
this.analogueGaugeWidgetSettingsForm.get('animationRule').updateValueAndValidity({emitEvent}); this.analogueGaugeWidgetSettingsForm.get('animationRule').updateValueAndValidity({emitEvent});
} }
protected doUpdateSettings(settingsForm: UntypedFormGroup, settings: WidgetSettings) { protected prepareOutputSettings(settings) {
settingsForm.setControl('highlights', this.prepareHighlightsFormArray(settings.highlights), {emitEvent: false}); settings.numbersFont.color = this.analogueGaugeWidgetSettingsForm.get('numbersColor').value;
} if (settings.titleFont) {
settings.titleFont.color = this.analogueGaugeWidgetSettingsForm.get('titleColor').value;
private prepareHighlightsFormArray(highlights: GaugeHighlight[] | undefined): UntypedFormArray {
const highlightsControls: Array<AbstractControl> = [];
if (highlights) {
highlights.forEach((highlight) => {
highlightsControls.push(this.fb.control(highlight, [Validators.required]));
});
} }
return this.fb.array(highlightsControls); settings.unitsFont.color = this.analogueGaugeWidgetSettingsForm.get('unitsColor').value;
} if (settings.valueFont) {
settings.valueFont.color = this.analogueGaugeWidgetSettingsForm.get('valueColor').value;
highlightsFormArray(): UntypedFormArray { settings.valueFont.shadowColor = this.analogueGaugeWidgetSettingsForm.get('valueColorShadow').value;
return this.analogueGaugeWidgetSettingsForm.get('highlights') as UntypedFormArray; }
} return settings;
public trackByHighlightControl(index: number, highlightControl: AbstractControl): any {
return highlightControl;
}
public removeHighlight(index: number) {
(this.analogueGaugeWidgetSettingsForm.get('highlights') as UntypedFormArray).removeAt(index);
}
public addHighlight() {
const highlight: GaugeHighlight = {
from: null,
to: null,
color: null
};
const highlightsArray = this.analogueGaugeWidgetSettingsForm.get('highlights') as UntypedFormArray;
const highlightControl = this.fb.control(highlight, [Validators.required]);
(highlightControl as any).new = true;
highlightsArray.push(highlightControl);
this.analogueGaugeWidgetSettingsForm.updateValueAndValidity();
}
highlightDrop(event: CdkDragDrop<string[]>) {
const highlightsArray = this.analogueGaugeWidgetSettingsForm.get('highlights') as UntypedFormArray;
const highlight = highlightsArray.at(event.previousIndex);
highlightsArray.removeAt(event.previousIndex);
highlightsArray.insert(event.currentIndex, highlight);
} }
} }

61
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.html

@ -1,61 +0,0 @@
<!--
Copyright © 2016-2023 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-expansion-panel class="gauge-highlight" fxFlex [formGroup]="gaugeHighlightFormGroup" [(expanded)]="expanded">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div>{{ highlightRangeText() }}</div>
<div class="tb-color-preview" style="margin-left: 6px;">
<div class="tb-color-result" [ngStyle]="{background: gaugeHighlightFormGroup.get('color').value}"></div>
</div>
</div>
</mat-panel-title>
<span fxFlex></span>
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeHighlight.emit()"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<section class="tb-widget-settings" fxLayout="column">
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center">
<mat-form-field fxFlex>
<mat-label translate>widgets.gauge.highlight-from</mat-label>
<input matInput type="number" formControlName="from">
</mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>widgets.gauge.highlight-to</mat-label>
<input matInput type="number" formControlName="to">
</mat-form-field>
</section>
<tb-color-input
formControlName="color"
icon="format_color_fill"
label="{{ 'widgets.gauge.highlight-color' | translate }}" openOnInput colorClearButton>
</tb-color-input>
</section>
</div>
</ng-template>
</mat-expansion-panel>

40
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.scss

@ -1,40 +0,0 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
:host {
display: block;
.mat-expansion-panel {
box-shadow: none;
&.gauge-highlight {
border: 1px groove rgba(0, 0, 0, .25);
.mat-expansion-panel-header {
padding: 0 24px 0 8px;
&.mat-expanded {
height: 48px;
}
}
}
}
}
:host ::ng-deep {
.mat-expansion-panel {
&.gauge-highlight {
.mat-expansion-panel-body {
padding: 0 8px 8px;
}
}
}
}

116
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.ts

@ -1,116 +0,0 @@
///
/// Copyright © 2016-2023 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core';
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { TranslateService } from '@ngx-translate/core';
import { isNumber } from '@core/utils';
export interface GaugeHighlight {
from: number;
to: number;
color: string;
}
@Component({
selector: 'tb-gauge-highlight',
templateUrl: './gauge-highlight.component.html',
styleUrls: ['./gauge-highlight.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => GaugeHighlightComponent),
multi: true
}
]
})
export class GaugeHighlightComponent extends PageComponent implements OnInit, ControlValueAccessor {
@Input()
disabled: boolean;
@Input()
expanded = false;
@Output()
removeHighlight = new EventEmitter();
private modelValue: GaugeHighlight;
private propagateChange = null;
public gaugeHighlightFormGroup: UntypedFormGroup;
constructor(protected store: Store<AppState>,
private translate: TranslateService,
private fb: UntypedFormBuilder) {
super(store);
}
ngOnInit(): void {
this.gaugeHighlightFormGroup = this.fb.group({
from: [null, []],
to: [null, []],
color: [null, []]
});
this.gaugeHighlightFormGroup.valueChanges.subscribe(() => {
this.updateModel();
});
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {
}
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
if (isDisabled) {
this.gaugeHighlightFormGroup.disable({emitEvent: false});
} else {
this.gaugeHighlightFormGroup.enable({emitEvent: false});
}
}
writeValue(value: GaugeHighlight): void {
this.modelValue = value;
this.gaugeHighlightFormGroup.patchValue(
value, {emitEvent: false}
);
}
highlightRangeText(): string {
const value: GaugeHighlight = this.gaugeHighlightFormGroup.value;
const from = isNumber(value.from) ? value.from : 0;
const to = isNumber(value.to) ? value.to : 0;
return `${from} - ${to}`;
}
private updateModel() {
const value: GaugeHighlight = this.gaugeHighlightFormGroup.value;
this.modelValue = value;
if (this.gaugeHighlightFormGroup.valid) {
this.propagateChange(this.modelValue);
} else {
this.propagateChange(null);
}
}
}

3
ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts

@ -58,7 +58,6 @@ import {
import { import {
AlarmsTableKeySettingsComponent AlarmsTableKeySettingsComponent
} from '@home/components/widget/lib/settings/alarm/alarms-table-key-settings.component'; } from '@home/components/widget/lib/settings/alarm/alarms-table-key-settings.component';
import { GaugeHighlightComponent } from '@home/components/widget/lib/settings/gauge/gauge-highlight.component';
import { import {
AnalogueRadialGaugeWidgetSettingsComponent AnalogueRadialGaugeWidgetSettingsComponent
} from '@home/components/widget/lib/settings/gauge/analogue-radial-gauge-widget-settings.component'; } from '@home/components/widget/lib/settings/gauge/analogue-radial-gauge-widget-settings.component';
@ -321,7 +320,6 @@ import {
EntitiesTableKeySettingsComponent, EntitiesTableKeySettingsComponent,
AlarmsTableWidgetSettingsComponent, AlarmsTableWidgetSettingsComponent,
AlarmsTableKeySettingsComponent, AlarmsTableKeySettingsComponent,
GaugeHighlightComponent,
AnalogueRadialGaugeWidgetSettingsComponent, AnalogueRadialGaugeWidgetSettingsComponent,
AnalogueLinearGaugeWidgetSettingsComponent, AnalogueLinearGaugeWidgetSettingsComponent,
AnalogueCompassWidgetSettingsComponent, AnalogueCompassWidgetSettingsComponent,
@ -438,7 +436,6 @@ import {
EntitiesTableKeySettingsComponent, EntitiesTableKeySettingsComponent,
AlarmsTableWidgetSettingsComponent, AlarmsTableWidgetSettingsComponent,
AlarmsTableKeySettingsComponent, AlarmsTableKeySettingsComponent,
GaugeHighlightComponent,
AnalogueRadialGaugeWidgetSettingsComponent, AnalogueRadialGaugeWidgetSettingsComponent,
AnalogueLinearGaugeWidgetSettingsComponent, AnalogueLinearGaugeWidgetSettingsComponent,
AnalogueCompassWidgetSettingsComponent, AnalogueCompassWidgetSettingsComponent,

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

@ -5008,6 +5008,7 @@
"title-icon": "Title icon", "title-icon": "Title icon",
"display-icon": "Display title icon", "display-icon": "Display title icon",
"card-icon": "Card icon", "card-icon": "Card icon",
"icon": "Icon",
"icon-color": "Icon color", "icon-color": "Icon color",
"icon-size": "Icon size", "icon-size": "Icon size",
"advanced-settings": "Advanced settings", "advanced-settings": "Advanced settings",
@ -5354,10 +5355,14 @@
"ticks-settings": "Ticks settings", "ticks-settings": "Ticks settings",
"min-value": "Minimum value", "min-value": "Minimum value",
"max-value": "Maximum value", "max-value": "Maximum value",
"min-value-short": "min",
"max-value-short": "max",
"start-ticks-angle": "Start ticks angle", "start-ticks-angle": "Start ticks angle",
"ticks-angle": "Ticks angle", "ticks-angle": "Ticks angle",
"major-ticks": "Major ticks",
"major-ticks-count": "Major ticks count", "major-ticks-count": "Major ticks count",
"major-ticks-color": "Major ticks color", "major-ticks-color": "Major ticks color",
"minor-ticks": "Minor ticks",
"minor-ticks-count": "Minor ticks count", "minor-ticks-count": "Minor ticks count",
"minor-ticks-color": "Minor ticks color", "minor-ticks-color": "Minor ticks color",
"tick-numbers-font": "Tick numbers font", "tick-numbers-font": "Tick numbers font",
@ -5369,21 +5374,29 @@
"units-font": "Units text font", "units-font": "Units text font",
"value-box-settings": "Value box settings", "value-box-settings": "Value box settings",
"show-value-box": "Show value box", "show-value-box": "Show value box",
"value-box": "Value box",
"value-int": "Digits count for integer part of value", "value-int": "Digits count for integer part of value",
"value-text": "Value text",
"value-text-shadow": "Value text shadow",
"value-font": "Value text font", "value-font": "Value text font",
"rect-stroke-color-start": "Rectangle stroke color - start gradient",
"rect-stroke-color-end": "Rectangle stroke color - end gradient",
"background-color": "Background color",
"shadow-color": "Shadow color",
"value-box-rect-stroke-color": "Value box rectangle stroke color", "value-box-rect-stroke-color": "Value box rectangle stroke color",
"value-box-rect-stroke-color-end": "Value box rectangle stroke color - end gradient", "value-box-rect-stroke-color-end": "Value box rectangle stroke color - end gradient",
"value-box-background-color": "Value box background color", "value-box-background-color": "Value box background color",
"value-box-shadow-color": "Value box shadow color", "value-box-shadow-color": "Value box shadow color",
"plate-settings": "Plate settings", "plate-settings": "Plate settings",
"show-plate-border": "Show plate border", "show-plate-border": "Plate border",
"plate-color": "Plate color", "plate-color": "Plate color",
"needle-settings": "Needle settings", "needle-settings": "Needle settings",
"needle-circle-size": "Needle circle size", "needle-circle-size": "Needle circle size",
"needle-color": "Needle color", "needle-color": "Needle color",
"needle-color-start": "Needle color - start gradient",
"needle-color-end": "Needle color - end gradient", "needle-color-end": "Needle color - end gradient",
"needle-color-shadow-up": "Upper half of the needle shadow color", "needle-color-shadow-up": "Upper half of the needle shadow color",
"needle-color-shadow-down": "Drop shadow needle color", "needle-color-shadow-down": "Drop shadow",
"highlights-settings": "Highlights settings", "highlights-settings": "Highlights settings",
"highlights-width": "Highlights width", "highlights-width": "Highlights width",
"highlights": "Highlights", "highlights": "Highlights",
@ -5393,7 +5406,8 @@
"no-highlights": "No highlights configured", "no-highlights": "No highlights configured",
"add-highlight": "Add highlight", "add-highlight": "Add highlight",
"animation-settings": "Animation settings", "animation-settings": "Animation settings",
"enable-animation": "Enable animation", "enable-animation": "Animation",
"animation-duration-rule": "Animation duration and rule",
"animation-duration": "Animation duration", "animation-duration": "Animation duration",
"animation-rule": "Animation rule", "animation-rule": "Animation rule",
"animation-linear": "Linear", "animation-linear": "Linear",
@ -5408,17 +5422,21 @@
"animation-debounce": "Debounce", "animation-debounce": "Debounce",
"animation-delastic": "Delastic", "animation-delastic": "Delastic",
"linear-gauge-settings": "Linear gauge settings", "linear-gauge-settings": "Linear gauge settings",
"bar-stroke": "Bar stroke",
"bar-stroke-width": "Bar stroke width", "bar-stroke-width": "Bar stroke width",
"bar-stroke-color": "Bar stroke color", "bar-stroke-color": "Bar stroke color",
"bar-background-color": "Gauge bar background color", "bar-background-color": "Bar background color - start gradient",
"bar-background-color-end": "Bar background color - end gradient", "bar-background-color-end": "Bar background color - end gradient",
"progress-bar-color": "Progress bar color", "progress-bar-color": "Progress bar color",
"progress-bar": "Progress bar",
"progress-bar-color-start": "Progress bar color - start gradient",
"progress-bar-color-end": "Progress bar color - end gradient", "progress-bar-color-end": "Progress bar color - end gradient",
"major-ticks-names": "Major ticks names", "major-ticks-names": "Major ticks names",
"show-stroke-ticks": "Show ticks stroke", "show-stroke-ticks": "Show ticks stroke",
"major-ticks-font": "Major ticks font", "major-ticks-font": "Major ticks font",
"border-color": "Border color", "border-color": "Border color",
"border-width": "Border width", "border-width": "Border width",
"needle-circle": "Needle circle",
"needle-circle-color": "Needle circle color", "needle-circle-color": "Needle circle color",
"animation-target": "Animation target", "animation-target": "Animation target",
"animation-target-needle": "Needle", "animation-target-needle": "Needle",
@ -5462,7 +5480,18 @@
"tick-color": "Tick color", "tick-color": "Tick color",
"tick-values": "Tick values", "tick-values": "Tick values",
"no-tick-values": "No tick values configured", "no-tick-values": "No tick values configured",
"add-tick-value": "Add tick value" "add-tick-value": "Add tick value",
"gauge-appearance": "Gauge appearance",
"units-title": "Units title",
"value": "Value",
"ticks": "Ticks",
"arrow-and-scale-color": "Arrow and scale default color",
"scale-settings": "Scale settings",
"scale": "Scale",
"scale-color": "Scale colors",
"compass-appearance": "Compass appearance",
"labels": "Labels",
"label-style": "Label style"
}, },
"gpio": { "gpio": {
"pin": "Pin", "pin": "Pin",

Loading…
Cancel
Save