The request looks simple: a trend on a Perspective view and one red vertical line at a specific timestamp, such as a batch start, an alarm, or a setpoint change. You open the Time Series Chart property tree and find nothing to set. The usual first workaround creates a new problem. You put the marker on a second Y axis, the line draws, and now a useless 0–100 axis sits on the right side of the trend.
Work through the checks below in order. Each one tells you which branch to take next.
Check 1: Confirm the Time Series Chart Has No Marker Property
Start here. Open the Time Series Chart in the Designer and expand its full property tree for your Ignition version. Look for anything named marker, annotation, guide, or reference line on the time axis.
- You find one: use it and stop here.
- You find nothing: the component does not draw a vertical marker natively. Stop hunting for a hidden setting and go to Check 2.
You have three real ways to build the marker:
- Data-driven: add a series whose points form a vertical segment.
- Overlay: lay a drawn line on top of the chart.
- Third-party: use a chart component that has an annotation layer.
Check 2: Decide Whether the Marker Must Be Interactive
Ask what operators will do with the line.
- They need to click it, select it, or drag it to pick a time: built-in components will fight you. Go to the third-party branch below.
- They only need to see it at a computed or tag-driven timestamp: stay with built-in components and go to Check 3.
Third-party branch. Musson Industrial publishes a Chart.js component for Perspective that bundles chartjs-plugin-annotation. The plugin supports these annotation types:
- line
- point
- box
- several other types
Most annotation values are scriptable options. That means the client can compute the position from the chart data, for example the average, minimum, or maximum of a series. The annotations are interactive. You can allow selection, detect clicks, and allow dragging.
This is the cleanest route if module installation is allowed on your gateway. If your site allows built-in components only, skip it.
Check 3: Built-In Only? Choose Data Series or Overlay
Two built-in methods work. Pick one based on how the chart behaves at runtime.
| Condition | Use | Why |
|---|---|---|
| Time range changes, chart autoscales, or view resizes | XY Chart with a marker series | The line lives in data coordinates, so it moves with the axis automatically. |
| Fixed time window, fixed view size, and you must keep the existing Time Series Chart | Coordinate Container overlay | No chart config changes, but you calculate the pixel position yourself. |
| Marker already on a second Y axis of the Time Series Chart, and that axis will not hide | Move to the XY Chart | The XY Chart exposes a per-axis visible property on every yAxes entry. |
How the data-driven marker works. A line series connects its points in order. Give it exactly two points with the same timestamp and different Y values, for example y = 0 and y = 100. The segment between those two points is vertical.
The line only spans the full plot height if those two Y values match the top and bottom of the axis the series uses. That axis therefore needs a fixed, strict range.
If you already built this on the Time Series Chart: check that component's axis configuration for a visibility property. If it has one, set it to false on the marker axis and go straight to verification. If it does not, rebuild on the XY Chart (ia.chart.xy). That is a built-in component, so you stay within the built-in-only rule.
Match the Symptom to the Cause
| Symptom on the view | Cause | Fix |
|---|---|---|
| Extra 0–100 axis on the right side of the trend | Marker series sits on its own Y axis, and that axis is still visible | Set that yAxes entry's visible to false on the XY Chart |
| Process trend squashed into a thin band | Marker points share the process axis, so autoscale stretches it to include 0 and 100 | Put the marker on a dedicated axis |
| Marker stops short of the top or bottom of the plot | Marker axis is autoscaling, or its range does not match the marker Y values | Set value.range.min and max equal to the marker Y values, with useStrict: true
|
| Diagonal line joining two markers | Several markers share one line series, so it connects the top of one to the bottom of the next | Use one series per marker |
| Marker never appears | Timestamp type or format does not match the X axis input, or the timestamp falls outside the displayed range | Feed the same timestamp type as the process data; check inputFormat
|
| Tooltip pops up showing 0 or 100 on hover | Marker series tooltip is enabled | Set the marker series tooltip.enabled to false
|
| Overlay line drifts after a resize or time-range change | Pixel math assumes a fixed plot area and a fixed time window | Lock the X range, or switch to the data-driven marker |
Build the Marker on the XY Chart
This is the resolving branch for most built-in-only installations.
A typical XY Chart setup looks like this:
- A time X axis named
timewithrender: "date"andinputFormatset toyyyy-MM-dd kk:mm:ss. - A process Y axis, for example
process temp. - Series whose
datablock points at a data source key and thet_stampand value columns.
Add the marker on top of that structure.
-
Add a marker Y axis. Append an entry to
props.yAxes. Hide it, fix its range, and remove its grid:{ "name": "marker", "visible": false, "render": "value", "value": { "range": { "min": 0, "max": 100, "useStrict": true } }, "appearance": { "opposite": true, "grid": { "opacity": 0 } } } -
Add a marker data source. Create a new key under the chart's data sources, for example
marker. Bind it to the marker timestamp, which can be a tag, a view parameter, or a query result. Add a script transform that returns two rows:def transform(self, value, quality, timestamp): # value = marker timestamp, same type/format as the process t_stamp column return [ {"t_stamp": value, "marker": 0}, {"t_stamp": value, "marker": 100} ] -
Add a marker series. Append an entry to
props.series:{ "name": "marker", "visible": true, "hiddenInLegend": true, "data": { "source": "marker", "x": "t_stamp", "y": "marker" }, "xAxis": "time", "yAxis": "marker", "render": "line", "tooltip": { "enabled": false } } - Color the line. Set the stroke color and width in the marker series' line appearance settings, for example red at a width that stands out from the process pen.
-
Add more markers if needed. Repeat steps 2 and 3 with a new data source key and a new series for each marker. Point every marker series at the same hidden
markeraxis.
Common time-wasters:
- Do not put the 0/100 points on the process axis to avoid a second axis. That squashes the trend.
- Do not leave the marker axis on autoscale. That shortens the line.
- Do not use a string timestamp when the process series uses epoch or date values, or the reverse. The marker lands outside the plotted range, or never parses.
Build the Overlay in a Coordinate Container
Use this only when you must keep the Time Series Chart untouched and the display geometry is stable.
- Place the Time Series Chart inside a Coordinate Container, sized to fill it.
- Add a thin line or shape component on top of the chart, styled red and set to the full plot height.
- Lock the time window. Bind the chart's displayed start and end times to known values. Without a fixed window you have nothing to calculate against.
- Bind the overlay's X position with an expression or script:
x_px = plot_left + plot_width * (t_marker - t_start) / (t_end - t_start)Here
plot_leftandplot_widthare the pixel offset and width of the actual plot area inside the chart. They are not the component bounds. Measure both on the running view, because Y-axis labels and the legend eat into the component width. - Hide the overlay whenever
t_markerfalls outsidet_starttot_end.
This method breaks whenever the plot area moves. Watch for these triggers:
- A longer axis label
- A legend change
- A different screen size
If operators resize or zoom, stop maintaining pixel math and move to the XY Chart branch.
Verify the Marker
- Position. Set the marker timestamp to a known process event. Confirm the line crosses the process pen at the same time shown in the process series tooltip.
-
Full height. The line must touch both the top and bottom of the plot area. If it does not, recheck the
min,max, anduseStrictvalues on the marker axis against the marker Y values. - No extra axis. Look at both sides of the plot. Neither side should show a 0–100 scale or dashed gridlines from the marker axis.
- Process scale unchanged. Compare the process axis range with and without the marker series. It must be identical.
- Range change. Shift the chart time window. The data-driven marker should move with the axis. An overlay marker must track correctly or hide itself.
- Legend and tooltip. Confirm the marker is absent from the legend. Hovering the line should show no tooltip.
- Session check. Open the view in a real Perspective session at the target screen resolution, not only in the Designer preview.
FAQ
Does the Ignition Perspective Time Series Chart have a built-in vertical marker line?
Check the property tree for your version. If you find no marker or annotation property, the component cannot draw one natively. Use an XY Chart two-point series, a Coordinate Container overlay, or a third-party Chart.js component with the annotation plugin.
Can I hide the second Y axis but keep the marker line visible?
On the XY Chart, yes. Set visible: false on the marker's yAxes entry, and fix its range with useStrict: true so the line still spans the plot. If your Time Series Chart axis configuration has no visibility property, rebuild the trend on the XY Chart.
Can I draw several marker lines on one Perspective chart?
Yes. Give each marker its own two-point series (timestamp at 0 and at 100), and point every marker series at the same hidden marker axis. Combining markers in one line series draws diagonal connectors between them.
When should I stop and contact Inductive Automation support?
Escalate if a hidden axis also stops its series from rendering, or if a marker series with matching timestamps still refuses to plot on a fixed-range axis. Before you call, export the chart JSON and note your exact Ignition version so support can reproduce the behavior.