Dashticz - V3.8.9 beta - linear-gradient in custom.js

Dashticz, alternative dashboard based on HTML, CSS, jQuery

Moderators: leecollings, htilburgs, robgeerts

Post Reply
Maikel76
Posts: 71
Joined: Friday 14 August 2020 6:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Bangkok
Contact:

Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Maikel76 »

Hi,
I would like to change the background with linear-gradient of one block according to the value of another block;
block 76 holds a number between 56 and 150 and is a custom sensor. Value 56 means slightly unhealthy, 150 means unhealthy. These are pm values. I would like to make block 79 that holds the value Unhealthy (it's a text device) have a background: linear-gradient. If i put this straight in custom.css it will show the gradient, but I cannot seem to find the exact code to add the css value in custom.js. I tried this with mountPoint and also with $('.block_79') but I'm clearly missing something.
Could you please sent me in the right direction?

This is my custom.js

Code: Select all

function getStatus_76(block) {                                      //airqualitypm25us
  var device = block.device;
  if (Domoticz.getAllDevices()[79].Data == 'Unhealthy') {
    var ug = parseFloat(device['Data']);                        //pm value in ug
    var bereik = 150 - 56; //max - min                          //precentage unhealthy
    var perc = ( bereik / ug ) * 100;
    var percstr = perc.toFixed(0).toString();
    var slightlyunhealthy = 'rgba(255,140,0,0.8)';              //oranje
    var unhealthy = 'rgba(220,20,60,0.9)';                      //rood
  // example  background: linear-gradient(to right, rgba(255,140,0,0.8), rgba(220,20,60,0.9) 70%) !important;
    //var grad = `background: linear-gradient(to right, ${slightlyunhealthy}, ${unhealthy} ${percstr}) !important;`;
    //$('.block_79').css(`background: linear-gradient(to right, ${slightlyunhealthy}, ${unhealthy} ${percstr}) !important`);
    $(block.mountPoint).css(`background: linear-gradient(to right, ${slightlyunhealthy}, ${unhealthy} ${percstr}) !important`);
  //$('.block_79').css(`background: linear-gradient(to right, rgba(255,140,0,0.8), rgba(220,20,60,0.9) 70%) !important`);
  //example  $(block.mountPoint + ' .ui-slider-horizontal').css('background-color', colorStr);
  } //end if
}
this is my CONFIG.js

Code: Select all

blocks[76] = {title: 'Pm2.5', width: 4, icon: 'fas fa-smog', last_update: false}
blocks[79] = {title: 'Level Pm', width: 4, hide_data: true, last_update: false, protected: true}
I'm running Domoticz 2022.1
If you need any more info please let me know
Thanks a lot in advance
Scripting is my passion, dzVents, LUA, Bash
Dashticz v3.10.7 Beta --Raspbian Buster
Lokonli
Posts: 2290
Joined: Monday 29 August 2016 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Lokonli »

Maikel76 wrote: Wednesday 02 March 2022 12:54 Hi,
I would like to change the background with linear-gradient of one block according to the value of another block;
block 76 holds a number between 56 and 150 and is a custom sensor. Value 56 means slightly unhealthy, 150 means unhealthy. These are pm values. I would like to make block 79 that holds the value Unhealthy (it's a text device) have a background: linear-gradient. If i put this straight in custom.css it will show the gradient, but I cannot seem to find the exact code to add the css value in custom.js. I tried this with mountPoint and also with $('.block_79') but I'm clearly missing something.
Could you please sent me in the right direction?

This is my custom.js

Code: Select all

function getStatus_76(block) {                                      //airqualitypm25us
  var device = block.device;
  if (Domoticz.getAllDevices()[79].Data == 'Unhealthy') {
    var ug = parseFloat(device['Data']);                        //pm value in ug
    var bereik = 150 - 56; //max - min                          //precentage unhealthy
    var perc = ( bereik / ug ) * 100;
    var percstr = perc.toFixed(0).toString();
    var slightlyunhealthy = 'rgba(255,140,0,0.8)';              //oranje
    var unhealthy = 'rgba(220,20,60,0.9)';                      //rood
  // example  background: linear-gradient(to right, rgba(255,140,0,0.8), rgba(220,20,60,0.9) 70%) !important;
    //var grad = `background: linear-gradient(to right, ${slightlyunhealthy}, ${unhealthy} ${percstr}) !important;`;
    //$('.block_79').css(`background: linear-gradient(to right, ${slightlyunhealthy}, ${unhealthy} ${percstr}) !important`);
    $(block.mountPoint).css(`background: linear-gradient(to right, ${slightlyunhealthy}, ${unhealthy} ${percstr}) !important`);
  //$('.block_79').css(`background: linear-gradient(to right, rgba(255,140,0,0.8), rgba(220,20,60,0.9) 70%) !important`);
  //example  $(block.mountPoint + ' .ui-slider-horizontal').css('background-color', colorStr);
  } //end if
}
this is my CONFIG.js

Code: Select all

blocks[76] = {title: 'Pm2.5', width: 4, icon: 'fas fa-smog', last_update: false}
blocks[79] = {title: 'Level Pm', width: 4, hide_data: true, last_update: false, protected: true}
I'm running Domoticz 2022.1
If you need any more info please let me know
Thanks a lot in advance
Nice challenge :)

Two issues:
* With jquery css unfortunately you cannot add !important
* mountPoint refers to the container of the block. The block itself will be recreated.

A solution: use css custom properties.

Compute the background setting and add this to the container as custom property:

Code: Select all

     block.$mountPoint.css('--bgcolor',  mycomputedvalue); 
Add a css class to the block in CONFIG.js:

Code: Select all

 blocks['myblock' ] = {
    ...
    addClass: 'myclass'
 }
 
And define this in custom.css, using the custom property:

Code: Select all

.myclass {
   background: var(--bgcolor)
}
The custom property --bgcolor can contain any value, text, other custom properties, etc.
Maikel76
Posts: 71
Joined: Friday 14 August 2020 6:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Bangkok
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Maikel76 »

Awesome, thanks a lot Lokonli, I think I understand. I will report back
Scripting is my passion, dzVents, LUA, Bash
Dashticz v3.10.7 Beta --Raspbian Buster
Maikel76
Posts: 71
Joined: Friday 14 August 2020 6:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Bangkok
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Maikel76 »

Challange solved;
This is the code in different places, I didn't put the addClass property in CONFIG.js because the class is also every time different, re-used the previously used code;
Ofcourse for every state (Unhealthy, very unhealthy, hazardous, etc) there is a specific block of code with its specific range-values, background values and calculated percentage values. The first 3 lines are generally used. The Data value of block 76 unfortunately includes the unit value so i needed to manupulate the string too.

Code: Select all

custom.js
////////////////////////STEP1: calculate percentage according to current value and range
function getStatus_79(block) {                                  //airqualitypm25us
  var pm = Domoticz.getAllDevices()[76];                      //get pm data from block 76 (custom sensor)
  var value = pm.Data;
  //var value = "80 µg/m³"                                    //example how data shows in pm data
  value = value.substring(0, value.length - 6);               //cut out last 6 char so youre left with the number
  if (block.device.Data == 'Good') {
    var bereik = 12; //max - min                          //calc percentage
    var perc = ( bereik / value ) * 100;
    var percstr = perc.toFixed(0).toString();
    percstr +=  '%';
    block.$mountPoint.css('--percgoo',  percstr);                       //transfer calculated percentage to custom.css
    }
.
.
.
function afterGetDevices(){
////////// STEP2: Add class according to state, next step in custom.css
    if (Domoticz.getAllDevices()[79].Data == 'Good') {
            $('.block_79').addClass('classGood');
    }
    else {
            $('.block_79').removeClass('classGood');
    }
.
.
.
custom.css
/********** STEP3: define class color and use specific percentage from custom.js   ************/
.classGood { /*darkgreen*/
   background: linear-gradient(to right, rgba(255,2550,255,0.5), rgba(0,100,0,0.6) var(--percgoo) ) !important;
}
.
.
.
CONFIG.js
blocks[79] = {title: 'Level Pm', width: 4, hide_data: true, last_update: false, protected: true}
Result is:
a background gradient that changes to more of the Very Unhealthy color the closer it gets to the start of that range and it changes more to the Unhealthy color the closer to the beginning of that range it gets

Thanks again Lokonli and if you or anyone see mistakes please let me know
Scripting is my passion, dzVents, LUA, Bash
Dashticz v3.10.7 Beta --Raspbian Buster
Lokonli
Posts: 2290
Joined: Monday 29 August 2016 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Lokonli »

Nice.

some (possible) improvements:

I think you can use 'var value=parseInt(pm.Data)' to get the integer value of the data. The value manipulation is then not needed anymore.

Instead of setting the class in the afterGetDevices function, it should work if you do that in the getStatus function itself.

Combining the two you will get this: (not tested ...)

Code: Select all

function getStatus_79(block) {                                  //airqualitypm25us
  var pm = Domoticz.getAllDevices()[76];                      //get pm data from block 76 (custom sensor)
  var value = parseInt(pm.Data);     //// parseInt
  //var value = "80 µg/m³"                                    //example how data shows in pm data
//// not needed anymore  value = value.substring(0, value.length - 6);               //cut out last 6 char so youre left with the number
  if (block.device.Data == 'Good') {
    var bereik = 12; //max - min                          //calc percentage
    var perc = ( bereik / value ) * 100;
   var percstr = ''+perc.toFixed(0) + ' %';
   block.$mountPoint.css('--percgoo',  percstr);                       //transfer calculated percentage to custom.css
  block.addClass = "classGood"
    }
   else block.addClass = ''
}

Maikel76
Posts: 71
Joined: Friday 14 August 2020 6:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Bangkok
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Maikel76 »

Lokonli wrote: Monday 07 March 2022 13:44 Nice.

some (possible) improvements:

I think you can use 'var value=parseInt(pm.Data)' to get the integer value of the data. The value manipulation is then not needed anymore.

Instead of setting the class in the afterGetDevices function, it should work if you do that in the getStatus function itself.

Combining the two you will get this: (not tested ...)

Code: Select all

function getStatus_79(block) {                                  //airqualitypm25us
  var pm = Domoticz.getAllDevices()[76];                      //get pm data from block 76 (custom sensor)
  var value = parseInt(pm.Data);     //// parseInt
  //var value = "80 µg/m³"                                    //example how data shows in pm data
//// not needed anymore  value = value.substring(0, value.length - 6);               //cut out last 6 char so youre left with the number
  if (block.device.Data == 'Good') {
    var bereik = 12; //max - min                          //calc percentage
    var perc = ( bereik / value ) * 100;
   var percstr = ''+perc.toFixed(0) + ' %';
   block.$mountPoint.css('--percgoo',  percstr);                       //transfer calculated percentage to custom.css
  block.addClass = "classGood"
    }
   else block.addClass = ''
}

Changed the code a little bit but this is definitely a lot shorter;
spaces before and after % not allowed so had to remove them from your code. Furthermore I didn't knew the = with addClass and its working like a charm. Also the parseInt is a nifty feature. Awesome and thanks.

Code: Select all

if (block.device.Data == 'Unhealthy') {
    var bereik = 150 - 56; //max - min                          //calc percentage
    var percstr = ( ( bereik / value ) * 100 ).toFixed(0) + '%';
    block.$mountPoint.css('--percunh',  percstr);                       //transfer calculated percentage to custom.css
    block.addClass = "classUnhealthy";
    }
    else block.addClass = "";
Edit: changed all code to move the block.addClass and it seemed to work at first but now it doesnt, enableing the previous addClass code makes it work again so I'm doing something wrong or it doesnt work :?
Edit2: Does the function afterGetDevices(){ does the magic trick??
Scripting is my passion, dzVents, LUA, Bash
Dashticz v3.10.7 Beta --Raspbian Buster
Lokonli
Posts: 2290
Joined: Monday 29 August 2016 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Lokonli »

getStatus_79 gets called only when device 79 changes, not when device 76 changes.
afterGetDevices gets called after every device update.

That may explain the things you see.
Maikel76
Posts: 71
Joined: Friday 14 August 2020 6:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Bangkok
Contact:

Re: Dashticz - V3.8.9 beta - linear-gradient in custom.js

Post by Maikel76 »

Lokonli wrote:getStatus_79 gets called only when device 79 changes, not when device 76 changes.
afterGetDevices gets called after every device update.

That may explain the things you see.
Aah yeah ofcourse :)
Then I would like to ask the question that I’m wondering about for some time:
Is it possible to export a set variable with function “getStatus_79” with export var className
Then how do I use/import that var inside another function “getStatus_76” ?
I experimented with it but could not get that to work


Sent from my iPhone using Tapatalk
Scripting is my passion, dzVents, LUA, Bash
Dashticz v3.10.7 Beta --Raspbian Buster
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest