Helloo,
Suite à plusieurs discussions sur le problème d’import d’un fichier javascript depuis un widget depuis la version 4.4 de Jeedom, j’ai pu tester cette solution qui évite l’utilisation du timeout (qui en général cache un problème et c’est le cas ici : estimation approximative d’une valeur de timeout pour ne plus avoir de souci)
Exemples de discussion ici :
Pour mes tests, je suis parti sur la modification d’un widget remontant le problème : Solid Gauge
L’idée est :
-
d’ajouter le code de la fonction
includeJS
visible ci-dessous soitdirectement dans le widget
ou soit enpersonnalisation avancée
pour mutualisation de plusieurs widgets. -
d’inclure un ou plusieurs fichiers JS à partir de cette fonction avec le code suivant :
<script>
// inclusion d'un fichier JS
includeJS('3rdparty/highstock/modules/solid-gauge.js', function() {
// code du widget
// ...
}
</script>
<script>
// inclusion de plusieurs fichiers JS
includeJS(['data/customTemplates/dashboard/cmd.action.color.nooPickAColor/pick-a-color.min.js', 'data/customTemplates/dashboard/cmd.action.color.nooPickAColor/tinycolor-0.9.15.min.js'], function() {
// code du widget
// ...
}
</script>
code widget modifié
<!-- https://community.jeedom.com/t/partage-solid-gauge-en-4-1/43922/22
Options : tickinterval / min / max / color1 / color2 / color3 / time
- color en rgb
- time égal à duration sinon rien
// Pour thème Jeedom non-Legacy -->
<!-- script src="core/php/getJS.php?file=3rdparty/highstock/modules/solid-gauge.js"></script -->
<div class="cmd cmd-widget #history#" data-type="info" data-subtype="numeric" data-cmd_id="#id#" data-cmd_uid="#uid#" data-version="#version#" data-eqLogic_id="#eqLogic_id#" title="Date de valeur : #valueDate#<br/>Date de collecte : #collectDate#" >
<div class="title #hide_name#">
<span class="cmdName">#name_display#</span>
</div>
<div class="content-sm">
<div class="gaugearnog23 cursor #history#" data-cmd_id="#id#"></div>
</div>
<div class="value">
<span class="timeCmd label label-default #history#" data-type="info"></span>
</div>
<div class="cmdStats #hide_history#">
<span title='{{Min}}' class='tooltips'>#minHistoryValue#</span>|<span title='{{Moyenne}}' class='tooltips'>#averageHistoryValue#</span>|<span title='{{Max}}' class='tooltips'>#maxHistoryValue#</span> <i class="#tendance#"></i>
</div>
<style>
.gaugearnog23 {
width: 105px;
height: 105px;
}
.gaugearnog23 .highcharts-pane {
fill: var(--el-defaultColor);
}
body[data-theme="core2019_Dark"] .gaugearnog23 .highcharts-tick {
stroke: rgb(38, 38, 38);
}
body[data-theme="core2019_Light"] .gaugearnog23 .highcharts-tick {
stroke: rgb(249, 249, 250);
}
.gaugearnog23 .highcharts-container .highcharts-axis-line {
stroke: transparent;
}
.gaugearnog23 .highcharts-yaxis-grid .highcharts-grid-line {
stroke: none !important;
}
</style>
<script>
/*
function includeJS(filename, callback) {
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
script.async = true; // Charger de manière asynchrone
// Gestion de l'événement de chargement du script
script.onload = script.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
callback(); // Appel de la fonction de rappel une fois que le script est chargé
// Nettoyage des événements pour éviter les fuites de mémoire
script.onload = script.onreadystatechange = null;
}
};
// Ajout du script à la fin du corps du document
document.body.appendChild(script);
}
*/
// Utilisation de la fonction pour inclure le fichier JavaScript et effectuer une action après son chargement
//includeJS('core/php/getJS.php?file=3rdparty/highstock/modules/solid-gauge.js', function() {
includeJS('3rdparty/highstock/modules/solid-gauge.js', function() {
// Code à exécuter après le chargement du fichier JavaScript
var tickInterval = is_numeric('#tickInterval#') ? parseFloat('#tickInterval#') : 25;
var min = is_numeric('#min#') ? parseFloat('#min#') : 0;
var max = is_numeric('#max#') ? parseFloat('#max#') : 100;
var color1 = ('#color1#' != '#'+'color1#') ? '#color1#' : 'rgb(0, 255, 0)';
var color2 = ('#color2#' != '#'+'color2#') ? '#color2#' : 'rgb(255, 255, 0)';
var color3 = ('#color3#' != '#'+'color3#') ? '#color3#' : 'rgb(255, 0, 0)';
jeedom.cmd.update['#id#'] = function(_options) {
var cmd = $('.cmd[data-cmd_uid=#uid#]');
$('.cmd[data-cmd_id=#id#]').attr('title','{{Date de valeur}} : '+_options.valueDate+'<br/>{{Date de collecte}} : '+_options.collectDate)
$('.cmd[data-cmd_uid=#uid#] .gaugearnog23').highcharts().series[0].points[0].update(_options.display_value)
if('#time#' == 'duration'){
jeedom.cmd.displayDuration(_options.valueDate, cmd.find('.timeCmd'));
}
else {
cmd.find('.timeCmd').parent().remove();
}
}
if (is_numeric('#state#')) {
$('.cmd[data-cmd_uid=#uid#] .gaugearnog23').empty().highcharts({
chart: {
style: {
fontFamily: 'Roboto'
},
type: 'solidgauge',
plotBackgroundColor: null,
plotBackgroundImage: null,
backgroundColor: null,
plotBorderWidth: 0,
plotShadow: false,
height: 106,
spacingTop: 0,
spacingLeft: 0,
spacingRight: 0,
spacingBottom: 0,
borderWidth : 0
},
title: null,
pane: {
center: ['50%', '50%'],
size: 85,
startAngle: 180,
endAngle: 540,
background: {
innerRadius: '70%',
outerRadius: '100%',
shape: 'arc',
borderWidth: 0,
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.3, color1],
[0.6, color2],
[0.9, color3]
],
lineWidth: 0,
minorTickInterval: null,
tickInterval: tickInterval,
tickWidth: 4,
tickLength: 15,
tickPosition: 'inside',
labels : {enabled: false},
min: min,
max: max,
zIndex: 6,
title: {
text: ''
}
},
labels : {enabled: false},
plotOptions: {
solidgauge: {
dataLabels: {
y: 9,
borderWidth: 0,
useHTML: true
}
}
},
credits: {
enabled: false
},
exporting : {
enabled: false
},
series: [{
name: '',
data: [Math.round(parseFloat('#state#') * 10) / 10],
radius: '100%',
innerRadius: '70%',
dataLabels: {
y: -22,
format: '<span style="color: var(--link-color); font-size: 24px;">{y}</span> <span style="color: var(--link-color); font-size: 12px; position: relative; top: -8px;">#unite#</span>'
},
}]
})
} else {
$('.cmd[data-cmd_uid=#uid#] .gaugearnog23').append('<center><span class="label label-danger">#state#</span></center>')
}
jeedom.cmd.update['#id#']({display_value:'#state#',valueDate:'#valueDate#',collectDate:'#collectDate#',alertLevel:'#alertLevel#'});
});
</script>
</div>
fonction includeJS (dans code widget ou personnalisation avancée)
function includeJS(filenames, callback) {
if (typeof filenames === 'string') {
filenames = [filenames];
}
let loadedCount = 0;
function loadScript(filename) {
/*if (document.querySelector(`script[src="${filename}"]`)) {
loadedCount++;
if (loadedCount === filenames.length) {
callback();
}
return;
}
*/
let sc = document.createElement('script');
sc.src = filename;
sc.type = 'text/javascript';
sc.async = true;
sc.onerror = function() {
loadedCount++;
if (loadedCount === filenames.length) {
callback();
}
sc.onerror = null;
};
sc.onload = sc.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
loadedCount++;
if (loadedCount === filenames.length) {
callback();
}
sc.onload = sc.onreadystatechange = null;
}
};
document.body.appendChild(sc);
}
filenames.forEach(filename => loadScript(filename));
}
Si vous avez l’occasion de tester et valider sur différents widgets sous Jeedom 4.4, je suis preneur de retours