Si d'abord, je regarde l'affichage myChart2 qui est seul, lorsque je réduit la largeur de la fenêtre, les dimensions de l'affichage suivent ce rétrécissement proportionnellement en horizontal et vertical. Si je ré-agrandis la fenêtre, l'affichage suit cet agrandissement proportionnellement en vertical et en horizontal pour revenir à ses dimensions d'origine.
Avec ce que tu me proposes, lors du rétrécissement, tout se passe bien, mais lors du ré-agrandissement, l'affichage reste à sa dimension réduite.
Par ailleurs, ce que je souhaite, est d'avoir l'affichage de gauche à 25 % et celui de droite à 75 %. Dans ces conditions, quelque soient les valeurs que je donne à height, ça ne change rien à l'affichage ; l'affichage à 25 % en width reste toujours inférieur en height par rapport à celui à 75% en width. Bref, un comportement pas très orthodoxe.
En suivant le tuto dont j'ai parlé précédemment, j'arrive à ce fichier html :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 Routeur photovoltaïque</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<style>
.cadreflex{
display: flex;
height: 500px;
background-color: #0AD;
border: 2px solid blue;
box-sizing: border-box;
margin: 20px 20px;
}
.cadre{
flex-direction: row;
}
.boite0{
flex-basis: 25%;
height: 50%;
background-color: #0DA;
padding: 10px 0px;
border: 2px solid green;
box-sizing: border-box;
margin: 5px;
}
.boite1{
flex-basis: 75%;
height: 50%;
background-color: #0DA;
padding: 10px 0px;
border: 2px solid green;
box-sizing: border-box;
margin: 5px;
}
</style>
</head>
<body onload="init();">
<h1 style="text-align: center;">ESP32 Routeur photovoltaïque</h1>
<div style="text-align: center;">
<button onclick="updateChart(1);" class="button button-data">Forme Courant & Tension</button>
<button onclick="updateChart(2);" class="button button-data">Historique Puissance</button>
</div>
<div id = "txt1">
<p>Date et Heure : <span id="DetH">0.00</span></p>
<p>Puissance active (W) : <span id="PA">0.00</span></p>
</div>
<div class="cadreflex cadre">
<div class="boite0">0</div>
<div class="boite1">1</div>
</div>
</body>
</html>
Si on l'exécute en tant que fichier html, on voit que si on raccourcit/agrandit la fenêtre, les containers (cadreflex, cadre, boite0 et boite1) suivent le mouvement ; ce que je souhaite.
Par contre, si au sein des containers intérieurs(boite0 et boite1), je place mes canvas, leurs affichages ne veulent plus suivre ... Voilà le code qui est une reprise de mon projet agrémenté de cette modification. C'est encore un fichier html qu'on peut lancer tout seul ...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 Routeur photovoltaïque</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<style>
.cadreflex{
display: flex;
height: 500px;
background-color: #0AD;
border: 2px solid blue;
box-sizing: border-box;
margin: 20px 20px;
}
.cadre{
flex-direction: row;
}
.boite0{
flex-basis: 25%;
height: 50%;
background-color: #0DA;
padding: 10px 0px;
border: 2px solid green;
box-sizing: border-box;
margin: 5px;
}
.boite1{
flex-basis: 75%;
height: 50%;
background-color: #0DA;
padding: 10px 0px;
border: 2px solid green;
box-sizing: border-box;
margin: 5px;
}
</style>
</head>
<body onload="init();">
<h1 style="text-align: center;">ESP32 Routeur photovoltaïque</h1>
<div style="text-align: center;">
<!-- <button id="maj-DT">MaJ Date & Heure</button> -->
<button onclick="updateChart(1);" class="button button-data">Forme Courant & Tension</button>
<button onclick="updateChart(2);" class="button button-data">Historique Puissance</button>
<a href="download-data"><button class="button button-data">Télécharger les données</button></a>
<button onclick="chgtHistos();" class="button button-data">Téléchargement historiques</button>
</div>
<div id = "txt1">
<p>Date et Heure : <span id="DetH">0.00</span></p>
<p>Puissance active (W) : <span id="PA">0.00</span></p>
</div>
<div id = "txt2">
<p>Puissance max : <input type="number" id="pMaxMod" value="1000" min="0"> <button onclick="ajusterPmax()">Ajuster</button></p>
</div>
<div class="cadreflex cadre">
<div class="boite0"><canvas id="myChart0" width="100%" height="100%" style="display: none"></canvas></div>
<div class="boite1"><canvas id="myChart1" width="100%" height="100%" style="display: none"></canvas></div>
</div>
<canvas id="myChart2" width="100%" height="35%" style="display: none"></canvas>
<script>
let txt1 = document.getElementById("txt1");
let txt2 = document.getElementById("txt2");
const interval = 2000;
let intervalId = -1;
let pAjustee = 1000; // Limite par défaut du nombre de points affichés
function init() {
txt1.style.display = "none";
txt2.style.display = "none";
}
async function chgtHistos() {
for (let i = 0; i < 7; i++) {
fetch('/quelFichier?val=' + i)
.then(response => {
const contentDisposition = response.headers.get('Content-Disposition');
const defaultFileName = `fichier_${i}.txt`; // Nom par défaut si le serveur n'en fournit pas
let fileName = defaultFileName;
if (contentDisposition && contentDisposition.includes('filename=')) {
const match = contentDisposition.match(/filename="?([^"]+)"?/);
if (match) {
fileName = match[1];
}
}
return response.blob().then(blob => ({ blob, fileName }));
})
.then(({ blob, fileName }) => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
.catch(error => console.error('Erreur lors du téléchargement:', error));
}
}
function ajusterPmax() {
const newPmax = document.getElementById('pMaxMod').value;
const parsedPmax = parseInt(newPmax, 10); // On force la base 10 pour la conversion
if (!isNaN(parsedPmax) && parsedPmax > 0) {
pAjustee = parsedPmax;
chart2.options.scales.y0.max = pAjustee;
chart2.options.scales.y2.max = pAjustee/230;
chart2.update();
fetch('/modifVal?val='+pAjustee);
}
}
const ctx0 = document.getElementById('myChart0').getContext('2d');
const chart0 = new Chart(ctx0, {
type: 'bubble',
data: {
datasets: [{
label: 'Cos Phi',
backgroundColor: 'rgb(255, 99, 132)'
}]
},
options: {
scales: {
x: {
min: -1,
max: 1,
display: true,
position: 'center',
title : {
display: true,
text: 'Re',
}
},
y: {
min: -1,
max: 1,
display: true,
position: 'center',
title : {
display: true,
text: 'Im',
}
}
}
}
});
const ctx1 = document.getElementById('myChart1').getContext('2d');
const chart1 = new Chart(ctx1, {
type: 'line',
data: {
labels: [],
datasets: [{
label: "Tension",
yAxisID: 'y0',
data: [],
borderColor: 'rgb(75, 192, 192)',
tension: 0.3 // Filtrage du signal ; doit être compris entre 0 (pas de filtrage) et 1 (filtrage max)
},
{
label: "Courant",
yAxisID: 'y1',
data: [],
borderColor: 'rgb(192, 192, 75)',
tension: 0.3
}]
},
options: {
scales: {
x: {
display: true,
title : {
display: true,
text: 'Echantillons',
}
},
y0: {
display: true,
position: 'left',
title : {
display: true,
text: 'Tension (V)',
}
},
y1: {
display: true,
position: 'left',
title : {
display: true,
text: 'Courant (A)',
}
}
}
}
});
const ctx2 = document.getElementById('myChart2').getContext('2d');
const chart2 = new Chart(ctx2, {
type: 'line',
data: {
labels: [],
datasets: [{
pointRadius: 0,
label: "Historique Puissance",
yAxisID: 'y0',
data: [],
borderColor: 'blue',
tension: 0.3 // Filtrage du signal ; doit être compris entre 0 (pas de filtrage) et 1 (filtrage max)
},
{
pointRadius: 0,
label: "Historique Tension",
yAxisID: 'y1',
data: [],
borderColor: 'green',
tension: 0.3
},
{
pointRadius: 0,
label: "Historique Courant",
yAxisID: 'y2',
data: [],
borderColor: 'red',
tension: 0.3
}]
},
options: {
plugins: {
zoom: {
zoom: {
drag: { // En sélectionnant une zone autour de la valeur à zoommer
enabled: true,
},
wheel: { // Avec la molette de la souris
enabled: true,
},
pinch: { // En pincement avec deux doigts sur un écran tactile
enabled: true,
},
mode: 'x',
onZoom: ({ brouette }) => console.log('Debut Zoom'),
onZoomComplete: ({ brouette }) => console.log('Fin Zoom'),
},
pan: {
enabled: true,
mode: 'x',
modifierKey: 'ctrl',
onPan: ({ brouette }) => console.log('Debut Pan'),
onPanStart: ({ brouette }) => console.log('Lancement Pan'),
onPanComplete: ({ brouette }) => console.log('Fin Pan'),
},
},
},
scales: {
x: {
display: true,
title : {
display: true,
text: 'Date et heure',
}
},
y0: {
min : 0,
max : pAjustee,
display: true,
position: 'right',
title : {
display: true,
text: 'Puissance (W)',
}
},
y1: {
min : 0,
max : 300,
display: true,
position: 'left',
title : {
display: true,
text: 'Tension (V)',
}
},
y2: {
min : 0,
max : 20,
display: true,
position: 'left',
title : {
display: true,
text: 'Courant (A)',
}
}
}
}
});
function updateChart(type) {
if (type == 1) {
fetch('/maj-DT')
.then(response => response.text())
.then(data => {
document.getElementById('DetH').textContent = data;
});
fetch('/pActive')
.then(response => response.text())
.then(data => {
document.getElementById('PA').textContent = data;
chart0.data.datasets[0].data = [{ x: 0.6, y: 0.3, r: 40 }];
chart0.update();
});
if (intervalId == -1) {
intervalId = setInterval(updateChart, interval, 1);
}
fetch('/formeUI')
.then(response => response.text())
.then(data => {
const rows = data.split('\n');
const labels = [];
const values0 = [];
const values1 = [];
let indx = 0;
rows.forEach(row => {
const [value0, value1] = row.split(',');
labels.push(indx++);
values0.push(parseFloat(value0));
values1.push(parseFloat(value1));
});
chart1.data.labels = labels;
chart1.data.datasets[0].data = values0;
chart1.data.datasets[1].data = values1;
chart1.update();
});
txt1.style.display = 'block';
txt2.style.display = 'none';
document.getElementById('myChart0').style.display = 'block';
document.getElementById('myChart1').style.display = 'block';
document.getElementById('myChart2').style.display = 'none';
} else {
if (intervalId != -1) {
clearInterval(intervalId);
}
intervalId = -1;
fetch('/histoUIP')
.then(response => response.text())
.then(data => {
const rows = data.split('\n');
const labels = [];
const values0 = [];
const values1 = [];
const values2 = [];
let indx = 0;
rows.forEach(row => {
const [label, value0, value1, value2] = row.split(',');
labels.push(label);
values0.push(parseFloat(value0));
values1.push(parseFloat(value1));
values2.push(parseFloat(value2));
});
chart2.resetZoom();
chart2.data.labels = labels;
chart2.data.datasets[0].data = values0;
chart2.data.datasets[1].data = values1;
chart2.data.datasets[2].data = values2;
chart2.update();
});
txt1.style.display = 'none';
txt2.style.display = 'block';
document.getElementById('myChart0').style.display = 'none';
document.getElementById('myChart1').style.display = 'none';
document.getElementById('myChart2').style.display = 'block';
}
}
</script>
</body>
</html>
Cordialement.
Pierre.