Guides pratiques HMIx

Créer un graphique circulaire CWC pour WinCC Unified

Un graphique circulaire permet de comparer la production de plusieurs lignes en un coup d’œil. Créons-le avec HTML, CSS et JavaScript, puis testons-le dans TIA Portal avec trois variables internes.

Équipe HMIx10 min de lectureVérifié le
Illustration d’un pupitre HMI avec un graphique circulaire à trois séries de valeurs 45, 35 et 20
Illustration créée par IA pour HMIx. L’exemple téléchargeable reprend ces trois valeurs dans un graphique en anneau avec une légende.

Environnement du guide : TIA Portal / WinCC Unified V21.1. Vérifiez l’importation et le fonctionnement de l’exemple sur votre appareil cible.

01

Qu'est-ce qu'un Custom Web Control ?

Un Custom Web Control, ou CWC, est un petit composant web placé dans une vue WinCC Unified. HTML définit son contenu, CSS son apparence et JavaScript son comportement. Il est utile lorsque les objets HMI standard n'offrent pas la présentation ou l'interaction souhaitée.

Pensez à un tableau de production, une table ou un graphique circulaire. Le contrôle expose des propriétés : des entrées nommées, comme ValueA. Dans TIA Portal, chaque propriété est liée à une variable HMI ; le CWC reçoit les valeurs et met le graphique à jour. Il ne se connecte pas directement à l’automate.

  • Choisissez un CWC pour des interactions spécifiques, plusieurs valeurs coordonnées ou une présentation particulière.
  • Pour un symbole dont la couleur, la position ou le remplissage varie, un SVG dynamique est souvent plus simple.
  • Pour réutiliser un ensemble d'objets HMI standard, envisagez un faceplate.

HMIx propose des centaines de ressources HMI gratuites à télécharger. Partez d'un contrôle du catalogue ou décrivez votre idée au générateur IA de HMIx pour créer une ressource adaptée à votre projet.

Pie Chart de HMIx avec cinq secteurs, une légende et une infobulle de série
Pie Chart – Dashboard Widget, publié sur HMIx : un graphique en anneau avec cinq éléments et des titres configurables. Téléchargez-le depuis sa fiche. Nous allons ensuite construire une version à trois entrées pour comprendre son fonctionnement. Voir cette ressource sur HMIx

Siemens · Programmation des Custom Web Controls

02

Avant de commencer

Utilisez un projet d'essai avec un appareil WinCC Unified et une vue vide. TIA Portal avec WinCC Unified Engineering et les composants Runtime ou de simulation compatibles doivent être installés. Un projet Comfort classique et un projet Unified sont deux cibles différentes.

  • Pour le premier test, utilisez Unified PC Runtime ou la simulation prise en charge par votre appareil Unified.
  • Pour modifier l'exemple, prévoyez un éditeur de texte et un outil ZIP. Visual Studio Code est pratique, mais pas obligatoire.
  • Aucun automate n’est nécessaire : trois variables HMI internes et trois champs E/S fourniront les valeurs de test.

L'aperçu dans un navigateur vérifie le dessin. Seul un essai dans Unified vérifie la connexion WebCC et la liaison à la variable.

03

Construire un graphique circulaire à trois valeurs

Notre graphique prend la forme d’un anneau : le total est au centre et chaque série figure dans la légende. Les entrées ValueA, ValueB et ValueC valent au départ 45, 35 et 20. Ce sont des quantités ; leur somme n’a pas besoin d’être 100. Le contrôle calcule la part de chacune.

  1. Préparer les fichiers

    Créez manifest.json à la racine et deux dossiers : assets et control. Dans control, créez index.html et code.js. Récupérez webcc.min.js de Siemens dans l'exemple officiel indiqué plus bas et placez-le aussi dans control. Chaque fichier a un rôle ; aucun framework web n'est nécessaire.

  2. Définir les trois entrées

    Dans manifest.json, déclarez ValueA, ValueB et ValueC comme nombres, avec les valeurs par défaut 45, 35 et 20. Le manifeste précise aussi le nom HMIx Pie Chart, son identité et son fichier de démarrage.

  3. Dessiner le graphique et la légende

    Dans control/index.html, placez un anneau à trois segments, le total et la légende A, B et C. Dans code.js, divisez chaque valeur par la somme pour obtenir sa proportion. Si les trois valeurs sont nulles, affichez un anneau vide. L’exemple utilise du SVG dans le HTML, sans bibliothèque de graphiques.

  4. Établir le lien avec Unified

    Chargez webcc.min.js de Siemens sans le modifier. Démarrez WebCC avec les mêmes trois propriétés, lisez leurs valeurs à la connexion et redessinez lors d’un changement signalé par onPropertyChanged. Les données actuelles apparaissent ainsi dès l’ouverture de l’écran.

  5. Créer le paquet

    Placez manifest.json, assets et control à la racine du ZIP, sans dossier supplémentaire autour. Nommez le ZIP avec le GUID du contrôle entre accolades. Après modification, recréez le ZIP avec cette structure ; changer uniquement son nom ne crée pas une nouvelle identité de contrôle.

Les noms ValueA, ValueB et ValueC doivent correspondre dans le manifeste et le JavaScript. Le téléchargement de ce guide est un exemple original à trois entrées ; le Pie Chart du catalogue utilise Apache ECharts et cinq éléments avec Value et Title.

Télécharger l’exemple de graphique circulaire

ZIP complet avec trois entrées numériques et WebCC. Code et structure vérifiés ; validez l’importation et la connexion dans WinCC Unified V21.1.

Voir le code de l'exemple

Facultatif : le téléchargement contient l'exemple complet. Il n'est pas nécessaire de saisir ce code pour réaliser le test.

manifest.json

{
  "mver": "1.2.0",
  "control": {
    "identity": {
      "name": "HmixPieChart",
      "version": "1.0",
      "displayname": "HMIx Pie Chart",
      "type": "guid://8D821B43-4EF5-4BF1-A31D-931D283C7C04",
      "start": "./control/index.html"
    },
    "metadata": {
      "author": "HMIx",
      "description": "Educational read-only three-value pie chart"
    },
    "contracts": {
      "api": {
        "methods": {},
        "events": {},
        "properties": {
          "ValueA": { "type": "number", "default": 45 },
          "ValueB": { "type": "number", "default": 35 },
          "ValueC": { "type": "number", "default": 20 }
        }
      }
    },
    "types": {}
  }
}

control/index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>HMIx Pie Chart</title>
    <style>
      * {
        box-sizing: border-box;
      }
      body {
        margin: 0;
        padding: 20px;
        background: #171e26;
        color: #f3f5f6;
        font:
          14px system-ui,
          sans-serif;
      }
      header {
        display: flex;
        justify-content: space-between;
        color: #bac5ce;
        font-size: 11px;
        letter-spacing: 0.14em;
      }
      main {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 24px;
        min-height: 240px;
      }
      svg {
        width: 55%;
        max-width: 300px;
        flex-shrink: 0;
      }
      ul {
        list-style: none;
        padding: 0;
        min-width: 110px;
      }
      li {
        display: grid;
        grid-template-columns: 10px 1fr auto;
        align-items: center;
        gap: 10px;
        padding: 14px 0;
        border-bottom: 1px solid #35404a;
      }
      .dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
      }
      small {
        display: block;
        margin-top: 4px;
        color: #bac5ce;
        font-variant-numeric: tabular-nums;
      }
      strong {
        font-variant-numeric: tabular-nums;
      }
      @media (max-width: 360px) {
        body {
          padding: 12px;
        }
        main {
          gap: 12px;
        }
      }
    </style>
  </head>
  <body>
    <header><span>HMIx</span><span>PIE CHART</span></header>
    <main>
      <svg viewBox="0 0 220 220" role="img" aria-labelledby="chart-title">
        <title id="chart-title">Distribution of A, B and C</title>
        <circle
          cx="110"
          cy="110"
          r="76"
          fill="none"
          stroke="#35404a"
          stroke-width="28"
        />
        <g transform="rotate(-90 110 110)" fill="none" stroke-width="28">
          <circle id="ValueA" cx="110" cy="110" r="76" stroke="#47d2c8" />
          <circle id="ValueB" cx="110" cy="110" r="76" stroke="#79a9ed" />
          <circle id="ValueC" cx="110" cy="110" r="76" stroke="#f5c16c" />
        </g>
        <text
          id="total"
          x="110"
          y="115"
          text-anchor="middle"
          fill="#f3f5f6"
          font-size="30"
          font-weight="600"
        >
          100
        </text>
        <text
          x="110"
          y="139"
          text-anchor="middle"
          fill="#bac5ce"
          font-size="10"
          letter-spacing="2"
        >
          A + B + C
        </text>
      </svg>
      <ul aria-label="Values and shares">
        <li>
          <i class="dot" style="background: #47d2c8"></i
          ><span>A<small id="ValueA-amount">45</small></span
          ><strong id="ValueA-percent">45%</strong>
        </li>
        <li>
          <i class="dot" style="background: #79a9ed"></i
          ><span>B<small id="ValueB-amount">35</small></span
          ><strong id="ValueB-percent">35%</strong>
        </li>
        <li>
          <i class="dot" style="background: #f5c16c"></i
          ><span>C<small id="ValueC-amount">20</small></span
          ><strong id="ValueC-percent">20%</strong>
        </li>
      </ul>
    </main>
    <script src="webcc.min.js"></script>
    <script src="code.js"></script>
  </body>
</html>

control/code.js

/* HMIx educational pie chart. Values are amounts, not required percentages. */
var values = { ValueA: 45, ValueB: 35, ValueC: 20 };
var keys = ['ValueA', 'ValueB', 'ValueC'];
var circumference = 2 * Math.PI * 76;

function drawChart() {
  // Normalize before adding to avoid overflow for very large finite values.
  var maximum = Math.max(values.ValueA, values.ValueB, values.ValueC, 1);
  var sum = keys.reduce(function (n, key) {
    return n + values[key] / maximum;
  }, 0);
  var offset = 0;
  keys.forEach(function (key) {
    var fraction = sum ? values[key] / maximum / sum : 0;
    var arc = document.getElementById(key);
    var length = fraction * circumference;
    arc.setAttribute('stroke-dasharray', length + ' ' + circumference);
    arc.setAttribute('stroke-dashoffset', String(-offset));
    arc.setAttribute('visibility', fraction ? 'visible' : 'hidden');
    document.getElementById(key + '-amount').textContent = String(values[key]);
    document.getElementById(key + '-percent').textContent =
      Math.round(fraction * 100) + '%';
    offset += length;
  });
  var total = values.ValueA + values.ValueB + values.ValueC;
  document.getElementById('total').textContent = isFinite(total)
    ? String(total)
    : '—';
}

function setValue(key, value) {
  if (keys.indexOf(key) === -1 || typeof value !== 'number' || !isFinite(value))
    return;
  values[key] = Math.max(0, value);
}

drawChart();
if (typeof WebCC !== 'undefined') {
  WebCC.start(
    function (connected) {
      if (!connected) return;
      keys.forEach(function (key) {
        setValue(key, WebCC.Properties[key]);
      });
      drawChart();
      WebCC.onPropertyChanged.subscribe(function (change) {
        setValue(change.key, change.value);
        drawChart();
      });
    },
    {
      methods: {},
      events: [],
      properties: { ValueA: 45, ValueB: 35, ValueC: 20 },
    },
    ['HMI'],
    10000,
  );
}

Siemens · Structure du manifesteSiemens · WebCC et interface avec RuntimeSiemens · Fichiers d’exemple et bibliothèque WebCC

04

Ajouter le ZIP au projet TIA Portal

  1. Ouvrir le dossier du projet

    Ouvrez le dossier contenant votre projet TIA Portal. Dans UserFiles, créez CustomControls s'il n'existe pas.

  2. Copier le paquet CWC

    Placez le fichier {GUID}.zip importable dans UserFiles\CustomControls. Gardez ce ZIP compressé. Ne copiez pas seulement index.html ni l'archive extérieure du téléchargement.

  3. Actualiser et placer le contrôle

    Ouvrez l’écran Unified. Dans Outils → Mes contrôles (Tools → My controls), actualisez puis faites glisser HMIx Pie Chart dans l’écran. Prévoyez de la place pour l’anneau et sa légende, par exemple 480 × 300 pixels.

  4. Vérifier son interface

    Sélectionnez le contrôle et ouvrez Propriétés → Propriétés → Interface. Repérez ValueA, ValueB et ValueC et affectez-leur les valeurs statiques 45, 35 et 20. Vous les relierez ensuite à des variables.

Capture Siemens montrant My controls, une jauge dans une vue Unified et ses propriétés Interface
Capture d’ingénierie Siemens : Mes contrôles → écran → Interface. Siemens montre GaugeMeter ; pour notre essai, sélectionnez HMIx Pie Chart et ses propriétés ValueA, ValueB et ValueC. Source · © Siemens AG · Licence et attribution

Siemens · Installation et utilisation d'un CWC

05

Tester avec trois variables internes, sans automate

  1. Créer trois variables internes

    Dans la table des variables HMI, ajoutez ProductionA, ProductionB et ProductionC, avec un type numérique tel que Real et sans connexion à un automate.

  2. Relier chaque entrée à sa variable

    Dans l’interface du CWC, choisissez Variable comme dynamisation : ValueA → ProductionA, ValueB → ProductionB et ValueC → ProductionC. Laissez Lecture seule activée ; les champs E/S modifieront les données.

  3. Ajouter trois champs E/S

    Placez un champ E/S en mode entrée/sortie pour chaque variable. Nommez-les A, B et C. Pour ce test, utilisez des quantités de 0 à 100 et définissez les limites de saisie si elles sont disponibles.

  4. Compiler et exécuter

    Définissez cette vue comme vue initiale, compilez la HMI et corrigez les erreurs signalées. Lancez la simulation HMI compatible ou chargez et démarrez le projet d'essai dans Unified PC Runtime. Ouvrez le client Runtime et connectez-vous avec l'utilisateur configuré dans le projet si nécessaire.

  5. Tester deux répartitions et l’état vide

    Saisissez 45, 35 et 20 en validant chaque entrée. Passez ensuite A à 90 : son segment grandit et le total atteint 145. Enfin, mettez les trois valeurs à zéro ; l’anneau doit être vide. Rouvrez l’écran pour vérifier la lecture des valeurs actuelles.

Capture Siemens d'une propriété CWC reliée à une variable avec Read-only activé
Liaison d’une propriété dans l’exemple Siemens. Remplacez GaugeValue / Motor_Speed par ValueA / ProductionA, puis répétez pour B et C en conservant Lecture seule. Source · © Siemens AG · Licence et attribution

Observez d'abord le résultat attendu

Modifiez A, B ou C et observez les segments. Les entrées sont des quantités ; le graphique calcule leurs pourcentages.

100Total
45 / 45%
35 / 35%
20 / 20%
Explication interactive de ce guide. Il ne s'agit pas d'une session WinCC Runtime.

Le test réussit lorsque…

45 / 35 / 20 donne un total de 100. Avec A = 90, le total atteint 145 et A représente environ 62 %. Trois zéros laissent l’anneau vide. Les valeurs actuelles doivent apparaître à la réouverture.

Siemens · Installation et utilisation d'un CWCSiemens · Exemple d'ingénierie et captures originales

06

Si quelque chose ne fonctionne pas

  • Le contrôle est absent : vérifiez UserFiles\CustomControls, la racine du ZIP, la validité du JSON et le nom GUID, puis actualisez My controls.
  • Le graphique apparaît sans évoluer : vérifiez ValueA, ValueB et ValueC, leurs variables et la connexion WebCC. Ouvrir le HTML localement vérifie son apparence, pas la connexion à Unified.
  • Il fonctionne sur PC mais pas sur Unified Comfort Panel : conservez les dépendances dans le paquet. Siemens documente des restrictions concernant les liens externes et les requêtes fetch ou XMLHttpRequest.
  • Une modification n'apparaît pas : recréez le ZIP, utilisez le mécanisme de mise à jour de TIA Portal, compilez et rechargez le projet d'essai. Gardez une copie de la version fonctionnelle.

Une fois ce test réussi, ajoutez une fonction à la fois. Validez le contrôle final sur l'appareil cible avant de le relier à un procédé réel.

Siemens · Restrictions CWC sur Unified Comfort Panel

Questions fréquentes

Faut-il connaître JavaScript ?

Vous pouvez importer et relier un CWC existant sans écrire de JavaScript. Pour modifier son comportement manuellement, des bases en HTML, CSS et JavaScript sont utiles. L'IA HMIx peut préparer les fichiers ; le résultat doit être vérifié dans Unified.

Puis-je le réutiliser dans un autre projet ?

Copiez le ZIP importable dans UserFiles\CustomControls de l'autre projet et configurez ses variables. Conservez ensemble le paquet et sa version. Ne supposez pas qu'il se comporte comme un type de faceplate versionné en bibliothèque.

Un aperçu correct suffit-il ?

Il confirme l'apparence, pas toute l'intégration Runtime. Testez aussi le démarrage, les changements de propriétés, l'appareil cible et les tailles de vue prévues.

Sources et lectures complémentaires