thingsboard-aplcache
Changes
ui/src/app/widget/lib/CanvasDigitalGauge.js 19(+17 -2)
ui/src/app/widget/lib/rpc/knob.svg 32(+32 -0)
ui/src/app/widget/lib/rpc/shiny-knob.scss 52(+37 -15)
Details
diff --git a/application/src/main/data/json/system/widget_bundles/control_widgets.json b/application/src/main/data/json/system/widget_bundles/control_widgets.json
index b06c979..a1cd3c9 100644
--- a/application/src/main/data/json/system/widget_bundles/control_widgets.json
+++ b/application/src/main/data/json/system/widget_bundles/control_widgets.json
@@ -42,11 +42,11 @@
"name": "Shiny Knob Control",
"descriptor": {
"type": "rpc",
- "sizeX": 2.5,
- "sizeY": 3,
+ "sizeX": 4,
+ "sizeY": 3.5,
"resources": [],
"templateHtml": "<tb-shiny-knob ctx='ctx'></tb-shiny-knob>",
- "templateCss": ".error {\n font-size: 14px !important;\n color: maroon;/*rgb(250,250,250);*/\n background-color: transparent;\n padding: 6px;\n}\n\n.error span {\n margin: auto;\n}\n\n.gpio-panel {\n padding-top: 10px;\n white-space: nowrap;\n}\n\n.switch-panel {\n margin: 0;\n height: 32px;\n width: 66px;\n min-width: 66px;\n}\n\n.switch-panel md-switch {\n margin: 0;\n width: 36px;\n min-width: 36px;\n}\n\n.switch-panel md-switch > div.md-container {\n margin: 0;\n}\n\n.switch-panel.col-0 md-switch {\n padding-left: 8px;\n padding-right: 4px;\n}\n\n.switch-panel.col-1 md-switch {\n padding-left: 4px;\n padding-right: 8px;\n}\n\n.gpio-row {\n height: 32px;\n}\n\n.pin {\n margin-top: auto;\n margin-bottom: auto;\n color: white;\n font-size: 12px;\n width: 16px;\n min-width: 16px;\n}\n\n.switch-panel.col-0 .pin {\n margin-left: auto;\n padding-left: 2px;\n text-align: right;\n}\n\n.switch-panel.col-1 .pin {\n margin-right: auto;\n \n text-align: left;\n}\n\n.gpio-left-label {\n margin-right: 8px;\n}\n\n.gpio-right-label {\n margin-left: 8px;\n}",
+ "templateCss": "",
"controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}\n\nself.onResize = function() {\n if (self.ctx.resize) {\n self.ctx.resize();\n }\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"minValue\": {\n \"title\": \"Minimum value\",\n \"type\": \"number\",\n \"default\": 0\n },\n \"maxValue\": {\n \"title\": \"Maximum value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"number\",\n \"default\": 50\n },\n \"theme\": {\n \"title\": \"Knob theme\",\n \"type\": \"string\",\n \"default\": \"light\"\n }, \n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"minValue\", \"maxValue\", \"requestTimeout\"]\n },\n \"form\": [\n \"minValue\",\n \"maxValue\",\n \"initialValue\",\n {\n \"key\": \"theme\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"light\",\n \"label\": \"Light\"\n },\n {\n \"value\": \"dark\",\n \"label\": \"Dark\"\n }\n ]\n },\n \"requestTimeout\"\n ]\n}",
"dataKeySettingsSchema": "{}\n",
ui/src/app/widget/lib/CanvasDigitalGauge.js 19(+17 -2)
diff --git a/ui/src/app/widget/lib/CanvasDigitalGauge.js b/ui/src/app/widget/lib/CanvasDigitalGauge.js
index e6c2e27..1a40235 100644
--- a/ui/src/app/widget/lib/CanvasDigitalGauge.js
+++ b/ui/src/app/widget/lib/CanvasDigitalGauge.js
@@ -238,6 +238,21 @@ export default class CanvasDigitalGauge extends canvasGauges.BaseGauge {
return this;
}
+ getValueColor() {
+ if (this.contextProgressClone) {
+ var color = this.contextProgressClone.currentColor;
+ if (!color) {
+ if (this.options.neonGlowBrightness) {
+ color = getProgressColor(0, this.options.neonColorsRange);
+ } else {
+ color = getProgressColor(0, this.options.colorsRange);
+ }
+ }
+ return color;
+ } else {
+ return '#000';
+ }
+ }
}
/* eslint-disable angular/document-service */
@@ -666,9 +681,9 @@ function drawBarGlow(context, startX, startY, endX, endY, color, strokeWidth, is
function drawProgress(context, options, progress) {
var neonColor;
if (options.neonGlowBrightness) {
- neonColor = getProgressColor(progress, options.neonColorsRange);
+ context.currentColor = neonColor = getProgressColor(progress, options.neonColorsRange);
} else {
- context.strokeStyle = getProgressColor(progress, options.colorsRange);
+ context.currentColor = context.strokeStyle = getProgressColor(progress, options.colorsRange);
}
let {barLeft, barRight, barTop, baseX, width, barBottom, Cx, Cy, Rm, Ro, Ri, strokeWidth} =
ui/src/app/widget/lib/rpc/knob.svg 32(+32 -0)
diff --git a/ui/src/app/widget/lib/rpc/knob.svg b/ui/src/app/widget/lib/rpc/knob.svg
new file mode 100644
index 0000000..d75c2b1
--- /dev/null
+++ b/ui/src/app/widget/lib/rpc/knob.svg
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg id="svg52850" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="28.222mm" width="28.222mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 99.999997 99.999997" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <defs id="defs52852">
+ <radialGradient id="radialGradient52746-69" xlink:href="#linearGradient53063" gradientUnits="userSpaceOnUse" cy="990.69" cx="1006.1" gradientTransform="matrix(.0028197 -2.0966 3.8027 .0051141 -2863.2 3472.2)" r="86.621"/>
+ <linearGradient id="linearGradient53063">
+ <stop id="stop53065" stop-color="#b5b5b5" offset="0"/>
+ <stop id="stop53067" stop-color="#f5f5f5" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient52746-69-7-0" gradientUnits="userSpaceOnUse" cy="990.69" cx="1006.1" gradientTransform="matrix(.0016764 -1.2465 2.2609 .0030406 -3150 20.652)" r="86.621">
+ <stop id="stop53119" stop-color="#808080" offset="0"/>
+ <stop id="stop53121" stop-color="#fdfdfd" offset="1"/>
+ </radialGradient>
+ <radialGradient id="radialGradient52746-69-7" xlink:href="#linearGradient53063" gradientUnits="userSpaceOnUse" cy="990.69" cx="1006.1" gradientTransform="matrix(.0016276 -1.2102 2.195 .002952 -3084.7 -17.281)" r="86.621"/>
+ </defs>
+ <metadata id="metadata52855">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g id="layer1" transform="translate(-330.69 -606.32)">
+ <g id="g53154" transform="matrix(.40816 -.40816 .40816 .40816 -513.05 503.76)">
+ <circle id="path52738-5" cy="1281.7" cx="907.94" r="86.621" fill="url(#radialGradient52746-69)"/>
+ <circle id="path52738-5-3-6" transform="scale(-1)" cy="-1281.7" cx="-907.94" r="51.5" fill="url(#radialGradient52746-69-7-0)"/>
+ <circle id="path52738-5-3" transform="scale(-1)" cy="-1281.7" cx="-907.94" r="50" fill="url(#radialGradient52746-69-7)"/>
+ </g>
+ </g>
+</svg>
diff --git a/ui/src/app/widget/lib/rpc/shiny-knob.directive.js b/ui/src/app/widget/lib/rpc/shiny-knob.directive.js
index b186799..e79f03b 100644
--- a/ui/src/app/widget/lib/rpc/shiny-knob.directive.js
+++ b/ui/src/app/widget/lib/rpc/shiny-knob.directive.js
@@ -17,7 +17,6 @@
import './shiny-knob.scss';
import CanvasDigitalGauge from './../CanvasDigitalGauge';
-//import tinycolor from 'tinycolor2';
/* eslint-disable import/no-unresolved, import/default */
@@ -53,7 +52,11 @@ function ShinyKnobController($element, $scope, $document) {
var knob = angular.element('.knob', $element),
knobContainer = angular.element('#knob-container', $element),
- knobTop = knob.find('.top'),
+ // knobTop = knob.find('.top'),
+ knobTopPointerContainer = knob.find('.top-pointer-container'),
+ knobTopPointer = knob.find('.top-pointer'),
+ knobValueBackground = knob.find('.value-background'),
+ knobValue = knob.find('.knob-value'),
startDeg = -1,
currentDeg = 0,
rotation = 0,
@@ -61,7 +64,7 @@ function ShinyKnobController($element, $scope, $document) {
var canvasBarElement = angular.element('#canvasBar', $element);
- var levelColors = ['rgb(0, 128, 0)', 'rgb(251, 192, 45)', 'rgb(244, 67, 54)'];
+ var levelColors = ['rgb(0, 128, 0)', 'rgb(251, 192, 45)', 'rgb(255, 0, 0)'];//['cyan'];//
var canvasBar;
$scope.$watch('vm.ctx', () => {
@@ -80,14 +83,14 @@ function ShinyKnobController($element, $scope, $document) {
var canvasBarData = {
renderTo: canvasBarElement[0],
hideValue: true,
- neonGlowBrightness: vm.darkTheme ? 40 : 0,
- gaugeWidthScale: 0.5,
- gaugeColor: vm.darkTheme ? 'rgb(23, 26, 28)' : 'rgba(0,0,0,0)',
+ neonGlowBrightness: 40,//40,//vm.darkTheme ? 40 : 0,
+ gaugeWidthScale: 0.2,
+ gaugeColor: vm.darkTheme ? 'rgb(23, 26, 28)' : 'rgba(0, 0, 0, 0.75)',
levelColors: levelColors,
minValue: vm.minValue,
maxValue: vm.maxValue,
gaugeType: 'donut',
- dashThickness: 1.5,
+ dashThickness: 0,//1.5,
donutStartAngle: Math.PI,
animation: false,
animationDuration: 250,
@@ -141,7 +144,7 @@ function ShinyKnobController($element, $scope, $document) {
currentDeg = tmp;
lastDeg = tmp;
- knobTop.css('transform','rotate('+(currentDeg)+'deg)');
+ knobTopPointerContainer.css('transform','rotate('+(currentDeg)+'deg)');
turn(currentDeg/359);
});
@@ -168,6 +171,8 @@ function ShinyKnobController($element, $scope, $document) {
var size = Math.min(width, height);
knob.css({width: size, height: size});
canvasBar.update({width: size, height: size});
+ var valHeight = knobValueBackground.height()/3.3;
+ knobValue.css({'fontSize': valHeight+'px', 'lineHeight': valHeight+'px'});
}
function turn(ratio) {
@@ -175,16 +180,20 @@ function ShinyKnobController($element, $scope, $document) {
if (canvasBar.value != value) {
canvasBar.value = value;
}
+ knobTopPointer.css({'backgroundColor': canvasBar.getValueColor()});
+ knobValue.css({'color': 'cyan'});//canvasBar.getValueColor()});
onValue(value);
}
function setValue(value) {
var ratio = (value-vm.minValue) / (vm.maxValue - vm.minValue);
rotation = lastDeg = currentDeg = ratio*360;
- knobTop.css('transform','rotate('+(currentDeg)+'deg)');
+ knobTopPointerContainer.css('transform','rotate('+(currentDeg)+'deg)');
if (canvasBar.value != value) {
canvasBar.value = value;
}
+ knobTopPointer.css({'backgroundColor': canvasBar.getValueColor()});
+ knobValue.css({'color': 'cyan'});//canvasBar.getValueColor()});
vm.value = value;
}
ui/src/app/widget/lib/rpc/shiny-knob.scss 52(+37 -15)
diff --git a/ui/src/app/widget/lib/rpc/shiny-knob.scss b/ui/src/app/widget/lib/rpc/shiny-knob.scss
index 7ff204c..a636ec5 100644
--- a/ui/src/app/widget/lib/rpc/shiny-knob.scss
+++ b/ui/src/app/widget/lib/rpc/shiny-knob.scss
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-$knob-img: url('./knob.png');
+$knob-img: url('./knob.svg');
-$bars-margin-pct: percentage(0.2);
-$shadow-size: 5;
+$bars-margin-pct: percentage(0.08);
+$value-background-margin-pct: percentage(0.30);
+$shadow-size: 0;
$shadow-size-px: $shadow-size+px;
$shadow-offset-px: $shadow-size/2+px;
@@ -25,7 +26,7 @@ $shadow-offset-px: $shadow-size/2+px;
width:100%;
height:100%;
&.dark {
- background: #000;//$dark-bg-img #1f2129;
+ background: #000;
}
.knob {
@@ -42,30 +43,51 @@ $shadow-offset-px: $shadow-size/2+px;
bottom: 0;
right: 0;
}
- .top{
+ .value-background {
+ position:absolute;
+ top: $value-background-margin-pct;
+ left: $value-background-margin-pct;
+ bottom: $value-background-margin-pct;
+ right: $value-background-margin-pct;
+ border-radius: 50%;
+ background: #000;
+ color: #fff;
+ font-weight: 500;
+ z-index:4;
+ }
+ .top-pointer-container {
position:absolute;
top: calc(#{$bars-margin-pct} - #{$shadow-offset-px});
left: $bars-margin-pct;
bottom: calc(#{$bars-margin-pct} + #{$shadow-offset-px});
right: $bars-margin-pct;
- background:$knob-img no-repeat;
- background-size: contain;
- z-index:10;
+ z-index:3;
cursor:default !important;
- &:after {
+ .top-pointer {
content:'';
- width:10px;
- height:10px;
- background-color:#666;
+ width:5%;
+ height:5%;
+ background-color:#b5b5b5;
position:absolute;
top:50%;
- left:10px;
- margin-top:-5px;
+ left:5%;
+ margin-top:-2.5%;
border-radius: 50%;
cursor:default !important;
- box-shadow: 0 0 1px #5a5a5a inset;
+ box-shadow: 1px 0 2px #040404;
}
}
+ .top{
+ position:absolute;
+ top: calc(#{$bars-margin-pct} - #{$shadow-offset-px});
+ left: $bars-margin-pct;
+ bottom: calc(#{$bars-margin-pct} + #{$shadow-offset-px});
+ right: $bars-margin-pct;
+ background:$knob-img no-repeat;
+ background-size: contain;
+ z-index:2;
+ cursor:default !important;
+ }
.base{
top: calc(#{$bars-margin-pct} - #{$shadow-offset-px});
left: $bars-margin-pct;
diff --git a/ui/src/app/widget/lib/rpc/shiny-knob.tpl.html b/ui/src/app/widget/lib/rpc/shiny-knob.tpl.html
index 18094b3..be48067 100644
--- a/ui/src/app/widget/lib/rpc/shiny-knob.tpl.html
+++ b/ui/src/app/widget/lib/rpc/shiny-knob.tpl.html
@@ -17,12 +17,15 @@
-->
<div class="tb-shiny-knob" layout="column" ng-class="{'dark': vm.darkTheme}">
- <div layout="row" layout-align="center start" class="md-padding">
- <span>{{ vm.value }}</span>
- </div>
<div id="knob-container" flex layout="column" layout-align="center center">
<div class="knob">
+ <div class="value-background" layout="row" layout-align="center center">
+ <span class="knob-value">{{ vm.value }}</span>
+ </div>
<canvas id="canvasBar"></canvas>
+ <div class="top-pointer-container">
+ <div class="top-pointer"></div>
+ </div>
<div class="top"></div>
<div class="base"></div>
</div>