-
Notifications
You must be signed in to change notification settings - Fork 0
/
fluid_level_1.json
18 lines (18 loc) · 17.1 KB
/
fluid_level_1.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"alias": "fluid_level_12",
"name": "fluid level 1",
"descriptor": {
"type": "latest",
"sizeX": 8,
"sizeY": 9,
"resources": [],
"templateHtml": "<div id=\"fluid-meter-3\"></div>\n\n",
"templateCss": "#container {\n overflow: auto;\n \n}\n",
"controllerScript": "function FluidMeter() {\n \n var context;\n var targetContainer;\n\n var time = null;\n var dt = null;\n\n var options = {\n drawShadow: true,\n drawText: true,\n drawPercentageSign: true,\n drawBubbles: true,\n fontSize: \"70px\",\n fontFamily: \"Arial\",\n fontFillStyle: \"white\",\n size: 300,\n borderWidth: 25,\n backgroundColor: \"#e2e2e2\",\n foregroundColor: \"#fafafa\"\n };\n\n var currentFillPercentage = 0;\n var fillPercentage = 0;\n var valueText = 0;\n\n //#region fluid context values\n var foregroundFluidLayer = {\n fillStyle: \"purple\",\n angle: 0,\n horizontalPosition: 0,\n angularSpeed: 0,\n maxAmplitude: 9,\n frequency: 30,\n horizontalSpeed: -150,\n initialHeight: 0\n };\n\n var backgroundFluidLayer = {\n fillStyle: \"pink\",\n angle: 0,\n horizontalPosition: 0,\n angularSpeed: 140,\n maxAmplitude: 12,\n frequency: 40,\n horizontalSpeed: 150,\n initialHeight: 0\n };\n\n var bubblesLayer = {\n bubbles: [],\n amount: 12,\n speed: 20,\n current: 0,\n swing: 0,\n size: 2,\n reset: function (bubble) {\n // calculate the area where to spawn the bubble based on the fluid area\n var meterBottom = (options.size - (options.size - getMeterRadius()) / 2) - options.borderWidth;\n var fluidAmount = currentFillPercentage * (getMeterRadius() - options.borderWidth * 2) / 100;\n\n bubble.r = random(this.size, this.size * 2) / 2;\n bubble.x = random(0, options.size);\n bubble.y = random(meterBottom, meterBottom - fluidAmount);\n bubble.velX = 0;\n bubble.velY = random(this.speed, this.speed * 2);\n bubble.swing = random(0, 2 * Math.PI);\n },\n init() {\n for (var i = 0; i < this.amount; i++) {\n\n var meterBottom = (options.size - (options.size - getMeterRadius()) / 2) - options.borderWidth;\n var fluidAmount = currentFillPercentage * (getMeterRadius() - options.borderWidth * 2) / 100;\n this.bubbles.push({\n x: random(0, options.size),\n y: random(meterBottom, meterBottom - fluidAmount),\n r: random(this.size, this.size * 2) / 2,\n velX: 0,\n velY: random(this.speed, this.speed * 2)\n });\n }\n }\n }\n //#endregion\n\n /**\n * initializes and mount the canvas element on the document\n */\n function setupCanvas() {\n var canvas = document.createElement('canvas');\n canvas.width = options.size;\n canvas.height = options.size;\n \n canvas.imageSmoothingEnabled = true;\n context = canvas.getContext(\"2d\");\n targetContainer.appendChild(canvas);\n\n // shadow is not required to be on the draw loop\n //#region shadow\n if (options.drawShadow) {\n context.save();\n context.beginPath();\n context.filter = \"drop-shadow(0px 4px 6px rgba(0,0,0,0.1))\";\n context.arc(options.size / 2, options.size / 2, getMeterRadius() / 2, 0, 2 * Math.PI);\n context.closePath();\n context.fill();\n context.restore();\n }\n //#endregion\n }\n\n /**\n * draw cycle\n */\n function draw() {\n var now = new Date().getTime();\n dt = (now - (time || now)) / 1000;\n time = now;\n\n requestAnimationFrame(draw);\n context.clearRect(0, 0, options.width, options.height);\n drawMeterBackground();\n drawFluid(dt);\n if (options.drawText) {\n drawText();\n }\n drawMeterForeground();\n }\n\n function drawMeterBackground() {\n context.save();\n context.fillStyle = options.backgroundColor;\n context.beginPath();\n context.arc(options.size / 2, options.size / 2, getMeterRadius() / 2 - options.borderWidth, 0, 2 * Math.PI);\n context.closePath();\n context.fill();\n context.restore();\n }\n\n function drawMeterForeground() {\n context.save();\n context.lineWidth = options.borderWidth;\n context.strokeStyle = options.foregroundColor;\n context.beginPath();\n context.arc(options.size / 2, options.size / 2, getMeterRadius() / 2 - options.borderWidth / 2, 0, 2 * Math.PI);\n context.closePath();\n context.stroke();\n context.restore();\n }\n /**\n * draws the fluid contents of the meter\n * @param {} dt elapsed time since last frame\n */\n function drawFluid(dt) {\n context.save();\n context.arc(options.size / 2, options.size / 2, getMeterRadius() / 2 - options.borderWidth, 0, Math.PI * 2);\n context.clip();\n drawFluidLayer(backgroundFluidLayer, dt);\n drawFluidLayer(foregroundFluidLayer, dt);\n if (options.drawBubbles) {\n drawFluidMask(foregroundFluidLayer, dt);\n drawBubblesLayer(dt);\n }\n context.restore();\n }\n\n\n /**\n * draws the foreground fluid layer\n * @param {} dt elapsed time since last frame\n */\n function drawFluidLayer(layer, dt) {\n // calculate wave angle\n if (layer.angularSpeed > 0) {\n layer.angle += layer.angularSpeed * dt;\n layer.angle = layer.angle < 0 ? layer.angle + 360 : layer.angle;\n }\n\n // calculate horizontal position\n layer.horizontalPosition += layer.horizontalSpeed * dt;\n if (layer.horizontalSpeed > 0) {\n layer.horizontalPosition > Math.pow(2, 53) ? 0 : layer.horizontalPosition;\n }\n else if (layer.horizontalPosition < 0) {\n layer.horizontalPosition < -1 * Math.pow(2, 53) ? 0 : layer.horizontalPosition;\n }\n\n var x = 0;\n var y = 0;\n var amplitude = layer.maxAmplitude * Math.sin(layer.angle * Math.PI / 180);\n\n var meterBottom = (options.size - (options.size - getMeterRadius()) / 2) - options.borderWidth;\n var fluidAmount = currentFillPercentage * (getMeterRadius() - options.borderWidth * 2) / 100;\n\n if (currentFillPercentage < fillPercentage) {\n currentFillPercentage += 15 * dt;\n } else if (currentFillPercentage > fillPercentage) {\n currentFillPercentage -= 15 * dt;\n }\n\n layer.initialHeight = meterBottom - fluidAmount;\n\n context.save();\n context.beginPath();\n\n context.lineTo(0, layer.initialHeight);\n\n while (x < options.size) {\n y = layer.initialHeight + amplitude * Math.sin((x + layer.horizontalPosition) / layer.frequency);\n context.lineTo(x, y);\n x++;\n }\n\n context.lineTo(x, options.size);\n context.lineTo(0, options.size);\n context.closePath();\n\n context.fillStyle = layer.fillStyle;\n context.fill();\n context.restore();\n }\n\n /**\n * clipping mask for objects within the fluid constrains\n * @param {Object} layer layer to be used as a mask\n */\n function drawFluidMask(layer) {\n var x = 0;\n var y = 0;\n var amplitude = layer.maxAmplitude * Math.sin(layer.angle * Math.PI / 180);\n\n context.beginPath();\n\n context.lineTo(0, layer.initialHeight);\n\n while (x < options.size) {\n y = layer.initialHeight + amplitude * Math.sin((x + layer.horizontalPosition) / layer.frequency);\n context.lineTo(x, y);\n x++;\n }\n context.lineTo(x, options.size);\n context.lineTo(0, options.size);\n context.closePath();\n context.clip();\n }\n\n function drawBubblesLayer(dt) {\n context.save();\n for (var i = 0; i < bubblesLayer.bubbles.length; i++) {\n var bubble = bubblesLayer.bubbles[i];\n\n context.beginPath();\n context.strokeStyle = 'white';\n context.arc(bubble.x, bubble.y, bubble.r, 2 * Math.PI, false);\n context.stroke();\n context.closePath();\n\n var currentSpeed = bubblesLayer.current * dt;\n\n bubble.velX = Math.abs(bubble.velX) < Math.abs(bubblesLayer.current) ? bubble.velX + currentSpeed : bubblesLayer.current;\n bubble.y = bubble.y - bubble.velY * dt;\n bubble.x = bubble.x + (bubblesLayer.swing ? 0.4 * Math.cos(bubblesLayer.swing += 0.03) * bubblesLayer.swing : 0) + bubble.velX * 0.5;\n\n // determine if current bubble is outside the safe area\n var meterBottom = (options.size - (options.size - getMeterRadius()) / 2) - options.borderWidth;\n var fluidAmount = currentFillPercentage * (getMeterRadius() - options.borderWidth * 2) / 100;\n\n if (bubble.y <= meterBottom - fluidAmount) {\n bubblesLayer.reset(bubble);\n }\n\n }\n context.restore();\n }\n\n function drawText() {\n var settings = self.ctx.settings;\n text = valueText.toFixed(0);\n if (settings.unit != undefined)\n text = valueText.toFixed(0) + \" \"+ settings.unit;\n\n context.save();\n context.font = getFontSize();\n context.fillStyle = options.fontFillStyle;\n context.textAlign = \"center\";\n context.textBaseline = 'middle';\n context.filter = \"drop-shadow(0px 0px 5px rgba(0,0,0,0.4))\"\n context.fillText(text, options.size / 2, options.size / 2);\n context.restore();\n }\n\n //#region helper methods\n function clamp(number, min, max) {\n return Math.min(Math.max(number, min), max);\n };\n function getMeterRadius() {\n return options.size * 0.9;\n }\n\n function random(min, max) {\n var delta = max - min;\n return max === min ? min : Math.random() * delta + min;\n }\n\n function getFontSize() {\n return options.fontSize + \" \" + options.fontFamily;\n }\n //#endregion\n\n return {\n init: function (env) {\n if (!env.targetContainer)\n throw \"empty or invalid container\";\n\n targetContainer = env.targetContainer;\n fillPercentage = clamp(env.fillPercentage, 0, 100);\n\n if (env.options) {\n options.drawShadow = env.options.drawShadow === false ? false : true;\n options.size = env.options.size;\n options.drawBubbles = env.options.drawBubbles === false ? false : true;\n options.borderWidth = env.options.borderWidth || options.borderWidth;\n options.foregroundFluidColor = env.options.foregroundFluidColor || options.foregroundFluidColor;\n options.backgroundFluidColor = env.options.backgroundFluidColor || options.backgroundFluidColor;\n options.backgroundColor = env.options.backgroundColor || options.backgroundColor;\n options.foregroundColor = env.options.foregroundColor || options.foregroundColor;\n\n options.drawText = env.options.drawText === false ? false : true;\n options.drawPercentageSign = env.options.drawPercentageSign === false ? false : true;\n options.fontSize = env.options.fontSize || options.fontSize;\n options.fontFamily = env.options.fontFamily || options.fontFamily;\n options.fontFillStyle = env.options.fontFillStyle || options.fontFillStyle;\n // fluid settings\n\n if (env.options.foregroundFluidLayer) {\n foregroundFluidLayer.fillStyle = env.options.foregroundFluidLayer.fillStyle || foregroundFluidLayer.fillStyle;\n foregroundFluidLayer.angularSpeed = env.options.foregroundFluidLayer.angularSpeed || foregroundFluidLayer.angularSpeed;\n foregroundFluidLayer.maxAmplitude = env.options.foregroundFluidLayer.maxAmplitude || foregroundFluidLayer.maxAmplitude;\n foregroundFluidLayer.frequency = env.options.foregroundFluidLayer.frequency || foregroundFluidLayer.frequency;\n foregroundFluidLayer.horizontalSpeed = env.options.foregroundFluidLayer.horizontalSpeed || foregroundFluidLayer.horizontalSpeed;\n }\n\n if (env.options.backgroundFluidLayer) {\n backgroundFluidLayer.fillStyle = env.options.backgroundFluidLayer.fillStyle || backgroundFluidLayer.fillStyle;\n backgroundFluidLayer.angularSpeed = env.options.backgroundFluidLayer.angularSpeed || backgroundFluidLayer.angularSpeed;\n backgroundFluidLayer.maxAmplitude = env.options.backgroundFluidLayer.maxAmplitude || backgroundFluidLayer.maxAmplitude;\n backgroundFluidLayer.frequency = env.options.backgroundFluidLayer.frequency || backgroundFluidLayer.frequency;\n backgroundFluidLayer.horizontalSpeed = env.options.backgroundFluidLayer.horizontalSpeed || backgroundFluidLayer.horizontalSpeed;\n }\n }\n\n\n\n bubblesLayer.init();\n setupCanvas();\n draw();\n },\n setPercentage(percentage, value) {\n\n fillPercentage = clamp(percentage, 0, 100);\n valueText = value;\n }\n }\n};\n\n\n\n\n\n\n\nself.onInit = function() {\n var settings = self.ctx.settings;\n\n\n\n\n \n self.onResize();\n\n}\n\nself.onDataUpdated = function() {\n var settings = self.ctx.settings;\n var value = 0;\n \n if (self.ctx.defaultSubscription.data.length > 0)\n {\n \n if (self.ctx.defaultSubscription.data[0].data.length > 0)\n value = self.ctx.defaultSubscription.data[0].data[0][1];\n if (settings.maxValue > 0)\n fm3.setPercentage((value / settings.maxValue) * 100, parseFloat(value));\n else\n fm3.setPercentage(value, parseFloat(value));\n \n }\n \n function isNumber(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n}\n var fm3 = new FluidMeter();\nself.onResize = function() {\n var settings = self.ctx.settings;\n let fillColorForeground = \"#16E1FF\"\n let fillColorBackground = \"#4F8FC6\"\n if (settings.colorScheme == 'green')\n {\n fillColorForeground = \"#55DD10\";\n fillColorBackground = \"#CDDD10\"\n }\n if (settings.colorScheme == 'purple')\n {\n fillColorForeground = \"purple\";\n fillColorBackground = \"pink\"\n }\n \n let size = self.ctx.width;\n if (self.ctx.height < self.ctx.width)\n size = self.ctx.height;\n \n console.log($(\"#fluid-meter-3\", self.ctx.$container))\n \n $(\"#fluid-meter-3\", self.ctx.$container)[0].innerHTML = \"\";\n fm3 = new FluidMeter();\n fm3.init({\n targetContainer: document.getElementById(\"fluid-meter-3\"),\n fillPercentage: 0,\n options: {\n fontSize: \"30px\",\n drawPercentageSign: false,\n drawBubbles: true,\n size: size,\n borderWidth: 19,\n backgroundColor: settings.backgroundColor,\n foregroundColor: \"#fafafa\",\n foregroundFluidLayer: {\n fillStyle: fillColorForeground,\n angularSpeed: 30,\n maxAmplitude: 10,\n frequency: 30,\n horizontalSpeed: -20\n },\n backgroundFluidLayer: {\n fillStyle: fillColorBackground,\n angularSpeed: 100,\n maxAmplitude: 3,\n frequency: 22,\n horizontalSpeed: 20\n }\n }\n});\n let value = 0;\n console.log (self.ctx);\nif (self.ctx.defaultSubscription.data.length > 0)\n {\n \n if (self.ctx.defaultSubscription.data[0].data.length > 0)\n value = self.ctx.defaultSubscription.data[0].data[0][1];\n if (settings.maxValue > 0)\n fm3.setPercentage((value / settings.maxValue) * 100, parseFloat(value));\n else\n fm3.setPercentage(value, parseFloat(value));\n \n }\n\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"maxValue\": {\n \"title\": \"Maximum Value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"unit\": {\n \"title\": \"Unit\",\n \"type\": \"string\",\n \"default\": \"%\"\n },\n \"colorScheme\": {\n \"title\": \"Color Scheme\",\n \"type\": \"string\",\n \"enum\": [\n \"blue\",\n \"green\",\n \"purple\"],\n \"default\": \"blue\"\n },\n \"backgroundColor\": {\n \"title\": \"Background Color\",\n \"type\": \"string\",\n \"default\": \"#008a00\"\n }\n },\n \"required\": [\"maxValue\", \"colorScheme\"]\n },\n \"form\": [\n \"maxValue\",\n \"unit\",\n \"colorScheme\",\n {\n \"key\": \"backgroundColor\",\n \"type\": \"color\",\n \"default\":\"#e2e2e2\"\n }\n \n ]\n \n \n}",
"dataKeySettingsSchema": "{}\n",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = Math.random() * 200;\\n\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"colorScheme\":\"blue\",\"maxValue\":200,\"unit\":\"l\",\"backgroundColor\":\"#eaeaea\"},\"title\":\"fluid level 1\"}"
},
"image": null,
"description": null
}