Perspective XY Chart Line Color: Resolving Property Mismatch

Karen Mitchell9 min read
HMI / SCADAOther ManufacturerTroubleshooting
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

Overview

The Perspective XY Chart component in Inductive Automation's Ignition platform provides a flexible way to display either time-series or XY data on a configured view. When a series is added without an explicit line color, the property editor displays a default gray swatch while the rendered chart uses a color chosen by the underlying charting library. This visual mismatch between the property UI and the rendered line causes confusion during commissioning and is the most common misinterpretation of the series.#.line.appearance.stroke.color property.

This reference documents the exact behavior, the underlying mechanism, the recommended configuration workflow, and the verification checks required to make the property editor reflect the actual rendered line color. All paths and property names are taken from the official Ignition 8.1 Perspective user manual. See the Perspective XY Chart documentation and the Inductive University XY Chart training video for the canonical reference set.

Scope: This article applies to Ignition 8.1.x Perspective. Property paths, palette behavior, and library dynamics are stable across the 8.1 release line. Earlier Perspective versions (8.0.x) use the same property tree but may render slightly different default palettes.

Problem Details

When an engineer adds an XY Chart to a Perspective view, configures a series via props.series, and inspects the line appearance sub-property, the following behavior is observed:

  • The series.<index>.line.appearance.stroke.color property displays a default gray swatch (or an empty value) in the property editor.
  • The rendered line on the chart uses a different color (blue, green, red, etc.) chosen automatically by the charting library.
  • Editing the color value in the property editor updates the rendered line correctly, but reverting to the default gray does not restore the auto-picked color — the line is rendered with no visible color or the next palette entry.

The mismatch is not a bug in the property binding pipeline; it is a deliberate delegation of color selection to the charting engine when the user has not specified a value. The property name (stroke.color) is intuitively correct, but the default state does not reflect what is actually being drawn on the canvas.

Root Cause

The Perspective XY Chart delegates initial color selection to the third-party charting library it embeds. The library is responsible for:

  1. Ensuring that no two series in the same chart use the same color.
  2. Ensuring adequate contrast between adjacent series for legibility.
  3. Avoiding colors that conflict with the active theme background or axis chrome.

To satisfy these constraints without writing back to the property tree on every render, the library reads the property as a hint, applies its own palette when the hint is empty or equal to the default placeholder, and uses the hint directly when the user provides a non-default value. The placeholder gray in the property editor is therefore not a color value; it is a visual indicator that the property is unset.

Why the property cannot be auto-updated: Writing the auto-picked color back to the property tree on every render would cause unnecessary binding evaluations, pollute the project diff history, and override any binding the user has configured for that property. The library therefore leaves the property empty by design.

Prerequisites

Before configuring line colors, confirm the following:

  • Ignition 8.1.x gateway with the Perspective module licensed and active.
  • A Perspective project loaded in the Designer with a view open for editing.
  • An XY Chart component dropped onto the view from the Component Palette (Chart category → XY).
  • At least one data source configured and bound to props.dataSources. Time-series sources should return tag history data; XY sources should return paired numeric arrays.
  • Read access to the Perspective XY Chart user manual page for the canonical property tree.

Step-by-Step Resolution

Follow the steps below to make the rendered line color match the property editor value and to lock the color so it does not change when additional series are added.

Step 1 — Add the XY Chart Component

  1. In the Designer, open the target view.
  2. From the Component Palette, select the Chart category.
  3. Drag the XY component onto the view canvas.
  4. Resize and position the chart as required for the layout.

Step 2 — Configure the Data Source

  1. Select the chart component on the canvas.
  2. In the Property Editor, expand props → dataSources.
  3. Add a new data source object. The minimum structure is:
    { "key": "series1", "type": "taghistorian", "tagPath": "[default]Path/To/Tag" }
  4. For XY data, set type to "xy" and provide paired x and y arrays or a query binding that returns them.

Step 3 — Add a Series Entry

  1. Expand props.series in the Property Editor.
  2. Add a new series object. The minimum structure is:
    { "name": "Series 1", "dataSource": "series1", "line": { "appearance": { "stroke": { "color": "", "width": 1 } } } }
  3. Note that the color field is intentionally left as an empty string. This is the value that triggers the auto-pick behavior.

Step 4 — Set an Explicit Color

  1. In the Property Editor, locate series.0.line.appearance.stroke.color.
  2. Click the color swatch and choose an explicit value (hex, RGB, or named CSS color). For example: "#1f77b4".
  3. Confirm in the Designer preview that the rendered line now matches the selected color.

Step 5 — Bind the Color (Optional)

To make the color dynamic, bind series.0.line.appearance.stroke.color to a tag, a parameter, or an expression. Recommended expression patterns:

if({[default]Line/OverrideColor} <> "",
   {[default]Line/OverrideColor},
   "#1f77b4")

This binding returns the operator override when present, otherwise falls back to the explicit color. Avoid binding to an empty string unless you intend to re-enable the auto-pick behavior.

Step 6 — Repeat for Additional Series

When adding series 1, 2, 3, etc., assign each a distinct explicit color to prevent the library from re-picking and to make the property editor and the canvas agree. A safe starting palette is shown in the table below.

Recommended Starting Palette

Series Index Hex Common Name Contrast on Light Theme Contrast on Dark Theme
0 #1f77b4 Tableau Blue Good Good
1 #ff7f0e Tableau Orange Good Good
2 #2ca02c Tableau Green Good Good
3 #d62728 Tableau Red Good Good
4 #9467bd Tableau Purple Good Good
5 #8c564b Tableau Brown Good Good
6 #e377c2 Tableau Pink Good Good
7 #7f7f7f Tableau Gray Marginal Good

Property Reference

The full property tree for the line appearance is:

series.<index>.line.appearance.stroke.color   (string, CSS color)
series.<index>.line.appearance.stroke.width   (number, pixels)
series.<index>.line.appearance.stroke.dash    (array, pixel pattern)
series.<index>.line.appearance.shape          (object, marker config)
series.<index>.line.appearance.fill           (object, area fill config)

Only the color field is delegated to the library when empty. width, dash, shape, and fill always reflect their explicit values because the library does not auto-pick them.

Data Source Configuration

The XY Chart supports three data source shapes:

  1. Time-series (tag historian): The library maps the timestamp domain to the X axis and the value to the Y axis. type must be "taghistorian".
  2. XY pairs (database or expression): The library maps explicit X and Y arrays to the axes. type must be "xy" and the payload must contain x and y numeric arrays of equal length.
  3. Custom (function-bound JSON): The component accepts any payload that the library can interpret. type is set to "custom" and a binding supplies the data.

The data source type does not affect color behavior. The library applies the same auto-pick logic to all three shapes.

Charting Library Behavior

The embedded charting library maintains an internal palette index that increments each time a new series is added without an explicit color. The index wraps at the palette length (typically eight colors) and resets when the chart is re-rendered from a new data set. The auto-picked color is not deterministic across re-renders unless the series order is stable. To guarantee a specific color for a specific series, always set color to an explicit value.

Determinism caveat: If two series both leave color empty, the library will assign them different colors on the first render, but the assignment depends on the order in which the series are processed. Re-ordering the series in props.series will swap the auto-picked colors. This is the most common cause of "the line color changed after I added a new series" reports.

Theme Considerations

The auto-picked palette is tuned for the default light theme. On the dark theme, the lower-order palette entries (especially gray) may have insufficient contrast against the canvas. Set explicit colors when the project is deployed against a dark theme to avoid legibility regressions.

To apply a project-wide palette, bind each series.<i>.line.appearance.stroke.color to a property of a custom property sheet (for example, params.chartColors) and let the view pass a single array down to all charts. This keeps the palette in one location and prevents drift between views.

Verification

After configuring explicit colors, validate the result with the following checks:

  1. Open the view in the Designer and confirm the rendered line color matches the swatch in the Property Editor.
  2. Open a web browser session pointed at the same project and confirm the same color renders. The library applies the same palette to both Designer and client.
  3. Add a second series with an empty color and confirm the first series retains its explicit color while the second receives an auto-picked color from the remaining palette entries.
  4. Bind a tag to color and change the tag value at runtime. The line should update within one render cycle (typically under 200 ms on a local client).

Troubleshooting Matrix

Symptom Likely Cause Remediation
Property shows gray, line shows a different color Auto-pick delegation Set an explicit color value
Line color changes after adding a new series Auto-pick re-ordering Set explicit colors on all series
Line is invisible against the canvas Auto-picked gray on dark theme Set an explicit high-contrast color
Color binding does not update at runtime Binding evaluates to empty string Ensure the binding always returns a non-empty string; use a fallback expression
Designer preview differs from client Stale browser cache Hard-reload the client (Ctrl+F5)
Color flicker on initial render Library re-palette after data arrives Pre-assign explicit colors before binding data
Color not applied when series added dynamically New series inherited empty color Bind new series entries to a color from the project palette

Best Practices

  • Always set explicit colors for production screens. Reserve auto-pick for prototypes and ad-hoc debugging.
  • Centralize the palette in a project parameter or a UDT instance to keep colors consistent across views.
  • Document the palette assignment in a property sheet comment so that future engineers know which color belongs to which series.
  • Avoid binding color to an expression that can return an empty string unless the auto-pick behavior is desired.
  • For accessibility, ensure the chosen palette passes WCAG 2.1 AA contrast (3:1 for non-text graphical objects) against both light and dark themes.

FAQ

Why does the line color property show gray in the Property Editor but a different color on the chart?

The gray swatch is a placeholder indicating the property is unset. When the value is empty, the embedded charting library auto-picks a color from its internal palette to satisfy contrast and uniqueness constraints. Set an explicit value in series.<index>.line.appearance.stroke.color to make the property editor and the rendered line agree.

How do I make the line color dynamic at runtime?

Bind series.<index>.line.appearance.stroke.color to a tag, parameter, or expression. Use a fallback expression such as if({tag} <> "", {tag}, "#1f77b4") to guarantee a non-empty value and prevent the library from re-entering auto-pick mode.

Can I lock the palette so all charts in the project use the same color order?

Yes. Define a project parameter (for example, params.chartPalette) as a string array and bind each series.<i>.line.appearance.stroke.color to {params.chartPalette}[i]. This keeps the assignment deterministic across all views and survives chart re-ordering.

Does the data source type affect color behavior?

No. The auto-pick logic is independent of the data source shape (tag historian, XY pairs, or custom). Color behavior is controlled solely by the value of series.<index>.line.appearance.stroke.color.

Why does the line color change when I add a new series?

When multiple series leave color empty, the library assigns palette entries in the order the series are processed. Adding a new series can shift the assignment of existing series if the internal palette index wraps. Set explicit colors on all series to prevent this shift.

Back to blog