Skip to Content
This documentation is provided with the HEAT environment and is relevant for this HEAT instance only.
RunnersCore UtilsTabular to Dataservice Node

tabular-to-dataservice (Transform Node)

The Tabular to Dataservice node converts a single tabular dataset (CSV, TSV, or tabular-query JSON) into a $heat-dataservice envelope for the Next dashboard data service. Downstream dashboard-v2 can consume the output without a hand-written json-template JMESPath layer.


Typical pipeline

CSV upload → tabular-to-dataservice → dashboard-v2

Optional upstream steps:

  • tabular-remap to normalize column names
  • tabular-query to filter or aggregate (set inputFormat: "json" and sourceTable on this node)

See the dashboard-v2 upstream contract for canonical payload shapes.


Configuration

PropertyTypeRequiredDefaultDescription
inputFormatauto | csv | tsv | json✖autojson for tabular-query output; auto sniffs CSV/TSV or JSON object
sourceTablestring✖*,tables key when input is JSON; required if multiple tables exist
timeColumnstring✔,Column used for series timeMs
timeColumnIsMsboolean✖trueValues are milliseconds offset from baseCapturedAt
timeColumnIsIso8601boolean✖falseParse ISO8601; timeMs = ms since minimum timestamp per realm
baseCapturedAtstring✖**,ISO8601 base when timeColumnIsMs=true
sortByTimeboolean✖trueSort emitted series points by timeMs
defaultRealmstring✖defaultRealm when no realmColumn or cell is empty
realmColumnstring✖,Distinct values become separate realms[].name
discardRowsWithEmptyRealmboolean✖falseDrop rows with empty realm cell
groupsarray✖one metrics groupChannel picker groups (id, name)
defaultGroupIdstring✖metricsGroup for auto-discovered channels
excludeColumnsarray✖[]Skip these columns (plus time/realm/PK columns)
includeColumnsarray✖,If set, only these columns become channels
channelsarray✖[]Explicit channel definitions (override auto)
treatEmptyAsNoneboolean✖trueTreat blank cells as empty
discardEmptyValuesboolean✖trueOmit series points with empty/non-numeric values
discardEmptyRowsboolean✖falseDrop rows where all channel values are empty
primaryKeyColumnsarray✖[]Extra dedupe key parts with timeColumn per channel
dedupePolicylast | first✖lastWhen duplicate time (+ PK), keep last or first row
dataserviceVersionstring✖1.0$heat-dataservice.version
dashboardUsersarray✖[]HEAT Auth external user GUIDs for dimension ACL

* Required when JSON input contains more than one table.

** Required when timeColumnIsMs=true and timeColumnIsIso8601=false.


Auto-discovered channels

By default, every column that is not reserved (time, realm, primary keys, excluded) and has at least one numeric value becomes a shape: "series" channel.

Channel id rule: lowercase header, non-alphanumeric characters become _, repeated _ collapsed (e.g. Speed (m/s) → speed_m_s). Layout configuration.channels in dashboard-v2 must use these ids (or define explicit channels[].id overrides).


Example (CSV)

{ "timeColumn": "time_ms", "timeColumnIsMs": true, "baseCapturedAt": "2025-01-01T00:00:00Z", "realmColumn": "pilot_id", "excludeColumns": ["notes"] }

Example (after tabular-query)

{ "inputFormat": "json", "sourceTable": "filtered", "timeColumn": "elapsed_ms", "timeColumnIsMs": true, "baseCapturedAt": "2025-01-01T00:00:00Z" }

Output

{ "$heat-dataservice": { "version": "1.0", "groups": [{ "id": "metrics", "name": "Metrics" }], "realms": [ { "name": "default", "channels": [ { "id": "speed_mps", "name": "speed_mps", "groupId": "metrics", "shape": "series", "data": [{ "timeMs": 0, "value": 10.0 }] } ] } ] }, "dashboard_users": [] }

Limits

  • The full table is loaded in memory (same as tabular-query / tabular-remap).
  • dashboard-v2 warns when realm count exceeds 50; avoid high-cardinality realmColumn values.

See also