Guías prácticas HMIx
Crea un pie chart con un Custom Web Control en WinCC Unified
Un gráfico circular permite comparar la producción de varias líneas de un vistazo. Vamos a crear uno con HTML, CSS y JavaScript, añadirlo a TIA Portal y probarlo con tres variables internas.

Entorno de la guía: TIA Portal / WinCC Unified V21.1. Comprueba la importación y la ejecución del ejemplo en tu dispositivo de destino.
¿Qué es un Custom Web Control?
Un Custom Web Control, o CWC, es un pequeño componente web que se coloca dentro de una pantalla de WinCC Unified. HTML define el contenido, CSS el aspecto y JavaScript hace que reaccione. Sirve cuando los objetos HMI estándar no ofrecen la presentación o la interacción que necesitas.
Piensa en un panel de producción, una tabla o un gráfico circular. El control expone propiedades: entradas con nombre, como ValueA. En TIA Portal conectas cada propiedad a una variable HMI; el CWC recibe los valores y actualiza el gráfico. Por sí solo no se conecta directamente al PLC.
- Elige un CWC para interacciones propias, varios valores coordinados o una composición especial.
- Para un símbolo que cambia de color, posición o nivel de llenado, un SVG dinámico suele ser más sencillo.
- Para reutilizar un conjunto de objetos HMI estándar, considera un faceplate.
En HMIx puedes descargar cientos de recursos HMI gratuitos. Empieza con un control del catálogo o describe tu idea al generador de IA de HMIx para crear un recurso que puedas adaptar a tu proyecto.

Antes de empezar
Utiliza un proyecto de prueba con un dispositivo WinCC Unified y una pantalla vacía. Necesitas TIA Portal con WinCC Unified Engineering y los componentes compatibles de Runtime o simulación instalados. Un proyecto Comfort convencional y uno Unified son destinos distintos.
- Para la primera prueba, utiliza Unified PC Runtime o la simulación admitida por tu dispositivo Unified.
- Si quieres modificar el ejemplo, ten a mano un editor de texto y una herramienta ZIP. Visual Studio Code es cómodo, pero no obligatorio.
- No necesitas un PLC: tres variables HMI internas y tres campos E/S proporcionarán los valores de prueba.
La vista previa del navegador comprueba el dibujo. La conexión WebCC y el enlace a la variable se verifican dentro de Unified.
Construye un pie chart de tres valores
Nuestro pie chart tiene forma de anillo: deja el total en el centro y muestra cada serie en una leyenda. Sus entradas son ValueA, ValueB y ValueC, con valores iniciales 45, 35 y 20. Son cantidades; no tienen que sumar 100. El control calcula qué parte del total ocupa cada una.
Prepara los archivos
Crea manifest.json en la raíz y dos carpetas: assets y control. Dentro de control, crea index.html y code.js. Obtén webcc.min.js de Siemens desde el ejemplo oficial enlazado más abajo y colócalo también en control. Cada archivo tiene una función; no necesitas ningún framework web.
Define las tres entradas
En manifest.json, declara ValueA, ValueB y ValueC como números, con valores iniciales 45, 35 y 20. El manifiesto también indica el nombre HMIx Pie Chart, su identidad y el archivo de inicio.
Dibuja el gráfico y la leyenda
En control/index.html, coloca un anillo de tres segmentos, el total y la leyenda A, B y C. En code.js, calcula cada proporción dividiendo el valor entre la suma. Si todos son cero, muestra un anillo vacío. El ejemplo utiliza SVG dentro del HTML y no necesita una librería de gráficos.
Conéctalo con Unified
Carga webcc.min.js de Siemens sin modificarlo. Inicia WebCC con las mismas tres propiedades, lee sus valores al conectar y vuelve a dibujar cuando onPropertyChanged comunique un cambio. Así se ve el dato actual al abrir la pantalla.
Empaqueta el contenido
Coloca manifest.json, assets y control en la raíz del ZIP, sin una carpeta adicional que los envuelva. Nombra el ZIP con el GUID del control entre llaves. Si editas nuestros archivos, reconstruye el ZIP con esa estructura; cambiar solo su nombre no crea una identidad de control nueva.
Los nombres ValueA, ValueB y ValueC deben coincidir en el manifiesto y en JavaScript. La descarga de esta guía es un ejemplo propio de tres entradas; el Pie Chart del catálogo utiliza Apache ECharts y cinco elementos con Value y Title.
ZIP completo con tres entradas numéricas y WebCC. Código y estructura comprobados; la importación y la conexión deben verificarse en WinCC Unified V21.1.
Ver el código del ejemplo
Opcional: la descarga contiene el ejemplo completo. No necesitas escribir este código para seguir la prueba.
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 · Estructura del manifiestoSiemens · WebCC e interfaz con RuntimeSiemens · Archivos de ejemplo y biblioteca WebCC
Añade el ZIP a tu proyecto de TIA Portal
Localiza la carpeta del proyecto
Abre la carpeta que contiene tu proyecto de TIA Portal. Dentro de UserFiles, crea CustomControls si no existe.
Copia el paquete CWC
Coloca el {GUID}.zip importable en UserFiles\CustomControls. Este ZIP debe permanecer comprimido. No copies únicamente index.html ni el paquete exterior de descarga.
Actualiza e inserta el control
Abre la pantalla Unified. En Herramientas → Controles propios (Tools → My controls), pulsa Actualizar y arrastra HMIx Pie Chart a la pantalla. Dale espacio al anillo y a su leyenda, por ejemplo 480 × 300 píxeles.
Comprueba su interfaz
Selecciona el control y abre Propiedades → Propiedades → Interfaz. Busca ValueA, ValueB y ValueC y asigna valores estáticos 45, 35 y 20. El siguiente paso los conectará a variables.

Pruébalo con tres variables internas, sin PLC
Crea tres variables internas
En la tabla de variables HMI, añade ProductionA, ProductionB y ProductionC, de un tipo numérico como Real y sin conexión a PLC.
Enlaza cada entrada con su variable
En la interfaz del CWC, elige Variable como dinamización: ValueA → ProductionA, ValueB → ProductionB y ValueC → ProductionC. Mantén Solo lectura activado; los campos E/S cambiarán los datos.
Añade tres campos E/S
Coloca un campo E/S en modo entrada/salida para cada variable. Identifícalos como A, B y C. Para esta prueba utiliza cantidades entre 0 y 100 y configura los límites de entrada cuando estén disponibles.
Compila y ejecuta
Establece esta pantalla como inicial, compila la HMI y corrige los errores indicados. Inicia la simulación HMI compatible, o carga y arranca el proyecto de prueba en Unified PC Runtime. Abre el cliente Runtime e inicia sesión con el usuario configurado en el proyecto si se solicita.
Prueba dos repartos y el estado vacío
Introduce 45, 35 y 20 y confirma cada entrada. Después cambia A a 90: su segmento crecerá y el total será 145. Por último, pon las tres entradas a cero; debe quedar un anillo vacío. Vuelve a abrir la pantalla para comprobar que conserva la lectura actual.

Primero, observa qué debería ocurrir
Cambia A, B o C y observa cómo se reparten los segmentos. Los valores son cantidades: el gráfico calcula sus porcentajes.
La prueba funciona cuando…
45 / 35 / 20 muestra un total de 100. Con A = 90, el total pasa a 145 y A ocupa aproximadamente el 62 %. Tres ceros dejan el anillo vacío. Al reabrir la pantalla deben aparecer los valores actuales.
Siemens · Instalación y uso de CWCSiemens · Ejemplo de ingeniería y capturas originales
Si algo no funciona
- No aparece el control: revisa UserFiles\CustomControls, la raíz del ZIP, la sintaxis JSON del manifiesto y el nombre GUID; después actualiza Controles propios.
- El gráfico aparece pero no cambia: revisa los nombres ValueA, ValueB y ValueC, sus variables y la conexión WebCC. Abrir el HTML localmente comprueba el aspecto, no la conexión con Unified.
- Funciona en PC pero falla en un Unified Comfort Panel: incluye las dependencias dentro del paquete. Siemens documenta restricciones para enlaces externos y para obtener datos con fetch o XMLHttpRequest.
- No ves una modificación: reconstruye el ZIP, utiliza el procedimiento de actualización de controles de TIA Portal, compila y vuelve a cargar el proyecto de prueba. Conserva una copia de la versión que funcionaba.
Cuando esta pequeña prueba funcione, añade una mejora cada vez. Valida el control final en el dispositivo de destino antes de conectarlo a un proceso real.
Preguntas frecuentes
¿Necesito saber JavaScript?
Puedes importar y enlazar un CWC existente sin escribir JavaScript. Para modificar su comportamiento a mano, ayudan unas nociones de HTML, CSS y JavaScript. La IA de HMIx puede preparar los archivos; el resultado se revisa y se prueba en Unified.
¿Puedo reutilizarlo en otro proyecto?
Copia el ZIP importable a UserFiles\CustomControls del otro proyecto y configura sus variables. Conserva el paquete y su versión juntos; no des por hecho que funciona como un tipo de faceplate versionado en biblioteca.
¿Una vista previa correcta significa que está listo?
Confirma el aspecto, pero no toda la integración con Runtime. Comprueba también el arranque, los cambios de propiedades, el dispositivo de destino y los tamaños de pantalla previstos.
Fuentes y lecturas complementarias
- Siemens · Programación de Custom Web Controls
- Siemens · Estructura del manifiesto
- Siemens · WebCC e interfaz con Runtime
- Siemens · Archivos de ejemplo y biblioteca WebCC
- Siemens · Instalación y uso de CWC
- Siemens · Ejemplo de ingeniería y capturas originales
- Siemens · Restricciones de CWC en Unified Comfort Panels