Voici 2 widgets développés ce week-end en s’inspirant de @sartog et d’autres. Tout d’abord, voici une jauge circulaire dont les couleurs varient en fonction de la valeur. Il n’y a pas de fond, le widget est transparent:
Les valeurs min, max et unités sont celles indiquées dans la commande info/numeric.
Voici le code, fichier du type cmd.info.numeric.TOneCircle.html (version du 09 fevrier 2022):
<div class="cmd cmd-widget" data-type="info" data-subtype="numeric" data-template="default" data-cmd_id="#id#" data-cmd_uid="#uid#" data-version="#version#" data-eqLogic_id="#eqLogic_id#">
<div class="title #hide_name#">
<span class="cmdName">#name_display#</span>
</div>
<div class="jauge#id#">
<div class="grille-valeur-unite#id#">
<span class="ligne"></span>
</div>
</div>
<template>
<div>scale : 1 facteur de dimensionnement</div>
</template>
<script>
jeedom.cmd.update['#id#'] = function(_options){
// Initialisation des variables.
//
// Pour l'utilisation des "Paramètres optionnels widget" :
// scale : taille du widget. 1 = 100%, inférieur à 1 on réduit la taille et supérieur à 1 on augmente la taille.
//
// Initialisation des constantes.
const scale = (is_numeric('#scale#')) ? parseFloat('#scale#') : 1;
// Initialisation des variables.
var valeur = _options.display_value;
var cmd = $('.cmd[data-cmd_id=#id#]');
var colorProgress;
var colorBgProgress;
var canvas;
var ratio = (valeur - #minValue#) / (#maxValue# - #minValue#);
// On ajuste les couleurs en fonction de valeur1
if (valeur < 15) {
colorProgress = "rgb(70,130,180)"; /* SteelBlue */
colorBgProgress = "rgb(175,238,238)"; /* PaleTurquoise */
} else if (valeur < 18) {
colorProgress = "rgb(64,224,208)"; /* Turquoise */
colorBgProgress = "rgb(175,238,238)"; /* PaleTurquoise */
} else if (valeur < 20) {
colorProgress = "rgb(20,205,50)"; /* LimeGreen */
colorBgProgress = "rgb(152,251,152)"; /* PaleGreen */
} else if (valeur < 23) {
colorProgress = "rgb(46,139,87)"; /* SeaGreen */
colorBgProgress = "rgb(152,251,152)"; /* PaleGreen */
} else if (valeur < 28) {
colorProgress = "rgb(255,165,0)"; /* Orange */
colorBgProgress = "rgb(255,218,185)"; /* PeachPuff */
} else if (valeur < 30) {
colorProgress = "rgb(255,99,71)"; /* Tomato */
colorBgProgress = "rgb(255,218,185)"; /* PeachPuff */
} else if (valeur < 35) {
colorProgress = "rgb(255,0,0)"; /* Red */
colorBgProgress = "rgb(255,160,122)"; /* LightSalmon */
} else {
colorProgress = "rgb(220,20,60)"; /* Crimson */
colorBgProgress = "rgb(255,160,122)"; /* LightSalmon */
}
// On crée un canvas dans la div et on récupère son contexte
cmd.find('div.jauge#id# canvas').remove();
canvas = $('<canvas width="100px" height="100px"></canvas>');
cmd.find('div.jauge#id#').append(canvas);
var ctx = canvas[0].getContext('2d');
/* On dessine le cercle en background */
ctx.beginPath();
ctx.arc(50,50,44,0,2*Math.PI);
ctx.lineWidth = 8;
ctx.strokeStyle = colorBgProgress;
ctx.stroke();
ctx.closePath();
// On dessine le cercle de la progression en fonction de valeur
ctx.beginPath();
ctx.arc(50,50,44,-1/2 * Math.PI,ratio * 2*Math.PI - 1/2 * Math.PI);
ctx.lineWidth = 8;
ctx.strokeStyle = colorProgress;
ctx.stroke();
ctx.closePath();
// On affiche la valeur avec son unité
cmd.find('.ligne').html(valeur + '<sup>' + '#unite#' + '</sup>');
// Scale.
cmd.find('div.jauge#id#').css('transform', 'scale(' + scale + ')');
}
jeedom.cmd.update['#id#']({display_value:'#state#'});
</script>
<style>
div.jauge#id# {
margin: 0;
padding: 0;
width: 100px;
height: 100px;
position: relative;
}
div.jauge#id# canvas {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
}
div.grille-valeur-unite#id# {
display: grid;
position : absolute;
top : 40px;
left: 10px;
height : 20px;
width : 80px;;
font-size: 18px;
font-weight: bold;
grid-template-columns : 100%;
grid-template-rows : auto;
}
span.ligne {
grid-column: 1;
grid-row: 1;
align-self: center;
color: rgb(105,105,105);
}
</style>
</div>
Pour paramétrer les ranges de valeurs et les couleurs, il suffit de personnaliser la série de 'if else if '.
Le seul paramètre optionnel est ‹ scale › qui détermine la taille du widget (par défaut 100x100px).
Deuxième widget, une double jauge qui fonctionne sur le même principe avec les couleurs qui changent en fonction de 2 valeurs. Exemple avec température et humidité :
Ce widget virtuel de type info/autre contient les 2 commandes à utiliser, séparées par une virgule, exemple :
Les paramètres optionnels sont nombreux car il faut indiquer: min, max et unité pour les 2 valeurs:
minValeur1, maxValeur1 et uniteValeur1 puis minValeur2, maxValeur2 et uniteValeur2:
Le paramètre scale donne un ratio de dimension, par défaut 1=100x100px.
Voici le code, à placer dans un fichier du type cmd.info.string.THTwoCircles.html (version du 09 février 2022):
<div class="cmd cmd-widget" data-type="info" data-subtype="string" data-template="default" data-cmd_id="#id#" data-cmd_uid="#uid#" data-version="#version#" data-eqLogic_id="#eqLogic_id#">
<div class="title #hide_name#">
<span class="cmdName">#name_display#</span>
</div>
<div class="jauge#id#">
<div class="grille-valeur-unite#id#">
<span class="ligne1"></span>
<span class="ligne2"></span>
</div>
</div>
<template>
<div>minValeur1 : 10 valeur minimum pour la jauge externe</div>
<div>maxValeur1 : 40 valeur maximum pour la jauge externe</div>
<div>uniteValeur1 : °C unité pour la première valeur</div>
<div>minValeur2 : 0 valeur minimum pour la jauge interne</div>
<div>maxValeur2 : 100 valeur maximum pour la jauge interne</div>
<div>uniteValeur2 : % unité pour la deuxième valeur</div>
<div>scale : 1 facteur de dimensionnement</div>
</template>
<script>
jeedom.cmd.update['#id#'] = function(_options){
// Initialisation des variables.
//
// Pour l'utilisation des "Paramètres optionnels widget" (conseillé), il faut impérativement utiliser ces libélés :
// minValeur1 : la valeur minimal sur laquelle sera basée le calcul de pourcentage.
// maxValeur1 : la valeur maximal sur laquelle sera basée le calcul de pourcentage.
// minValeur2 : idem que #minValeur1
// maxValeur2 : idem que #maxValeur1
// uniteValeur1 : L'unité qui sera affichée à côté de la 1ère valeur.
// uniteValeur2 : L'unité qui sera affichée à côté de la 2nde valeur.
// scale : taille du widget. 1 = 100%, inférieur à 1 on réduit la taille et supérieur à 1 on augmente la taille.
//
// Initialisation des constantes.
const minValeur1 = (is_numeric('#minValeur1#')) ? parseFloat('#minValeur1#') : 10;
const maxValeur1 = (is_numeric('#maxValeur1#')) ? parseFloat('#maxValeur1#') : 40;
const minValeur2 = (is_numeric('#minValeur2#')) ? parseFloat('#minValeur2#') : 0;
const maxValeur2 = (is_numeric('#maxValeur2#')) ? parseFloat('#maxValeur2#') : 100;
const uniteValeur1 = ('#uniteValeur1#' != '#' + 'uniteValeur1' + '#') ? '#uniteValeur1#' : '°C';
const uniteValeur2 = ('#uniteValeur2#' != '#' + 'uniteValeur2' + '#') ? '#uniteValeur2#' : '%';
const scale = (is_numeric('#scale#')) ? parseFloat('#scale#') : 1;
// Initialisation des variables.
var valeur = _options.display_value.split(',');
var cmd = $('.cmd[data-cmd_id=#id#]');
var valeur1 = valeur[0];
var valeur2 = valeur[1];
var colorProgress1;
var colorBgProgress1;
var colorProgress2;
var colorBgProgress2;
var canvas;
var ratio1 = (valeur1 - minValeur1) / (maxValeur1 - minValeur1);
var ratio2 = (valeur2 - minValeur2) / (maxValeur2 - minValeur2);
// On ajuste les couleurs en fonction de valeur1
if (valeur1 < 15) {
colorProgress1 = "rgb(70,130,180)"; /* SteelBlue */
colorBgProgress1 = "rgb(175,238,238)"; /* PaleTurquoise */
} else if (valeur1 < 18) {
colorProgress1 = "rgb(64,224,208)"; /* Turquoise */
colorBgProgress1 = "rgb(175,238,238)"; /* PaleTurquoise */
} else if (valeur1 < 20) {
colorProgress1 = "rgb(20,205,50)"; /* LimeGreen */
colorBgProgress1 = "rgb(152,251,152)"; /* PaleGreen */
} else if (valeur1 < 23) {
colorProgress1 = "rgb(46,139,87)"; /* SeaGreen */
colorBgProgress1 = "rgb(152,251,152)"; /* PaleGreen */
} else if (valeur1 < 28) {
colorProgress1 = "rgb(255,165,0)"; /* Orange */
colorBgProgress1 = "rgb(255,218,185)"; /* PeachPuff */
} else if (valeur1 < 30) {
colorProgress1 = "rgb(255,99,71)"; /* Tomato */
colorBgProgress1 = "rgb(255,218,185)"; /* PeachPuff */
} else if (valeur1 < 35) {
colorProgress1 = "rgb(255,0,0)"; /* Red */
colorBgProgress1 = "rgb(255,160,122)"; /* LightSalmon */
} else {
colorProgress1 = "rgb(220,20,60)"; /* Crimson */
colorBgProgress1 = "rgb(255,160,122)"; /* LightSalmon */
}
// On ajuste les couleurs en fonction de valeur2
if (valeur2 < 40) {
colorProgress2 = "rgb(255,215,0)"; /* Gold */
colorBgProgress2 = "rgb(255,250,205)"; /* LemonChiffon */
} else if (valeur2 < 60) {
colorProgress2 = "rgb(46,139,87)"; /* SeaGreen */
colorBgProgress2 = "rgb(152,251,152)"; /* PaleGreen */
} else if (valeur2 < 75) {
colorProgress2 = "rgb(70,130,180)"; /* SteelBlue */
colorBgProgress2 = "rgb(175,238,238)"; /* PaleTurquoise */
} else if (valeur2 < 90) {
colorProgress2 = "rgb(255,99,71)"; /* Tomato */
colorBgProgress2 = "rgb(255,218,185)"; /* PeachPuff */
} else {
colorProgress2 = "rgb(255,0,0)"; /* Red */
colorBgProgress2 = "rgb(255,160,122)"; /* LightSalmon */
}
// On crée un canvas dans la div et on récupère son contexte
cmd.find('div.jauge#id# canvas').remove();
canvas = $('<canvas width="100px" height="100px"></canvas>');
cmd.find('div.jauge#id#').append(canvas);
var ctx = canvas[0].getContext('2d');
/* On dessine le cercle extérieur en background */
ctx.beginPath();
ctx.arc(50,50,44,0,2*Math.PI);
ctx.lineWidth = 8;
ctx.strokeStyle = colorBgProgress1;
ctx.stroke();
ctx.closePath();
// On dessine le cercle extérieur de la progression en fonction de valeur1
ctx.beginPath();
ctx.arc(50,50,44,-1/2 * Math.PI,ratio1 * 2*Math.PI - 1/2 * Math.PI);
ctx.lineWidth = 8;
ctx.strokeStyle = colorProgress1;
ctx.stroke();
ctx.closePath();
// On dessine le cercle en background
ctx.beginPath();
ctx.arc(50,50,34,0,2*Math.PI);
ctx.lineWidth = 8;
ctx.strokeStyle = colorBgProgress2;
ctx.stroke();
ctx.closePath();
// On dessine le cercle de la progression en fonction de valeur2
ctx.beginPath();
ctx.arc(50,50,34,-1/2 * Math.PI,ratio2 * 2*Math.PI - 1/2 * Math.PI);
ctx.lineWidth = 8;
ctx.strokeStyle = colorProgress2;
ctx.stroke();
ctx.closePath();
// On ajoute un trait horizontal de séparation des valeurs
ctx.beginPath();
ctx.lineWidth = 1;
ctx.setLineDash([4,2]);
ctx.strokeStyle = "rgb(112,128,144)";
ctx.moveTo(22,50);
ctx.lineTo(80,50);
ctx.stroke();
ctx.closePath();
// On affiche les 2 valeurs avec leurs unités
cmd.find('.ligne1').html(valeur1 + '<sup>' + uniteValeur1 + '</sup>');
cmd.find('.ligne2').html(valeur2 + '<sup>' + uniteValeur2 + '</sup>');
// Scale.
cmd.find('div.jauge#id#').css('transform', 'scale(' + scale + ')');
}
jeedom.cmd.update['#id#']({display_value:'#state#'});
</script>
<style>
div.jauge#id# {
margin: 0;
padding: 0;
width: 100px;
height: 100px;
position: relative;
}
div.jauge#id# canvas {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
}
div.grille-valeur-unite#id# {
display: grid;
position : absolute;
top : 25px;
left: 25px;
height : 50px;
width : 50px;;
font-size: 14px;
font-weight: bold;
grid-template-columns : 100%;
grid-template-rows : auto;
}
span.ligne1 {
grid-column: 1;
grid-row: 1;
align-self: center;
color: rgb(105,105,105);
}
span.ligne2 {
grid-column: 1;
grid-row: 2;
align-self: center;
color: rgb(105,105,105);
}
</style>
</div>
cdt