1169 lines
53 KiB
QML
1169 lines
53 KiB
QML
//========================================================================================================================================================================
|
|
// CAPTEUR.QML
|
|
// Ce fichier traite l'affichage des détails d'un capteur. La page affiche notamment :
|
|
// - La valeur actuelle
|
|
// - les valeurs mini et maxi sur la période avec leur date, la moyenne sur la période et le delta @1h
|
|
// - la courbe historique de niveau
|
|
// La page est appelée depuis la page HOME, en cliquant sur l'une des zones de bas de page ou depuis la page CAPTEURS.
|
|
//========================================================================================================================================================================
|
|
|
|
import QtQuick 2.12
|
|
import QtQuick.Controls 2.12
|
|
import QtQuick.Layouts 1.12
|
|
//import QtCharts 2.3
|
|
import QtCharts
|
|
|
|
import qt.koriolan.shipheart 1.0
|
|
import"fonctions.js" as Fonctions
|
|
import"fonctions_date_heure.js" as Fonctions_date_heure
|
|
|
|
|
|
|
|
Shipheart_page {
|
|
id: page_capteur
|
|
|
|
|
|
// Mis en forme :
|
|
readonly property double pourcentage_largeur_colonne_gauche: 0.5
|
|
readonly property double pourcentage_largeur_graphique: 0.85
|
|
readonly property double espace_colonnes_principales: 20
|
|
|
|
readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas - (2 * espace_lignes_principales)
|
|
readonly property double pourcentage_hauteur_ligne_haut: 0.6
|
|
readonly property double pourcentage_hauteur_ligne_erreur: 0.3 // Part de 'pourcentage_hauteur_ligne_haut'
|
|
readonly property double espace_lignes_principales: 20
|
|
|
|
readonly property double donnees_capteur_pourcentage_largeur_donnee: 0.33
|
|
readonly property double donnees_capteur_pourcentage_largeur_valeur: 0.33
|
|
readonly property double donnees_capteur_pourcentage_largeur_heure: 1 - (donnees_capteur_pourcentage_largeur_donnee + donnees_capteur_pourcentage_largeur_valeur)
|
|
|
|
readonly property double nb_boutons_periode: 4
|
|
|
|
readonly property int periode_init_raffraichissement_parametres: 1 // En ms
|
|
readonly property int periode_raffraichissement_parametres: 1000 // En ms
|
|
readonly property int periode_init_raffraichissement_graphiques: 20 // En ms
|
|
readonly property int periode_raffraichissement_graphiques: (15 * 1000) // en ms
|
|
|
|
|
|
// Affichage :
|
|
property bool courbe_flag_vide: false // Flag indiquant s'il y a des données à afficher ou pas
|
|
property int courbe_nombre_principal_graduations_axe_x: 13
|
|
property int courbe_nombre_zoom_1_graduations_axe_x: 8
|
|
property int courbe_nombre_graduations_axe_y: 5
|
|
property string courbe_format_principal_axe_x: "HH:mm" // exemple : "yyyy-MM-dd HH:mm:ss"
|
|
property string courbe_format_zoom_1_axe_x: "HH:mm" // exemple : "yyyy-MM-dd HH:mm:ss"
|
|
property bool flag_zoom_en_cours: false
|
|
property real zoomx_en_cours: 1
|
|
|
|
|
|
// Données :
|
|
property bool flag_init: true // Permet de bloquer certains affichage tant que l'init n'est pas terminée
|
|
|
|
property int code_capteur: shipheart_capteur_predefini_aucun
|
|
property int id_capteur: 0
|
|
property int etat_systeme: 0
|
|
property string nom_capteur: "---"
|
|
property int type_entrees: -1
|
|
property string entrees: ""
|
|
property int id_variable: -1
|
|
property int etat: 0
|
|
property string chaine_valeur: "---"
|
|
property string symbole_unite: ""
|
|
property int type_unite: 0
|
|
property int precision_affichage: 1
|
|
property int conversion_unite: 0
|
|
property int nouvelle_unite: 0
|
|
property int periode_analyse: 0
|
|
property string texte_alerte: ""
|
|
property int nb_events: -1 // -1: aucun event n'est lié à ce capteur, 0: au moins 1 event est lié à ce capteur mais aucun n'a Etat_test>0, 1: au moins un event lié et au moins un Etat_test=1
|
|
|
|
property date xMin_date
|
|
property date xMax_date
|
|
property real yMin_valeur: 0
|
|
property real yMax_valeur: 1
|
|
property int precision_affichage_axe_y_courbe: 1
|
|
|
|
|
|
|
|
|
|
// Modèles :
|
|
// Note : les modèles chargés dans 'main.qml' n'ont pas à être rechargés dans les pages suivantes
|
|
|
|
|
|
//===========================================================
|
|
// Timer periode raffraichissement parametres capteur :
|
|
//===========================================================
|
|
Timer {
|
|
id: timer_raffraichissement_parametres
|
|
interval: periode_init_raffraichissement_parametres
|
|
triggeredOnStart: false
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
if (interval === periode_init_raffraichissement_parametres) // Premier passage, 1ms après le premier chargement
|
|
{
|
|
interval = periode_raffraichissement_parametres;
|
|
busy_indicator.running = true;
|
|
init_page();
|
|
}
|
|
else
|
|
{
|
|
mise_a_jour_valeurs_instantanees();
|
|
}
|
|
}
|
|
}
|
|
|
|
//===========================================================
|
|
// Timer periode raffraichissement graphiques :
|
|
//===========================================================
|
|
Timer {
|
|
id: timer_raffraichissement_graphiques
|
|
interval: periode_raffraichissement_graphiques
|
|
triggeredOnStart: false
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
if (interval === periode_init_raffraichissement_graphiques) interval = periode_raffraichissement_graphiques;
|
|
|
|
if (!flag_init) // La gestion du premier calcul des courbes est géré directement par 'init()' car le séquençage des 2 timers au démarrage n'est pas garanti !!
|
|
{
|
|
if (!flag_zoom_en_cours) // On ne met pas à jour les courbes si on est en train de zoomer
|
|
{
|
|
mise_a_jour_courbes();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Titre de la page :
|
|
Shipheart_titre_1 {titre:nom_capteur; hauteur: shipheart_hauteur_bandeau_haut}
|
|
|
|
//-------------------------------------------------------
|
|
// Ecran haut - gauche :
|
|
//-------------------------------------------------------
|
|
Rectangle {
|
|
id: zone_affichage_haut_gauche
|
|
x: 0
|
|
y: shipheart_hauteur_bandeau_haut;
|
|
width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2);
|
|
height: affichage_hauteur_utile * pourcentage_hauteur_ligne_haut;
|
|
color: "transparent"
|
|
visible: (etat_systeme === 0)
|
|
|
|
//-------------------------------------------------------
|
|
// Valeur si aucune unité :
|
|
Rectangle {
|
|
id: valeur_capteur_sans_unite
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
visible: (symbole_unite === "")
|
|
|
|
Text {
|
|
anchors.fill: parent
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
padding: 10
|
|
text: chaine_valeur
|
|
font.family: "Montserrat"
|
|
fontSizeMode: Text.HorizontalFit;
|
|
minimumPixelSize: 30;
|
|
font.pixelSize: 80
|
|
elide: Text.ElideRight
|
|
wrapMode: Text.Wrap
|
|
font.weight: Font.Bold
|
|
color: couleur_blanc_casse
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------
|
|
// Valeur si unité :
|
|
Rectangle {
|
|
id: valeur_capteur_avec_unite
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
visible: (symbole_unite !== "")
|
|
|
|
Text {
|
|
id: valeur_actuelle
|
|
anchors {
|
|
verticalCenter: parent.verticalCenter
|
|
horizontalCenter: parent.horizontalCenter
|
|
horizontalCenterOffset: -20
|
|
}
|
|
text: chaine_valeur
|
|
font.family: "Montserrat"
|
|
font.pixelSize: 120
|
|
font.weight: Font.Bold
|
|
color: (nb_events > 0) ? couleur_rouge : couleur_blanc_casse
|
|
}
|
|
|
|
//-------------------------------------------------------
|
|
// Unite :
|
|
Text {
|
|
anchors {
|
|
baseline: valeur_actuelle.baseline
|
|
left: valeur_actuelle.right
|
|
leftMargin: 10
|
|
}
|
|
text: symbole_unite
|
|
font.pixelSize: 20
|
|
color: couleur_blanc_casse
|
|
}
|
|
}
|
|
|
|
//-----------------------------------
|
|
// Alarmes :
|
|
Rectangle {
|
|
id: zone_alarmes
|
|
width: parent.width
|
|
height: 50
|
|
color: shipheart_couleur_fond_bouton
|
|
radius: shipheart_rayon_bouton
|
|
anchors {
|
|
left: parent.left
|
|
bottom: parent.bottom
|
|
}
|
|
visible: nb_events >= 0
|
|
|
|
Image {
|
|
source: (nb_events === 0) ? "/images/cloche_sombre.png" : "/images/cloche_rouge.png"
|
|
sourceSize.height: 20
|
|
anchors {
|
|
verticalCenter: zone_alarmes.verticalCenter
|
|
horizontalCenter: zone_alarmes.horizontalCenter
|
|
}
|
|
}
|
|
|
|
//-----------------------------------
|
|
// Zone de clics dédiée aux alarmes :
|
|
MouseArea{
|
|
anchors.fill: zone_alarmes
|
|
|
|
onClicked: {
|
|
shipheart_clic();
|
|
boite_dialogue_liste_alarmes.open();
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
mise_a_jour_valeurs_instantanees();
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------
|
|
// Ecran haut - droite :
|
|
//-------------------------------------------------------
|
|
Rectangle {
|
|
id: zone_affichage_haut_droite
|
|
x: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) + (espace_colonnes_principales / 2);
|
|
y: shipheart_hauteur_bandeau_haut
|
|
width: ((shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2));
|
|
height: (affichage_hauteur_utile * pourcentage_hauteur_ligne_haut * pourcentage_hauteur_ligne_erreur) - (espace_lignes_principales / 2)
|
|
color: "transparent"
|
|
border.width: 3
|
|
border.color: couleur_rouge
|
|
radius: shipheart_rayon_bouton
|
|
visible: (etat_systeme === 0) && (texte_alerte !== "")
|
|
|
|
Image {
|
|
id: picto_alerte
|
|
source: "/images/ak14.png"
|
|
sourceSize.height: 30;
|
|
anchors {
|
|
left: parent.left
|
|
leftMargin: 20
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
Text { // Affiche parfaitement 1, 2 ou 3 lignes de texte. A partir de 4 et 5, ça mort sur le contour du rectangle mais c'est encore lisible.
|
|
width: parent.width - picto_alerte.width - picto_alerte.anchors.leftMargin - anchors.leftMargin;
|
|
wrapMode: Text.Wrap
|
|
horizontalAlignment: Text.AlignHCenter
|
|
leftPadding: 10 // Dégage le pictogramme sur la gauche
|
|
rightPadding: 10 // Evite de se caler sur le bord droit du rectangle
|
|
text: texte_alerte;
|
|
anchors {
|
|
left: picto_alerte.right
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
font.pixelSize: 16
|
|
color: couleur_blanc_casse
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------
|
|
// Ecran milieu - droite :
|
|
//-------------------------------------------------------
|
|
Rectangle {
|
|
id: zone_affichage_milieu_droite
|
|
x: zone_affichage_haut_droite.x
|
|
y: zone_affichage_haut_droite.y + zone_affichage_haut_droite.height + espace_lignes_principales
|
|
width: zone_affichage_haut_droite.width
|
|
height: (affichage_hauteur_utile * pourcentage_hauteur_ligne_haut * (1 - pourcentage_hauteur_ligne_erreur)) - (espace_lignes_principales / 2)
|
|
color: "transparent"
|
|
visible: (etat_systeme === 0)
|
|
|
|
ColumnLayout {
|
|
width: parent.width
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 10
|
|
|
|
ListModel {
|
|
id: modele_donnees_capteur
|
|
ListElement { donnee: qsTr("Max"); valeur: "---"; heure: "--:--" ; ligne_sup: 1; ligne_inf: 1; hauteur:50; }
|
|
ListElement { donnee: qsTr("Moyen"); valeur: "---"; heure: "" ; ligne_sup: 0; ligne_inf: 1; hauteur:50; }
|
|
ListElement { donnee: qsTr("Min"); valeur: "---"; heure: "--:--" ; ligne_sup: 0; ligne_inf: 1; hauteur:50; }
|
|
ListElement { donnee: qsTr("Delta (Max - Min)"); valeur: "---"; heure: "-----" ; ligne_sup: 0; ligne_inf: 1; hauteur:80; }
|
|
// ListElement { donnee: qsTr("Delta (24h)"); valeur: "---"; heure: "-----" ; ligne_sup: 0; ligne_inf: 1; hauteur:40; }
|
|
}
|
|
|
|
Repeater {
|
|
model: modele_donnees_capteur
|
|
|
|
Rectangle {
|
|
Layout.alignment: Qt.AlignCenter
|
|
Layout.preferredWidth: parent.width
|
|
Layout.preferredHeight: model.hauteur
|
|
color: "transparent"
|
|
|
|
Rectangle {
|
|
id: ligne_sup
|
|
height:1
|
|
width:parent.width
|
|
color: couleur_gris_tres_fonce_transparent
|
|
visible: model.ligne_sup ? 1 : 0;
|
|
}
|
|
Text {
|
|
id: titre_ligne
|
|
width: parent.width * donnees_capteur_pourcentage_largeur_donnee;
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
horizontalAlignment: Text.AlignLeft
|
|
leftPadding: 10
|
|
text: model.donnee
|
|
font.pixelSize: 18
|
|
color: couleur_blanc_casse
|
|
}
|
|
Text {
|
|
id: valeur_ligne
|
|
anchors.left: titre_ligne.right
|
|
width: parent.width * donnees_capteur_pourcentage_largeur_valeur;
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
text: model.valeur
|
|
font.pixelSize: 18
|
|
color: couleur_blanc_casse
|
|
}
|
|
Text {
|
|
id: heure_ligne
|
|
anchors.left: valeur_ligne.right
|
|
width: parent.width * donnees_capteur_pourcentage_largeur_heure;
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
horizontalAlignment: Text.AlignRight
|
|
rightPadding: 10
|
|
text: model.heure
|
|
font.pixelSize: 18
|
|
color: couleur_blanc_casse
|
|
}
|
|
Rectangle {
|
|
id: ligne_inf
|
|
anchors.top: parent.bottom;
|
|
height:1
|
|
width:parent.width
|
|
color: couleur_gris_tres_fonce_transparent
|
|
visible: model.ligne_inf ? 1 : 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------
|
|
// Ecran bas :
|
|
//-------------------------------------------------------
|
|
Rectangle {
|
|
id: zone_affichage_bas
|
|
x: 0
|
|
y: zone_affichage_haut_gauche.y + zone_affichage_haut_gauche.height + espace_lignes_principales;
|
|
width: shipheart_largeur_page;
|
|
height: affichage_hauteur_utile * (1 - pourcentage_hauteur_ligne_haut)
|
|
color: "transparent"
|
|
visible: (etat_systeme === 0)
|
|
|
|
//========================
|
|
// Graphique :
|
|
ChartView {
|
|
id: graphique
|
|
antialiasing: true
|
|
anchors {
|
|
top: parent.top;
|
|
left:parent.left;
|
|
bottom:parent.bottom;
|
|
margins: -15 // Un peu compliqué mais permet, avec la ligne suivante, ...
|
|
}
|
|
margins { right: 0; bottom: 0; left: 5; top: 0 } // ... d'annuler les marges.
|
|
width: parent.width * pourcentage_largeur_graphique;
|
|
backgroundColor: "transparent"
|
|
// animationDuration: 10000
|
|
// animationOptions: ChartView.SeriesAnimations
|
|
legend {visible: false }
|
|
visible: (id_variable !== 0)
|
|
|
|
DateTimeAxis {
|
|
id: axisX
|
|
format: (zoomx_en_cours > 0.5) ? courbe_format_principal_axe_x : courbe_format_zoom_1_axe_x
|
|
min: xMin_date
|
|
max: xMax_date
|
|
tickCount: (zoomx_en_cours > 0.5) ? courbe_nombre_principal_graduations_axe_x : courbe_nombre_zoom_1_graduations_axe_x
|
|
//labelsColor: (!flag_zoom_en_cours) ? couleur_blanc_casse : couleur_green_yellow
|
|
labelsColor: couleur_blanc_casse
|
|
labelsFont: Qt.font({pointSize: 10})
|
|
color: couleur_gris_moyen
|
|
shadesColor: courbes_couleur_shades_fond
|
|
shadesVisible: true
|
|
gridVisible: false
|
|
// gridLineColor: "green"
|
|
}
|
|
ValueAxis {
|
|
id: axisY1
|
|
min: yMin_valeur
|
|
max: yMax_valeur
|
|
tickCount: courbe_nombre_graduations_axe_y
|
|
labelFormat: "%." + precision_affichage_axe_y_courbe + "f"
|
|
// labelsColor: (!flag_zoom_en_cours) ? couleur_blanc_casse : couleur_green_yellow
|
|
labelsColor: couleur_blanc_casse
|
|
labelsFont:Qt.font({pointSize: 10})
|
|
color: couleur_gris_moyen
|
|
// shadesColor: courbes_couleur_shades_fond
|
|
shadesVisible: false
|
|
gridVisible: true
|
|
gridLineColor: couleur_gris_tres_fonce
|
|
titleText: "<font color='" + couleur_blanc_casse + "'>" + symbole_unite + "</font>"
|
|
titleFont {
|
|
pointSize: 20
|
|
bold: true
|
|
}
|
|
}
|
|
LineSeries { // Utilisé si on veut renforcer la courbe mais sans avoir tout le tour de l'area renfocée (qui se fait dans AreaSeries pour le coup)
|
|
id: courbe_principale
|
|
name: "Courbe principale"
|
|
axisX: axisX
|
|
axisY: axisY1
|
|
capStyle: Qt.RoundCap
|
|
style: Qt.SolidLine
|
|
width: courbes_epaisseur_bordure
|
|
color: shipheart_couleur_bordure_courbes
|
|
}
|
|
|
|
// Affichage des 2 points Min et Maxi :
|
|
ScatterSeries {
|
|
id: courbe_principale_mini_maxi
|
|
axisX: axisX
|
|
axisY: axisY1
|
|
|
|
markerSize: 10
|
|
borderColor: "transparent"
|
|
borderWidth: 0
|
|
color: couleur_green_yellow
|
|
}
|
|
|
|
Text {
|
|
id: texte_courbe_vide
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: qsTr("Aucune donnée n'est disponible pour cette période")
|
|
font.pixelSize: 20
|
|
font.weight: Font.Bold
|
|
color: "red"
|
|
visible: courbe_flag_vide ? true : false;
|
|
}
|
|
|
|
|
|
//---------------------------------
|
|
// Rectangle de sélection de zoom :
|
|
Rectangle {
|
|
id: rectangle_zoom
|
|
x: pinch_area.zoom_x
|
|
y: pinch_area.zoom_y
|
|
width: pinch_area.zoom_w
|
|
height: pinch_area.zoom_h
|
|
radius: shipheart_rayon_zoom
|
|
|
|
color: couleur_bleu_koriolan_tres_transparent
|
|
}
|
|
|
|
//---------------------------------
|
|
// Zone de pinch :
|
|
PinchArea{
|
|
id: pinch_area
|
|
|
|
// Propriété de la eone de zoom pendant toute la phase de sélection :
|
|
property real zoom_x: 0
|
|
property real zoom_y: 0
|
|
property real zoom_w: 0
|
|
property real zoom_h: 0
|
|
|
|
anchors.fill: parent // Calé sur 'graphique'.
|
|
// Attention : la zone de traçage à l'intérieur de 'graphique' est 'graphique.plotArea'.
|
|
// Toutes les coordonnées sont données dans 'graphique' mais on limite à l'usage les coordonnées intérieures à 'graphique.plotArea'.
|
|
|
|
//-----------------------------------------------
|
|
// Mis à jour en cours de déplacement du pinch :
|
|
onPinchUpdated: {
|
|
|
|
if ((pinch.point1.x !== pinch.point2.x) || // Il arrive, en fin de pinch, que les 2 points renvoyés soient les mêmes...
|
|
(pinch.point1.y !== pinch.point2.y)) // ... Il faut éviter de les traiter sous peine de ramener W et H à 0.
|
|
{
|
|
// Récupération des données en s'affranchissant de la position des 2 points :
|
|
zoom_x = Math.min(pinch.point1.x, pinch.point2.x)
|
|
zoom_y = Math.min(pinch.point1.y, pinch.point2.y)
|
|
zoom_w = Math.abs(pinch.point1.x - pinch.point2.x)
|
|
zoom_h = Math.abs(pinch.point1.y - pinch.point2.y)
|
|
|
|
// Limitation de 'x' et 'w' à la largeur de la zone de traçage :
|
|
if (zoom_x < graphique.plotArea.x) zoom_x = graphique.plotArea.x;
|
|
if (zoom_x > (graphique.plotArea.x + graphique.plotArea.width)) zoom_x = graphique.plotArea.x + graphique.plotArea.width
|
|
if ((zoom_x + zoom_w) > (graphique.plotArea.x + graphique.plotArea.width)) zoom_w = (graphique.plotArea.x + graphique.plotArea.width) - zoom_x;
|
|
|
|
// Limitation de 'y' et 'h' à la hauteur de la zone de traçage :
|
|
if (zoom_y < graphique.plotArea.y) zoom_y = graphique.plotArea.y;
|
|
if (zoom_y > (graphique.plotArea.y + graphique.plotArea.height)) zoom_y = graphique.plotArea.y + graphique.plotArea.height
|
|
if ((zoom_y + zoom_h) > (graphique.plotArea.y + graphique.plotArea.height)) zoom_h = (graphique.plotArea.y + graphique.plotArea.height) - zoom_y;
|
|
}
|
|
}
|
|
|
|
//-------------------------
|
|
// Valeur de fin du pinch :
|
|
onPinchFinished: {
|
|
// Préparation du zoom sur le rectangle sélectionné :
|
|
var r = Qt.rect(zoom_x, zoom_y, zoom_w, zoom_h);
|
|
graphique.zoomIn(r);
|
|
flag_zoom_en_cours = true;
|
|
|
|
zoomx_en_cours *= (zoom_w / graphique.plotArea.width);
|
|
|
|
// Effacement du rectangle :
|
|
zoom_x = 0
|
|
zoom_y = 0
|
|
zoom_w = 0
|
|
zoom_h = 0
|
|
}
|
|
|
|
// Déplacement de la courbe :
|
|
MouseArea{
|
|
anchors.fill: parent
|
|
drag.target: dragTarget
|
|
drag.axis: Drag.XAndYAxis
|
|
onClicked: {
|
|
shipheart_clic();
|
|
if (!flag_zoom_en_cours) // Si le zoom est en cours, il ne faut PAS lancer le raffraichissement...!
|
|
{
|
|
busy_indicator.running = true;
|
|
timer_raffraichissement_graphiques.interval = periode_init_raffraichissement_graphiques; // Cela permet de lancer le "busy_indicator' avant de faire la mise à jour de la courbe
|
|
}
|
|
}
|
|
onPressAndHold: {
|
|
raz_zoom();
|
|
}
|
|
}
|
|
Item {
|
|
id: dragTarget
|
|
property real oldX : x // Permet de mémoriser la dernière position d'arrivée
|
|
property real oldY : y
|
|
|
|
property real cumulX : 0 // Permet de revenir à un déclage nul lorsque nécessaire
|
|
property real cumulY : 0
|
|
|
|
onXChanged: {
|
|
graphique.scrollLeft( x - oldX );
|
|
cumulX -= (x - oldX); // Le signe '-' permettra ensuite de revenir à le position de départ
|
|
oldX = x;
|
|
}
|
|
|
|
onYChanged: {
|
|
graphique.scrollUp( y - oldY );
|
|
cumulY -= (y - oldY); // Le signe '-' permettra ensuite de revenir à le position de départ
|
|
oldY = y;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//========================
|
|
// Busy Indicator :
|
|
Shipheart_busy_indicator {
|
|
id: busy_indicator
|
|
}
|
|
|
|
//========================
|
|
// Boutons de pếriode :
|
|
ColumnLayout {
|
|
spacing: 10
|
|
anchors {
|
|
top: parent.top;
|
|
right:parent.right;
|
|
rightMargin: 5;
|
|
bottom:parent.bottom;
|
|
}
|
|
width: (parent.width * (1 - pourcentage_largeur_graphique)) - anchors.rightMargin;
|
|
|
|
ListModel {
|
|
id: modele_periodes_graphique
|
|
}
|
|
|
|
Repeater {
|
|
model: modele_periodes_graphique
|
|
|
|
Rectangle {
|
|
color: "transparent"
|
|
Layout.preferredWidth: parent.width;
|
|
Layout.preferredHeight: (parent.height / nb_boutons_periode) - parent.spacing;
|
|
|
|
Text {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: model.libelle
|
|
font.pixelSize: 18
|
|
font.weight: (model.index === periode_analyse) ? Font.Bold : Font.Normal
|
|
color: couleur_blanc_casse
|
|
}
|
|
MouseArea { // Zone d'interaction. On est obligé de la mettre dans la grille pour que Rectangle et MouseArea soient frères ou parent/enfant ET qu'on n'occupe qu'un espace dans la grille.
|
|
anchors.fill: parent
|
|
onClicked: {
|
|
shipheart_clic();
|
|
raz_zoom(); // Au-delà de la fonctionnalité, c'est obligatoire sinon, le raffraichissement des la courbe est bloqué au niveau du timer
|
|
periode_analyse = model.index;
|
|
busy_indicator.running = true;
|
|
timer_raffraichissement_graphiques.interval = periode_init_raffraichissement_graphiques; // Cela permet de lancer le "busy_indicator' avant de faire la mise à jour de la courbe
|
|
}
|
|
}
|
|
// Fond du bouton :
|
|
Rectangle { // Permet d'avoir un fond et de pouvoir régler son opacité sans changer celle des textes au-dessus
|
|
width: parent.width
|
|
height: parent.height
|
|
color: (model.index === periode_analyse) ? (flag_zoom_en_cours ? couleur_green_yellow_transparent : shipheart_couleur_fond_bouton_actif) : shipheart_couleur_fond_bouton;
|
|
opacity: 0.5
|
|
radius: shipheart_rayon_bouton
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
|
// mise_a_jour_courbes(); // Si on met la MAJ là, on va attendre la dispo des valeurs avant d'afficher le Rectangle. En la mettant dans un timer séparé, la page est affichée et on charge ensuite les valeurs.
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------
|
|
// Message d'erreur si capteur Absent
|
|
// (le module sur lequel le capteur est configuré n'est pas physiquement présent)
|
|
//-------------------------------------------------------
|
|
Rectangle {
|
|
id: zone_message_absence
|
|
x: 0
|
|
y: shipheart_hauteur_bandeau_haut + espace_lignes_principales
|
|
width: shipheart_largeur_page
|
|
height: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas - espace_lignes_principales
|
|
color: "transparent"
|
|
visible: (etat_systeme !== 0)
|
|
|
|
Rectangle { // Rectangle entouré de rouge
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.verticalCenterOffset: -50
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: parent.width
|
|
height: parent.height / 2
|
|
radius: shipheart_rayon_bouton
|
|
border.width: 3
|
|
border.color: couleur_rouge
|
|
color: couleur_rouge_transparent//"transparent"
|
|
|
|
Image { // Pictogramme DANGER
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.verticalCenterOffset: -100
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
source: "/images/ak14.png"
|
|
sourceSize.height: 70;
|
|
}
|
|
|
|
Text { // Texte d'info
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.verticalCenterOffset: 50
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: parent.width
|
|
height : parent.height / 2
|
|
horizontalAlignment: Qt.AlignCenter
|
|
verticalAlignment: Qt.AlignVCenter
|
|
padding: 50
|
|
text: (type_entrees === shipheart_capteur_type_entrees_ow)
|
|
? qsTr("La sonde One Wire correspondant à ce capteur n'est pas accessible.<br />Vérifier son câblage entre le port One Wire à l'arrière de ShipBase et la sonde.")
|
|
: qsTr("Le module assurant la supervision de ce capteur n'est pas accessible !<br /><br />Si des ajouts/suppression/déplacements de modules ont eu lieu récemment, mettez à jour la configuration correspondant dans le menu MODULES de PARAMETRES AVANCES.<br /><br />Dans le cas où aucune modification n'a été effectuée récemment, vérifier les connexions de tous les modules.")
|
|
color: couleur_blanc_casse
|
|
font.pixelSize: 18
|
|
wrapMode: Label.Wrap
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
// Bandeau bas :
|
|
//-------------------------------------------------------
|
|
Row {
|
|
x: 0
|
|
y: shipheart_hauteur_page - shipheart_hauteur_bandeau_bas;
|
|
width: shipheart_largeur_page;
|
|
height: shipheart_hauteur_bandeau_bas;
|
|
spacing: 5
|
|
padding: 5
|
|
|
|
|
|
//.................................................
|
|
// Bouton retour
|
|
//.................................................
|
|
Rectangle {
|
|
id: bandeau_bas_zone_retour
|
|
width: parent.width - (2 * parent.padding)
|
|
height: shipheart_hauteur_bandeau_bas - parent.topPadding - parent.bottomPadding;
|
|
radius: 5
|
|
color: shipheart_couleur_fond_bouton
|
|
|
|
Image {
|
|
source: "/images/icone_retour.png"
|
|
sourceSize.height: 30
|
|
anchors {
|
|
verticalCenter: parent.verticalCenter
|
|
horizontalCenter: parent.horizontalCenter
|
|
}
|
|
}
|
|
|
|
MouseArea { // Zone d'interaction. On est obligé de la mettre dans la grille pour que Rectangle et MouseArea soient frères ou parent/enfant ET qu'on n'occupe qu'un espace dans la grille.
|
|
id: mouse_area_bandeau_bas_zone_retour
|
|
anchors.fill: parent
|
|
onClicked: {
|
|
shipheart_clic();
|
|
stackView.pop()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------
|
|
// Boite d'affichage de la liste des alarmes :
|
|
//-------------------------------------------------------
|
|
Shipheart_boite_dialogue_liste_alarmes {
|
|
id: boite_dialogue_liste_alarmes
|
|
|
|
titre: nom_capteur
|
|
type_source: shipheart_source_mesure_capteur
|
|
id_source: id_capteur
|
|
id_variable: page_capteur.id_variable
|
|
titre_widget: nom_capteur
|
|
unite: symbole_unite
|
|
}
|
|
|
|
//===========================================================
|
|
// Economiseur : Doit être placé en fin de page pour fonctionner
|
|
//===========================================================
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
preventStealing: true // Permet que cela fonctionne même si un élément flickable (notamment) soit derrière et "vole" le click
|
|
enabled: flag_economiseur_actif
|
|
onClicked: {
|
|
mise_en_veille(0);
|
|
}
|
|
}
|
|
|
|
|
|
//=============================================================================================================
|
|
// Init de la page
|
|
//=============================================================================================================
|
|
function init_page()
|
|
{
|
|
|
|
if (id_capteur === 0)
|
|
{
|
|
console.log("La page 'capteur.qml' a été appelée sans 'id_capteur'. L'affichage de la page est impossible");
|
|
return;
|
|
}
|
|
|
|
//====================================================================
|
|
// Init du nom des périodes du graphique :
|
|
modele_periodes_graphique.append({ "libelle": Fonctions_date_heure.nom_periode_analyse(0), "actif": true });
|
|
modele_periodes_graphique.append({ "libelle": Fonctions_date_heure.nom_periode_analyse(1), "actif": true });
|
|
modele_periodes_graphique.append({ "libelle": Fonctions_date_heure.nom_periode_analyse(2), "actif": true });
|
|
modele_periodes_graphique.append({ "libelle": Fonctions_date_heure.nom_periode_analyse(3), "actif": true });
|
|
|
|
// Première mise à jour :
|
|
mise_a_jour_valeurs_instantanees();
|
|
mise_a_jour_courbes();
|
|
|
|
// Libération du flag :
|
|
flag_init = false;
|
|
}
|
|
|
|
|
|
//=============================================================================================================
|
|
// Mise à jour de la valeur instantannée
|
|
//=============================================================================================================
|
|
function mise_a_jour_valeurs_instantanees()
|
|
{
|
|
var req, res;
|
|
var nb;
|
|
var i;
|
|
var liste_valeurs_textes;
|
|
var age;
|
|
var valeur;
|
|
|
|
|
|
req = 'SELECT Cle_primaire, ';
|
|
req += ' Etat_systeme, ';
|
|
req += ' Nom, ';
|
|
req += ' Type_entrees, ';
|
|
req += ' Entrees, ';
|
|
req += ' ID_Variable, ';
|
|
req += ' Etat, ';
|
|
req += ' Valeur, ';
|
|
req += ' Precision_affichage_mesures, ';
|
|
req += ' Liste_valeurs_textes, ';
|
|
|
|
req += ' IF ( (Type_entrees=' + shipheart_capteur_type_entrees_nmea + '), ';
|
|
req += ' ( SELECT ( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(Date_maj) ) ';
|
|
req += ' FROM TB_Nmea2000 WHERE ';
|
|
req += ' Pgn=SUBSTRING_INDEX(Entrees, \':\', 1) AND Field=SUBSTRING_INDEX(Entrees, \':\', -1) ), ';
|
|
req += ' (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(Date_maj)) )';
|
|
req += ' AS Age ';
|
|
|
|
|
|
req += ' FROM TB_Capteurs WHERE Cle_primaire="' + id_capteur + '" ';
|
|
//console.log("Requête = [" + req + "]");
|
|
res = bdd.requete_unique(req);
|
|
|
|
i = 0;
|
|
id_capteur = Number(res[i++]);
|
|
etat_systeme = Number(res[i++]);
|
|
nom_capteur = res[i++];
|
|
type_entrees = Number(res[i++]);
|
|
entrees = res[i++];
|
|
id_variable = Number(res[i++]);
|
|
etat = Number(res[i++]);
|
|
valeur = Number(res[i++]);
|
|
precision_affichage = Number(res[i++]);
|
|
liste_valeurs_textes = res[i++];
|
|
age = Number(res[i++]);
|
|
|
|
texte_alerte = "";
|
|
|
|
// Recherche infos sur variable :
|
|
req = ' SELECT Unite, Conversion_unite FROM TB_Variables WHERE Cle_primaire="' + id_variable + '" ';
|
|
res = bdd.requete_unique(req);
|
|
i = 0;
|
|
symbole_unite = res[i++];
|
|
conversion_unite = Number(res[i++]);
|
|
|
|
// Traitement des conversions d'unités :
|
|
switch(conversion_unite)
|
|
{
|
|
case shipheart_type_unite_volume:
|
|
nouvelle_unite = shipheart_unite_volume;
|
|
symbole_unite = shipheart_unite_volume_symbole;
|
|
type_unite = shipheart_type_unite_volume;
|
|
break;
|
|
case shipheart_type_unite_temperature:
|
|
nouvelle_unite = shipheart_unite_temperature;
|
|
symbole_unite = shipheart_unite_temperature_symbole;
|
|
type_unite = shipheart_type_unite_temperature;
|
|
break;
|
|
case shipheart_type_unite_latitude:
|
|
nouvelle_unite = 0;
|
|
symbole_unite = "";
|
|
type_unite = shipheart_type_unite_latitude;
|
|
break;
|
|
case shipheart_type_unite_longitude:
|
|
nouvelle_unite = 0;
|
|
symbole_unite = "";
|
|
type_unite = shipheart_type_unite_longitude;
|
|
break;
|
|
default:
|
|
nouvelle_unite = 0;
|
|
type_unite = 0;
|
|
break;
|
|
}
|
|
|
|
// Cas spécifiques en fonction du type de capteur :
|
|
chaine_valeur = Fonctions.conversion_unites( valeur, nouvelle_unite, "", precision_affichage, type_unite);
|
|
switch(type_entrees)
|
|
{
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_aux:
|
|
case shipheart_capteur_type_entrees_calculee_booleen:
|
|
|
|
// Traitement des listes :
|
|
var chaines_valeurs_textes = liste_valeurs_textes.split(';');
|
|
for (let chaine_valeur_texte of chaines_valeurs_textes)
|
|
{
|
|
var chaine = chaine_valeur_texte.split('/');
|
|
if (chaine.length === 2) // Evite de traiter les cas invalides (notamment, une chaine totalement vide qui arrive ici avec un length de 1...)
|
|
{
|
|
if (valeur === Number(chaine [0])) // Si l'une des valeurs de la liste correspond à la valeur actuelle :
|
|
{
|
|
chaine_valeur = chaine[1]; // La valeur affichée sera le texte correspondant.
|
|
break; // Et il est inutile de chercher d'autres valeurs...
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_level_sensor:
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_ow:
|
|
|
|
if (etat !== shipheart_capteur_etat_normal)
|
|
{
|
|
texte_alerte = qsTr("La sonde One Wire du capteur est détectée en défaut.<br />Vérifier son câblage depuis l'arrière de ShipBase.")
|
|
}
|
|
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_predefinie:
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_nmea:
|
|
if (age > shipheart_periode_obsolescence_capteur_nmea)
|
|
{
|
|
texte_alerte = qsTr("Le capteur n'a pas reçu de mise à jour sur le réseau NMEA depuis<br />%1<br />Les données affichées sont donc probablement obsolètes.").arg(Fonctions_date_heure.chaine_duree(age * 1000));
|
|
}
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
default :
|
|
break;
|
|
}
|
|
|
|
|
|
// Recherche des events liés à ce capteur et leur valeur :
|
|
nb_events = -1;
|
|
|
|
req = 'SELECT Etat_test ';
|
|
req += ' FROM TB_Events ';
|
|
req += ' WHERE Validite=1 ';
|
|
req += ' AND Alarme_source>0 ';
|
|
req += ' AND Type_source=' + shipheart_source_mesure_capteur + ' ';
|
|
req += ' AND ID_Source=' + id_capteur + ' ';
|
|
//console.log("Requête = [ " + req + "; ]");
|
|
nb = bdd.requete(req);
|
|
for (i = 0; i < nb; i ++)
|
|
{
|
|
res = bdd.lecture_ligne();
|
|
if (!res.isEmpty)
|
|
{
|
|
if (nb_events < Number(res[0])) nb_events = Number(res[0]);
|
|
}
|
|
}
|
|
// En sorttant, on a donc nb_events=-1 si aucun event lié, 0 si au moins un event lié mais tous leurs Etat_test=0, et 1 si au moins un event et au moins un a Etat_test=1.
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================================================
|
|
// Mise à jour des données des courbes
|
|
//=============================================================================================================
|
|
function mise_a_jour_courbes()
|
|
{
|
|
var req, res;
|
|
var nb;
|
|
var date_debut, date_fin;
|
|
var courbe_principale_duree;
|
|
var mini_maxi;
|
|
var ymin_x, ymin_y, ymax_x, ymax_y;
|
|
var delta_x, delta_y;
|
|
var gradient;
|
|
var chaine_valeur_min, chaine_valeur_moyenne, chaine_valeur_max;
|
|
var format_chaine_heure; // 0=format court ("hh:mm") et 1=format long ("MM/dd hh:mm")
|
|
|
|
console.time('mise_a_jour_courbes')
|
|
|
|
// Paramètres de la courbe dépendant de la période d'analyse :
|
|
switch(periode_analyse)
|
|
{
|
|
default:
|
|
case 0: // 1 heure
|
|
courbe_nombre_principal_graduations_axe_x = 7 // Nombre de bandes verticales + 1
|
|
courbe_nombre_zoom_1_graduations_axe_x = 7 // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
courbe_format_principal_axe_x = "HH:mm" // exemple : "yyyy-MM-dd HH:mm:ss"
|
|
courbe_format_zoom_1_axe_x = "HH:mm" // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
break;
|
|
|
|
case 1: // 24 heures
|
|
courbe_nombre_principal_graduations_axe_x = 13 // Nombre de bandes verticales + 1
|
|
courbe_nombre_zoom_1_graduations_axe_x = 13 // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
courbe_format_principal_axe_x = "HH:mm" // exemple : "yyyy-MM-dd HH:mm:ss"
|
|
courbe_format_zoom_1_axe_x = "HH:mm" // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
break;
|
|
|
|
case 2: // 7 jours
|
|
courbe_nombre_principal_graduations_axe_x = 8 // Nombre de bandes verticales + 1
|
|
courbe_nombre_zoom_1_graduations_axe_x = 8 // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
courbe_format_principal_axe_x = "dd/MM HH:mm" // exemple : "yyyy-MM-dd HH:mm:ss"
|
|
courbe_format_zoom_1_axe_x = "HH:mm" // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
break;
|
|
|
|
case 3: // 30 jours
|
|
courbe_nombre_principal_graduations_axe_x = 31 // Nombre de bandes verticales + 1
|
|
courbe_nombre_zoom_1_graduations_axe_x = 13 // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
courbe_format_principal_axe_x = "dd" // exemple : "yyyy-MM-dd HH:mm:ss"
|
|
courbe_format_zoom_1_axe_x = "HH:mm" // Utilisé lorsque le taux de zoom passe en-dessous de 0.5
|
|
break;
|
|
}
|
|
|
|
|
|
// Dates et durée :
|
|
courbe_principale_duree = Fonctions_date_heure.duree_periode_analyse(periode_analyse); // En secondes
|
|
date_fin = new Date(); // En UTC
|
|
date_debut = Fonctions_date_heure.date_add_secondes(date_fin, -(courbe_principale_duree)); // En UTC
|
|
//console.log("Date de début initiale UTC = " + date_debut + " et date de fin UTC = " + date_fin)
|
|
|
|
// Mise à jour des données de la courbe principale :
|
|
console.log("Type_unite="+type_unite+", et nouvelle_unite="+nouvelle_unite);
|
|
res = tbmesuresModel.maj_data(graphique.series("Courbe principale"), "TB_Mesures_capteurs", id_capteur, id_variable, date_debut, date_fin, 1, 1, (shipheart_fuseau_horaire + shipheart_heure_ete), type_unite, nouvelle_unite);
|
|
|
|
|
|
// Traitements spécifiques en focntion du type de capteur :
|
|
chaine_valeur_min = Number(res[6]).toFixed(precision_affichage) + " " + symbole_unite;
|
|
chaine_valeur_moyenne = Number(res[9]).toFixed(precision_affichage) + " " + symbole_unite;
|
|
chaine_valeur_max = Number(res[8]).toFixed(precision_affichage) + " " + symbole_unite;
|
|
|
|
switch(type_entrees)
|
|
{
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_aux:
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_level_sensor:
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_ow:
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
case shipheart_capteur_type_entrees_predefinie:
|
|
|
|
if (Number(entrees) === shipheart_capteur_predefini_lat)
|
|
{
|
|
chaine_valeur_min = Fonctions.chaine_latitude(Number(res[6]));
|
|
chaine_valeur_moyenne = Fonctions.chaine_latitude(Number(res[9]));
|
|
chaine_valeur_max = Fonctions.chaine_latitude(Number(res[8]));
|
|
}
|
|
if (Number(entrees) === shipheart_capteur_predefini_lon)
|
|
{
|
|
chaine_valeur_min = Fonctions.chaine_longitude(Number(res[6]));
|
|
chaine_valeur_moyenne = Fonctions.chaine_longitude(Number(res[9]));
|
|
chaine_valeur_max = Fonctions.chaine_longitude(Number(res[8]));
|
|
}
|
|
|
|
break;
|
|
|
|
//-----------------------------------------------------------------
|
|
default :
|
|
break;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------
|
|
// Cas où aucune donnée n'est disponible sur la période :
|
|
if (Number(res[0]) === 0)
|
|
{
|
|
courbe_principale_flag_vide = true; // Permet d'afficher le texte "Aucune donnée disponible..." sur la zone graphique
|
|
|
|
modele_donnees_capteur.set(0, {"valeur": "---", heure : "--:--"}) // valeurs par défaut pour supprimer les anciennes valeurs
|
|
modele_donnees_capteur.set(1, {"valeur": "---", heure : "--"})
|
|
modele_donnees_capteur.set(2, {"valeur": "---", heure : "--:--"})
|
|
modele_donnees_capteur.set(3, {"valeur": "---", heure : "--:--"})
|
|
// modele_donnees_capteur.set(4, {"valeur": "---", heure : "--:--"})
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------
|
|
// Cas où des données sont disponibles sur la période (cas normal donc...) :
|
|
else
|
|
{
|
|
courbe_flag_vide = false;
|
|
|
|
xMin_date = new Date(Number(res[1])); // Nécessaire pour la Min de l'axe X (NB : les dates retournées par 'maj_data' sont en heure locale)
|
|
xMax_date = new Date(Number(res[3])); // Nécessaire pour la Max de l'axe X (NB : les dates retournées par 'maj_data' sont en heure locale)
|
|
mini_maxi = Fonctions.ajustement_mini_maxi(Number(res[6]), Number(res[8]), courbe_nombre_graduations_axe_y);
|
|
yMin_valeur = mini_maxi.mini // Nécessaire pour le Min de l'axe Y
|
|
yMax_valeur = mini_maxi.maxi // Nécessaire pour le Max de l'axe Y
|
|
precision_affichage_axe_y_courbe = Fonctions.precision_affichage_mini_maxi(Number(res[6]), Number(res[8]), courbe_nombre_graduations_axe_y);
|
|
//console.log("Min val=" + Number(res[6]) + " et mini=" + yMin_valeur + " - Max val=" + Number(res[8]) + " et maxi=" + yMax_valeur);
|
|
|
|
// Mise à jour des données numériques :
|
|
var chaine_heure;
|
|
|
|
if (format_chaine_heure === 0) chaine_heure = Fonctions_date_heure.chaine_heure_courte(new Date(Number(res[7]))); // Date MAX format court...
|
|
else chaine_heure = Fonctions_date_heure.chaine_date_heure_courte(new Date(Number(res[7]))); // ... ou format long
|
|
modele_donnees_capteur.set(0, {"valeur": chaine_valeur_max, "heure": "[" + chaine_heure + "]"}) // Valeur MAX
|
|
modele_donnees_capteur.set(1, {"valeur": chaine_valeur_moyenne}) // Valeur MOYENNE
|
|
if (format_chaine_heure === 0) chaine_heure = Fonctions_date_heure.chaine_heure_courte(new Date(Number(res[5]))); // Date MIN format court...
|
|
else chaine_heure = Fonctions_date_heure.chaine_date_heure_courte(new Date(Number(res[5]))); // ... ou format long
|
|
modele_donnees_capteur.set(2, {"valeur": chaine_valeur_min, "heure": "[" + chaine_heure + "]"}) // Valeur MIN
|
|
|
|
// Calcul du delta X :
|
|
ymin_x = Number(res[5]);
|
|
ymax_x = Number(res[7]);
|
|
delta_x = ymax_x - ymin_x;
|
|
|
|
// Calcul du delta Y :
|
|
ymin_y = Number(res[6]);
|
|
ymax_y = Number(res[8]);
|
|
delta_y = ymax_y - ymin_y;
|
|
|
|
// Ajout du delta :
|
|
modele_donnees_capteur.set(3, {"valeur": ((ymax_x > ymin_x) ? "+" : "-") + delta_y.toFixed(precision_affichage + 1) + " " + symbole_unite, "heure": Fonctions_date_heure.chaine_duree(delta_x)})
|
|
|
|
// Ajout des points de Min/Max sur la courbe :
|
|
courbe_principale_mini_maxi.clear();
|
|
courbe_principale_mini_maxi.append(ymin_x, ymin_y);
|
|
courbe_principale_mini_maxi.append(ymax_x, ymax_y);
|
|
|
|
}
|
|
busy_indicator.running = false; // Arrêt du tourniquet s'il est en marche
|
|
|
|
console.timeEnd('mise_a_jour_courbes')
|
|
}
|
|
|
|
//=============================================================================================================
|
|
// RAZ du zoom
|
|
//=============================================================================================================
|
|
function raz_zoom()
|
|
{
|
|
|
|
graphique.zoomReset(); // RAZ du zoom proprement dit
|
|
graphique.scrollLeft(dragTarget.cumulX); // RAZ du déplacement horizontal par annulation du cumul
|
|
graphique.scrollUp(dragTarget.cumulY); // RAZ du déplacement vertical par annulation du cumul
|
|
|
|
dragTarget.cumulX = 0; // RAZ du cumul après retour à la position d'origine
|
|
dragTarget.cumulY = 0;
|
|
|
|
flag_zoom_en_cours = false;
|
|
zoomx_en_cours = 1;
|
|
}
|
|
}
|
|
|