Configuring Dynamic Bar Graph Colors in WinCC Unified V20

David Krause16 min read
SiemensTutorial / How-toWinCC
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Context: Why a Single Bar Object Cannot Be Recolored at Runtime on Basic Panels

The original engineering requirement is straightforward: drive a bar graph on an HMI with a process value and visually classify that value by switching the bar fill color according to severity (for example, green = nominal, yellow = warning, red = alarm). On legacy WinCC Flexible SP projects and on current WinCC Basic (TIA Portal) runtime, this requirement collides with a hard architectural limit: the runtime scripting engine that would be required to call Bar.FillColor = ... is not loaded, not licensed, or not exposed on the Basic Panel class.

The TP1500 Basic PN referenced in the original query is a 15-inch Basic Panel that runs WinCC Basic (or, on older SP projects, WinCC Flexible 2008 SP5). Neither runtime supports VBScript, nor any other active scripting language. The runtime supports dynamic dialogs, tag-driven property animations, and visibility animations, but it does not expose an event-driven API that lets the engineer set a fill color from a value change. The same is true for all TPxxx Basic, KTPxxx Basic, and the lowest-cost Comfort variants that ship with the Basic firmware image.

Hard limit: If your target device is a TP1500 Basic PN, KTP700 Basic, KTP1000 Basic, or any other panel built on the Basic firmware image, you cannot recolor a single Bar object at runtime through user code. You must either (a) upgrade to a Unified Comfort Panel or a Unified PC Runtime V20 and use the JavaScript path documented below, or (b) use the stacked-Bar visibility workaround documented in Solution Path B.

Platform Capability Matrix: Script and Color Property Support per HMI Class

HMI Class Example Device Runtime VBScript JavaScript Bar FillColor Dynamization
Basic Panels TP1500 Basic PN, KTP700 Basic, KTP1000 Basic WinCC Basic / WinCC Flexible 2008 No No Not directly; use stacked-bar visibility trick
Comfort Panels TP1500 Comfort, TP1900 Comfort, TP2200 Comfort WinCC Comfort / WinCC Advanced (TIA) Yes (limited) No Yes, via VBScript (Bar.FillColor = RGB(...))
Unified Comfort Panels MTP1500 Unified, MTP1900 Unified, MTP2200 Unified WinCC Unified V17 / V18 / V19 / V20 No Yes Yes, native
Unified PC Runtime WinCC Unified RT V20 (PC-based) WinCC Unified V20 No Yes Yes, native
WinCC Professional (SCADA) WinCC RT Professional V20 WinCC Professional V20 Yes (C / VBS) No Yes, via VBS or C script

This matrix is the decision tree. If the panel is Basic, stop reading at Solution Path B. If the panel is Unified Comfort or a Unified PC RT, continue to Solution Path A. If the panel is Comfort and you have an existing WinCC Comfort TIA project, see the legacy VBScript pattern in Solution Path D.

Solution Path A — WinCC Unified V20: Native Color Dynamization with JavaScript

WinCC Unified, available since TIA Portal V15.1 and significantly expanded through V17, V18, V19, and V20, exposes every visual property of every screen object to the runtime JavaScript API. The Bar (RT Unified) object inherits the full property set of the Unified UI library, which means FillColor, BackColor, BorderColor, Value, Minimum, Maximum, and every other visual and data property can be read or written from a user-defined JavaScript function. The official configuration reference is the Bar (RT Unified) - WinCC Unified configuration manual (TIA Portal V20), and the runtime operator-side reference is the Bar (RT Unified) - Operating instructions (WinCC Unified V20).

Prerequisites

  • TIA Portal V20 (V18 or V19 with the latest HSPs is also acceptable; the API is stable from V17 onward).
  • WinCC Unified Runtime V20 installed on a Unified Comfort Panel (MTP1500 / MTP1900 / MTP2200) or running as PC RT V20.
  • An active HMI connection between the PLC (S7-1500, S7-1200, ET 200SP, or third-party controller via OPC UA) and the Unified device.
  • An HMI tag of data type Int or Word that carries the severity code. Recommended encoding: 0 = OK / nominal, 1 = warning, 2 = alarm, 3 = critical.
  • An HMI tag for the process value itself (the bar height) of data type Int or Real matching the configured Minimum / Maximum range of the bar.

Step 1 — Insert the Bar (RT Unified) Object and Bind the Process Value

  1. In the TIA Portal project tree, expand Unified device → Screens and open the target screen.
  2. From the Toolbox under Elements, drag Bar onto the screen. This is the Bar (RT Unified) object, not the legacy Bar from WinCC Comfort.
  3. In the Properties → Properties pane, set Process value to the HMI tag that carries the bar height (for example, HMI_Tag_TankLevel).
  4. Set Minimum = 0 and Maximum = 100 (or your engineering range). Set Bar direction to Bottom to top for a tank-style fill.
  5. Set the static FillColor to a neutral grey (for example, #808080) as a fallback. The script will overwrite this every time the severity tag changes.
  6. Under Properties → Appearance, set the bar width to match the visible part of the screen. Note the exact Name of the object (default: Bar_1); the script must reference it by this name.

Step 2 — Configure the Severity Tag and Alarm Source

The severity tag is a discrete value that drives both the bar color and, typically, the alarm state. It can come from three sources:

  1. PLC-driven: the S7-1500 program writes the severity code to a PLC tag that is exposed to the HMI. Most common pattern.
  2. HMI-calculated: a Unified script evaluates the process value and writes the severity tag. Use this when the severity threshold is purely a visualization concern.
  3. Alarm-driven: the WinCC Unified alarm system sets the severity as part of the alarm state. Bind the bar color directly to the alarm state attribute.

For a typical tank level, the engineering thresholds are:

Severity Code Meaning Typical Bar Color (HTML hex) Trigger Example (TankLevel %)
0 Nominal / OK #2ECC71 (green) 0 – 79 %
1 Warning #F1C40F (amber) 80 – 94 %
2 Alarm #E74C3C (red) 95 – 100 %
3 Critical / Fault #8E44AD (purple) Sensor error, comms loss

Step 3 — Create the Color Dynamization JavaScript

  1. In the project tree, navigate to Unified device → Scripts.
  2. Right-click Scripts → Add new script. Name it BarColor_Severity.js.
  3. Open the script and paste the following pattern. The example reads the severity tag, then writes FillColor on the bar object:
// BarColor_Severity.js - WinCC Unified V20 // Trigger: Tag change on HMI_Tag_Severity (Int) // Target : Bar object named 'Bar_1' on the active screen. export function SetBarColor_BySeverity(item) { // Read the severity code (0=OK, 1=Warning, 2=Alarm, 3=Critical) let severity = HMIRuntime.Tags.Read('HMI_Tag_Severity').Value; // Locate the bar object by name. Screen.FindItem returns the live object. let bar = Screen.FindItem('Bar_1'); if (bar === null) { HMIRuntime.Trace('SetBarColor_BySeverity: Bar_1 not found'); return; } // Map severity to FillColor. Hex literal with 0xAARRGGBB layout. switch (severity) { case 0: bar.FillColor = 0xFF2ECC71; // green - nominal break; case 1: bar.FillColor = 0xFFF1C40F; // amber - warning break; case 2: bar.FillColor = 0xFFE74C3C; // red - alarm break; case 3: bar.FillColor = 0xFF8E44AD; // purple - critical / fault break; default: bar.FillColor = 0xFF808080; // grey - unknown / fallback } // Optional: also drive the border so the operator can spot transitions // even on monochrome HMIs. bar.BorderColor = 0xFF000000; // black outline on every state }

The same script can read the bar value itself and classify severity in-engine if the PLC does not provide a discrete severity code:

// BarColor_AutoClassify.js - classify the value of the bar itself. export function ClassifyAndColor(item) { let value = HMIRuntime.Tags.Read('HMI_Tag_TankLevel').Value; let bar = Screen.FindItem('Bar_1'); if (value >= 95) bar.FillColor = 0xFFE74C3C; // red else if (value >= 80) bar.FillColor = 0xFFF1C40F; // amber else bar.FillColor = 0xFF2ECC71; // green }

Step 4 — Bind the Script Trigger

The script must fire when the severity tag changes. The Unified V20 trigger model offers three options:

  1. Tag change trigger (recommended): the runtime calls the function every time the tag value updates. Bind under Bar_1 → Events → Property → Value, or attach the script globally to Tags → HMI_Tag_Severity → Events → Value changed.
  2. Cyclic trigger: configure the script as a scheduled task with a 250 ms cycle. Use this only when the PLC produces transient severity codes that may be missed by event triggers.
  3. Screen-load trigger: call the function from Screen → Events → Loaded so the bar is always correctly colored when the screen opens, regardless of the trigger cadence.

For belt-and-braces, attach the function to all three triggers. The runtime de-duplicates rapid back-to-back calls.

Step 5 — Verification

  1. Compile the project (Project → Compile → Software (rebuild all)). Address any warnings in the Messages pane.
  2. Download to the Unified Comfort Panel or start Unified PC RT V20 simulation.
  3. Force the severity tag to 0 from the PLC or from the HMI tag table. The bar must turn green within one scan cycle (typically < 250 ms).
  4. Force the severity tag to 2. The bar must turn red within the same cycle.
  5. Cycle the screen. The bar color must persist or be re-evaluated correctly when the screen is reloaded.

Solution Path B — Stacked-Bar Visibility Trick for WinCC Basic (No Scripting)

Because Basic Panels cannot host user scripts, the only practical technique that does not require upgrading the hardware is to stack multiple Bar objects with identical geometry and use a visibility animation to switch between them. The active bar changes with the severity tag; the others are hidden.

  1. Insert four Bar objects (one per severity level) on top of each other, all named uniquely (for example Bar_OK, Bar_Warning, Bar_Alarm, Bar_Critical).
  2. For every bar, bind the Process value to the same source tag and apply identical Minimum / Maximum / Direction / Geometry. Misalignment is the most common visual bug in this pattern.
  3. Set each bar's static FillColor to the desired severity color (green / amber / red / purple).
  4. On each bar, configure a visibility animation on the Display property. Use a range or bit-pattern condition tied to the severity tag:
    • Bar_OK visible only when HMI_Tag_Severity == 0
    • Bar_Warning visible only when HMI_Tag_Severity == 1
    • Bar_Alarm visible only when HMI_Tag_Severity == 2
    • Bar_Critical visible only when HMI_Tag_Severity == 3
  5. Place the four bars at the same X, Y, Width, Height in z-order from bottom to top so the visible one always wins the paint order.
Performance: WinCC Basic evaluates the visibility animation on every tag change of the source tag. With four stacked bars and a tag updated every 100 ms, the panel performs four range comparisons per update. On a TP1500 Basic PN this is well within the recommended load envelope, but if you stack more than eight bars per screen, expect a measurable cycle-time penalty.

A second variant uses one bar and a separate background rectangle or graphic I/O field. The graphic I/O field is colored via an Appearance animation and sized to match the bar, then placed behind the bar. This is essentially the same trick but reduces the number of bar evaluations from N to 1.

Solution Path C — Trend View Bar / Line Color (Adjacent Limitation)

The same architectural limitation applies to trend views. The original Siemens FAQ entry — historically published as Entry ID 24249449 on the Siemens Industry Online Support — confirms that the line and bar color inside a Trend View object is not exposed through the VBScript property interface in WinCC Comfort / Advanced, and remains inaccessible in older WinCC Flexible builds. In WinCC Unified V20, the situation improves but only partially: trend curves can be configured with multiple trend areas where each area can hold a different color, but you cannot recolor a single trend area from a script without recreating the area at runtime. For dynamic trend-color requirements, prefer WinCC Unified's Online Trend Control with multiple predefined areas, or use the Function Trend Control with discrete time-stamped trend segments.

Solution Path D — Legacy Comfort Panels with VBScript

For projects already on a Comfort Panel (TP1500 Comfort / TP1900 Comfort / TP2200 Comfort), the same requirement is solved with VBScript. The object model differs from Unified: you reference the screen via HmiRuntime.Screens("Screen_1") and the bar via HmiRuntime.Screens("Screen_1").ScreenItems("Bar_1"). The property name FillColor is identical, and it accepts a BGR long integer (not an HTML hex). Color conversion helper:

' WinCC Comfort - SetBarColor.vbs Sub SetBarColor() Dim severity, bar, col severity = SmartTags("HMI_Tag_Severity") Set bar = HmiRuntime.Screens("Screen_1").ScreenItems("Bar_1") Select Case severity Case 0: col = RGB(46, 204, 113) ' green Case 1: col = RGB(241, 196, 15) ' amber Case 2: col = RGB(231, 76, 60) ' red Case 3: col = RGB(142, 68, 173) ' purple Case Else: col = RGB(128, 128, 128) End Select bar.FillColor = col End Sub

Bind the SetBarColor sub to a tag-change event on HMI_Tag_Severity via the Events tab of the tag in the HMI tags editor.

Verification Checklist

# Check Expected Result Pass/Fail
1 Compile project with no warnings 0 errors, 0 warnings in the Messages pane  
2 Force severity = 0 from the PLC Bar fill is green within one scan cycle  
3 Force severity = 1 from the PLC Bar fill is amber  
4 Force severity = 2 from the PLC Bar fill is red  
5 Force severity = 3 from the PLC Bar fill is purple  
6 Set severity to an undefined value (for example, 7) Bar fill is grey (fallback)  
7 Reload the screen during runtime Bar color reflects the current severity immediately (no flash to default grey)  
8 Disconnect PLC connection Bar retains last color or shows fallback per design (documented choice)  
9 Cycle power on the panel Bar re-evaluates after the connection is re-established  
10 Audit with WinCC Unified audit / trace log Trace shows SetBarColor_BySeverity: Bar_1 not found only when the bar name is wrong  

Troubleshooting Matrix

Symptom Likely Root Cause Diagnostic Step Fix
Bar color does not change at all on TP1500 Basic PN Basic Panel runtime has no script engine Confirm the device under Device configuration → General shows WinCC Basic Apply Solution Path B (stacked bars) or migrate to a Unified Comfort Panel
Script runs in simulation but not on the panel Trigger not bound to runtime tag change, only to compile-time event Open Scripts → Triggers on the panel and confirm Tag change is enabled Re-add the trigger and redownload
Bar flickers between colors Cyclic trigger running too fast, OR PLC toggling the severity tag on every scan Watch the severity tag in the HMI tag table with trace Latch the severity tag in the PLC or use edge detection in the script
Color is correct on screen load but stale after navigation Script fires on tag change only, no screen-load handler Check the screen Loaded event Add a screen-load call to SetBarColor_BySeverity
Unified Trace logs Bar_1 not found Object name mismatch (case sensitive) OR object is on a different screen Cross-check the object name in the screen Properties pane Use Screen.FindItem('Bar_1') with the exact case-sensitive name
Trend view line color will not change from script Property not exposed on the Trend object model Inspect the Trend object properties in the type information Use multiple trend areas with different static colors instead of one dynamic area
JavaScript throws TypeError: Cannot read property 'FillColor' of null Screen.FindItem returned null because the bar is on a faceplate or pop-up Inspect the screen hierarchy at runtime Use the correct Screen reference for the faceplate instance, not the base screen
VBScript on Comfort Panel fails with Object required Screen name or item name spelled incorrectly Use HmiRuntime.Screens("...") with the configured screen name Correct the string and verify the project compiles

Color Coding Conventions and Accessibility Notes

Color alone is not an accessibility-safe encoding. The NAMUR NA 102 / NE 131 recommendation for process HMI explicitly advises against using color as the sole indicator of state; always pair the bar fill with one of:

  • A state-specific label or icon overlay (e.g. a triangle warning glyph for alarm).
  • A border or pattern change (e.g. dashed border on the alarm state).
  • A numeric or text readout of the severity code on the same screen.

Within the bar object, BorderColor, BorderWidth, and the surrounding Text field properties are all dynamic in the same way as FillColor. Bind them in the same script for a multi-modal indicator.

Performance and Update Timing

The JavaScript event trigger in WinCC Unified V20 fires within one tag-acquisition cycle of the source tag. With the default 1 s acquisition cycle the worst-case latency between PLC value change and bar color update is approximately 1 s. For sub-second response on critical alarms, shorten the acquisition cycle of the severity tag to 100 ms or 250 ms under Tags → HMI_Tag_Severity → Properties → Acquisition. The bar fill color update itself is GPU-accelerated on Unified Comfort Panels and is not the bottleneck; the bottleneck is the tag acquisition cycle.

Common Errors When Migrating from WinCC Flexible to WinCC Unified

Engineers who carry a WinCC Flexible project forward to WinCC Unified often assume the VBScript property names map 1:1. They do not. The Unified JavaScript model is more strict in three ways:

  1. String identifiers for screen items are case sensitive. Screen.FindItem('bar_1') returns null if the configured name is Bar_1.
  2. Color values are 32-bit ARGB longs (0xAARRGGBB), not 24-bit BGR as in Comfort VBScript.
  3. Tag reads return a tag object; you must explicitly read .Value, .Quality, and .Timestamp on the returned object.

These three differences account for the majority of migration bugs reported on the Siemens Industry Online Support portal.

Field-Proven Checklist Before Commissioning

  1. Verify that the TIA Portal version installed matches the panel firmware image (V20 ↔ V20).
  2. Compile with the Strict mode option enabled; address every warning.
  3. Run a 24-hour soak test with the severity tag forced through every state every 30 minutes.
  4. Capture a trace of the script under realistic PLC traffic to confirm the script does not block the UI thread.
  5. Verify the bar color updates correctly when the connection is intentionally broken and restored.

FAQ

Can a TP1500 Basic PN change the color of a bar graph at runtime?

No. The TP1500 Basic PN uses WinCC Basic or WinCC Flexible 2008, neither of which supports runtime scripting. Use the stacked-Bar visibility trick (Solution Path B) on this panel class, or migrate to a Unified Comfort Panel such as the MTP1500 Unified or to Unified PC Runtime V20.

Which WinCC Unified V20 property controls the bar fill color?

The FillColor property of the Bar (RT Unified) object. It accepts a 32-bit ARGB long integer in the form 0xAARRGGBB; for example, 0xFFE74C3C is opaque red. See the Bar (RT Unified) configuration manual.

How do I trigger the color script in WinCC Unified V20?

Bind the JavaScript function to a tag-change event on the severity tag under Tags → HMI_Tag_Severity → Events → Value changed. For belt-and-braces coverage, also call the function from Screen → Events → Loaded so the bar is correctly colored on every screen navigation.

Can I change a trend view line or bar color dynamically from a script?

Partially. In WinCC Comfort / Advanced and older WinCC Flexible builds, line and bar colors inside a Trend View object are not exposed through the VBScript property interface (Siemens Entry ID 24249449 documents this limit). In WinCC Unified V20 you can configure multiple trend areas with different static colors and route data to the appropriate area; recoloring a single area from script is not supported.

How long does the bar take to update after the PLC changes the severity tag?

The update latency is dominated by the tag acquisition cycle configured for HMI_Tag_Severity. With the default 1 s cycle the worst-case latency is approximately 1 s. Shorten the cycle to 250 ms or 100 ms in Tags → HMI_Tag_Severity → Properties → Acquisition for sub-second response on critical alarms; the bar repaint itself adds under 16 ms.

Back to blog