Trends and signals
Trend <smart-trend>
Trend is a historian trend chart for process data.
<smart-trend> · 25 properties, 16 methods, 5 events · source/modules/smart.trend.js
Usage in Blazor
The Razor component is <Trend> in Smart.Blazor.Industrial: every property is a parameter in PascalCase, every event an EventCallback<Event> named On<Event> whose ev["Detail"] is the typed detail class, and the methods are called on the @ref. String choices are enums. In a Blazor Web App (.NET 8 and later) the page needs an interactive render mode, for example @rendermode InteractiveServer; a statically rendered component stays empty.
@using Smart.Blazor.Industrial
@* .NET 8 and later: an interactive render mode, on the page or for the whole app *@
@rendermode InteractiveServer
<Trend @ref="trend" ShowBands="true"
OnHistoryRequest="OnHistoryRequest" />
@code {
Trend trend;
void OnHistoryRequest(Event ev)
{
TrendHistoryRequestEventDetail detail = ev["Detail"];
}
// Task<bool> Push(object record)
void Call() => trend.Push(new { });
}
Properties
| Parameter | Type, default | Description |
|---|---|---|
Pens | IEnumerable<object> | Sets or retrieves the pens as [{ field, label, unit, min, max, color, visible, precision, quality, qualityField }]. field is the key under which each record carries the value; min and max are the engineering range the pen is scaled against, and a pen without them is scaled to the data on screen. quality is the tag's current quality - good, uncertain, bad or stale, or an OPC UA status code - and applies to the latest reading; qualityField names the record field that carries each sample's own quality (a word or a status code), read at the cursor too. A reading whose quality is not good says so beside the value, in the readout and in the accessible names. Items that are not objects, or have no field, are skipped. Assign a new array to update the component. |
Data | IEnumerable<object> | Sets or retrieves the records held by the trend as { timestamp, field: value, .. }, in time order. Assigning the property replaces the records; push and pushMany add to them. A record without a timestamp is stamped with the current time. |
TimeField | string | Sets or retrieves the key a record carries its time under, a timestamp in milliseconds or a Date. |
Bands | IEnumerable<object> | Sets or retrieves the prediction bands, one per pen, as [{ field, label, confidence, color, records }], where records is [{ timestamp, expected, lower, upper }] in time order and confidence is the confidence level as a fraction (0.95 for a 95% interval). A band is drawn under its pen and scaled against the pen's range, and the readout shows the expected value and the interval at the cursor. The model that produces the band is part of the application. Assign a new array to update the component. |
Markers | IEnumerable<object> | Sets or retrieves the anomaly markers as [{ id, field, timestamp, timestampEnd, severity, score, label, description }]. severity is advisory, warning or critical (other values are treated as warning) and score is the model's confidence from 0 to 1, shown with the marker. A marker with a field is placed on that pen's line; a marker without a field spans the plot. A marker with a timestampEnd is an interval and is drawn as a band of time. Markers can be stepped through with N and P, are read out at the cursor, and are reported by the markerClick event. Assign a new array to update the component. Items that are not objects (null, for example) are skipped with a console warning. |
ShowBands | bool | Determines whether the prediction bands are drawn and read out. The bands are kept either way. |
ShowMarkers | bool | Determines whether the anomaly markers are drawn, read out and stepped through. The markers are kept either way. |
TimeSpan | int | Sets or retrieves the window's width in milliseconds. |
End | double | Sets or retrieves the right edge of the window as a timestamp, while the trend is not live. The value is clamped to the newest sample, so the window cannot be moved into the future. |
Live | bool | Determines whether the window follows the newest sample. Dragging, zooming, setWindow and pan turn it off; goLive turns it back on. |
ScaleMode | TrendScaleMode | Sets or retrieves how the pens share the plot. percent draws every pen from 0 to 100% of its own range, as a historian does, which compares signals by shape; value draws all pens on one axis in engineering units, from min to max or from the data, for pens that share a unit. |
Min | double | Sets or retrieves the bottom of the shared value axis in value mode. null follows the data. |
Max | double | Sets or retrieves the top of the shared value axis in value mode. null follows the data. |
GapAfter | double | Sets or retrieves the maximum interval between two samples, in milliseconds, before the line is broken between them and valueAt returns NaN inside the gap. null (the default) works it out from the data: five times the median interval between records, so a late or missed poll is still joined and an outage is a gap, not a slope. 0 never breaks the line. With historian data that is stored on change (compressed), where long intervals are normal, set it to the longest interval that is not an outage, or 0. NaN or a negative value is ignored with a console warning and the interval is worked out from the data. |
HistoryLength | int | Sets or retrieves the number of records kept, 100 000 by default; the oldest records are dropped beyond it, but never a record inside the window on screen (or the one just before it), so a window wider than the bound keeps everything it shows. 0 keeps every record. When records assigned through data are dropped, a console warning says how many. NaN or a negative value keeps 100 000. |
StaleAfter | double | Sets or retrieves how long, in milliseconds, a pen may go without a new sample while the trend is live before its latest reading is marked stale - in the pens panel, the readout and their accessible names. null (the default) uses the gap interval (gapAfter, or the one worked out from the data), and never less than 2 s. 0 never marks a pen stale. The time is counted from when a sample arrived through push(), pushMany() or data, so a source clock that is off does not matter; history pages older than the newest sample held do not count as new. |
Cursor | double | Sets or retrieves the cursor as a timestamp. null hides it. With a cursor, the readout and the pens panel show the interpolated value of every pen at that time; without a cursor they show the newest values. |
ShowPens | bool | Determines whether the pens panel is shown next to the plot. The panel has one button per pen with its label, range and value, which shows or hides the pen. |
ShowReadout | bool | Determines whether the readout under the plot, the instant and every visible pen's value at it, is shown. |
ShowGrid | bool | Determines whether grid lines are drawn at the value and time ticks. |
ShowTimeAxis | bool | Determines whether the time axis is labelled under the plot, seconds on a short window, minutes on an hour, the date on a day. |
Interactive | bool | Determines whether the plot responds to the pointer and keyboard: drag pans, wheel zooms around the pointer, click places the cursor, double-click returns to live, and with focus the arrow keys move the cursor, plus and minus zoom, L returns to live and Escape clears the cursor. Off for a trend embedded in a scrolling page. The plot is then role="application" with a focusable tab stop and announces what the cursor reads; with interactive off it is role="img" and not a tab stop. |
Label | string | Sets or retrieves the trend's name, shown in the header and in the accessible name. |
PrecisionDigits | int | Sets or retrieves how many decimal places a value is printed with, for pens that do not set their own. Clamped to 0-20 when formatting. |
LineWidth | double | Sets or retrieves the width of a pen in pixels. |
Methods
| Method | Description |
|---|---|
Task<bool> Push(object record) | Appends one record and redraws. Returns false when there was nothing to add.record object { timestamp, field: value, .. }. A record without a timestamp is stamped on arrival. |
Task<bool> PushMany(IEnumerable<object> records) | Appends a batch of records, either live samples or a page of history, merged in time order, so that history arriving after live samples is placed correctly. Returns false when there was nothing to add.records array The records. |
void Clear() | Removes every record. |
Task<IEnumerable<object>> Snapshot() | Returns a copy of the records held, oldest first. |
Task<double> ValueAt(string field, long time) | Returns a pen's value at an instant, interpolated between the samples either side, or NaN outside the record, inside a gap (two samples further apart than gapAfter, or than the interval worked out from the data when gapAfter is null), next to a sample with no reading, or for a pen with no samples.field string The pen's field.time number A timestamp. |
Task<object> BandAt(string field, int time) | Returns the expected value and interval of a band for a pen at a time, interpolated between the two band records on either side, as { expected, lower, upper, confidence, label }, or null when the pen has no band at that time.field string The pen's field.time number A timestamp. |
Task<IEnumerable<object>> MarkersAt(int time) | Returns the markers at a time: an interval marker that contains the time, or an instant marker within one pixel column of it, so that a cursor placed with the pointer selects the marker.time number A timestamp. |
Task<object> NextMarker() | Moves the cursor to the next marker on screen after the cursor (or to the first marker when there is no cursor or the cursor is past the last one), announces it and returns it. Returns null when there are no markers on screen. |
Task<object> PreviousMarker() | Moves the cursor to the previous marker on screen, wrapping to the last one, announces it and returns it. Returns null when there are no markers on screen. |
Task<string> ToCSV() | Returns the visible window as CSV, an ISO timestamp column and one column per visible pen, for a spreadsheet. |
void GoLive() | Returns to live mode and follows the newest sample. |
void SetWindow(long from, long to) | Shows the given time interval and leaves live mode.from number A timestamp.to number A timestamp. |
void Zoom(double factor) | Zooms the window by a factor, keeping one time in place, and leaves live mode.factor number Above 1 zooms in, below 1 zooms out.around number A timestamp to keep in place; defaults to the window's centre. |
void Pan(long delta) | Moves the window by a time interval and leaves live mode. The window stops at the newest sample.delta number Milliseconds; negative moves back into the record. |
void TogglePen(int index) | Shows or hides one pen and raises the penVisibilityChange event.index number Which pen.visible boolean Force a state instead of toggling. |
void Invalidate() | Redraws the plot on the next animation frame, so that many pushes between two frames cost one draw. |
Events
Every event is an EventCallback<Event>; Event is a dictionary and ev["Detail"] converts to the detail class named under the event.
| Event | Description and detail |
|---|---|
OnWindowChange | This event is triggered when the interval on screen changes, by a drag, a zoom, a pan, setWindow, goLive, or a new sample while live.From double The window's start, as a timestamp.To double The window's end, as a timestamp.Live bool Whether the window follows the newest sample. |
OnHistoryRequest | This event is triggered when the window reaches a time before the earliest record held, once per interval rather than once per pixel of a drag. The application responds with pushMany; Smart.Industrial.Connect.trend responds from the history of a session.From double The start of the interval needed, as a timestamp.To double The end of the interval needed, the earliest record held, or the window's end.Fields dynamic The pens' fields. |
OnCursorChange | This event is triggered when the cursor is placed, moved or cleared through the pointer or keyboard.Time double The cursor's timestamp, or null when cleared.Values object Every pen's value at the cursor, keyed by field; NaN where there is none. |
OnMarkerClick | This event is triggered when a marker is clicked, or Enter is pressed with the cursor on one. The cursor has already moved to the marker. A host that wants the operator's verdict on the model, a true or a false positive, asks for it here.Marker object The marker, as it was given.Time double The time under the pointer or cursor. |
OnPenVisibilityChange | This event is triggered when a pen is shown or hidden from the pens panel or through togglePen.Index int Which pen.Field string The pen's field.Visible bool Whether it is now drawn. |
Types
enum TrendScaleMode
TrendScaleMode.Percent TrendScaleMode.Value
CSS variables
The component declares 4 CSS variables; the CSS page shows how to set them.
--smart-trend-height --smart-trend-pens-width --smart-trend-plot-background --smart-trend-grid-color