Skip to content

Runtime attributes

The data-dash roles and every data attribute the Dashies dashboard runtime reads, including the viewer controls and time intelligence.

A published dashboard is one HTML file. The runtime finds every element carrying data-dash, reads the other data-* attributes on it to learn what to render, and resolves each value against the data island.

You get these attributes for free when you publish a spec with tiles. You write them by hand only in look mode, where the markup is yours. Either way the same runtime reads them, and every binding must resolve against a declared dataset or the publish is refused.

Roles

data-dash names what an element is. Seventeen values are recognised.

RoleRendered by the spec tile
metrickpi
chartchart
tabletable
matrixmatrix
heatmapheatmap
scatterscatter
treemaptreemap
waterfallwaterfall
funnelfunnel
drilldowndrilldown
stackedstacked
combocombo
piepie
donutdonut
gaugegauge
filterfilter
updated-atemitted once per dashboard, not by a tile

The kpi tile compiles to data-dash="metric"; that is the only case where the tile type and the role differ in name. The text and custom tiles carry no data-dash at all: one is prose and the other is markup you own.

data-dash="updated-at" marks the span that receives the freshness stamp. It takes no other attributes.

Routing

AttributeValueNotes
data-dataseta dataset nameWhich dataset this tile reads. Emitted on every bound tile when the dashboard declares more than one; with a single dataset it is omitted and the runtime uses that one.

Binding a value

AttributeValueRead by
data-measurea measure keyEvery role that shows a figure.
data-measurescomma-separated measure keyschart, for a multi-series chart.
data-measure2a measure keycombo, the secondary axis.
data-num, data-denmeasure keysAny role showing a ratio. The ratio is computed under the current filters, never stored.
data-num-scope, data-den-scopeallComputes that side of the ratio over the unfiltered dataset, which is how a share-of-total is expressed.
data-num2, data-den2measure keyscombo, a ratio on the secondary axis.
data-aggan aggregate nameAn override the compiler never emits. It is honoured only where it agrees with the stored measure; a claim the data cannot support renders unavailable.

Naming a dimension

AttributeValueRead by
data-xa dimension keychart, stacked, combo, treemap, waterfall, funnel, pie, donut.
data-rows, data-colsdimension keysmatrix, heatmap.
data-pointa dimension keyscatter, one point per member.
data-levelscomma-separated dimension keysdrilldown, outermost first.
data-seriesa dimension keychart, stacked.
data-dima dimension keyfilter.

Shape and scale

AttributeValueRead by
data-typebar, hbar, line, areachart, stacked.
data-type2bar, line, areacombo, the secondary series.
data-stacknormal, percentstacked.
data-axis-syncpresentcombo, forces both axes onto one scale.
data-subtotalsboth, row, col, nonematrix, heatmap.
data-colorheat, divergingmatrix, heatmap.
data-min, data-max, data-targetnumbersgauge. These are numeric literals, not measure keys.
data-stagescomma-separated dimension valuesfunnel, in the order the funnel runs.
data-top-n, data-other, data-totala number, then two flagsdrilldown.

How much, and how big

AttributeValueRead by
data-limitan integerMembers rendered before truncation. The ceiling differs per role: see Tile types.
data-sortvalue-desc, value-asc, or <key>:asc / <key>:desc on a tablechart, table.
data-columns, data-groupcolumn keystable.
data-height120 to 800Every drawn chart role.

Display

AttributeValueNotes
data-labela stringThe visible label, on a filter.
data-formata format nameHow to render the figure. data-format2 is the combo secondary.
data-currencyan ISO 4217 codeEmitted only where it differs from the dashboard's global currency.
data-decimals0 to 6Same rule.
data-scalea divisorInert. The compiler emits it on a ratio binding and no runtime fragment reads it, so it changes nothing. It is why a measure declaring scale: cents or scale: points is refused at publish rather than rendered at 100 times its value.

Viewer controls

These are what make a published page interactive without a server. Each is read at view time and changes only what is on screen.

AttributeValueEffect
data-multipresentThe filter becomes a multi-select listbox instead of a single-select.
data-rangepresentThe filter becomes a range selector. A tile may carry data-multi or data-range, never both.
data-controlscontrol namesAdds live sort and limit controls to a chart or table, so a reader can reorder or widen it.
data-xfilterpresentClicking a bar filters the rest of the dashboard by that member.
data-drilla dataset nameClicking the tile opens a modal showing that dataset's detail for the clicked member.
data-tilea tile idThe identity a control or cross-filter addresses. Emitted alongside the two above.

A multi-select or range filter changes which cells the resolver has to combine, which is why declaring one can change the dataset mode a spec needs. See how mode is resolved.

Time intelligence

Four attributes, on a metric tile only. The compiler does not emit these; they are available in look mode and on hand-written markup.

AttributeValue
data-timeintelthe date dimension key to walk
data-compareyoy, qoq, mom, pop, ytd, running, movavg
data-compare-aspct, delta, prior, current. Defaults to pct. Applies to a shift mode only
data-window2 to 1,000, required by movavg

yoy, qoq and mom shift the anchor period back 12, 3 and 1 months. pop steps to the previous period actually present in the series rather than a calendar guess. ytd and running accumulate up to and including the anchor.

Every one of these resolves at view time out of cells a lattice already precomputed, so the comparison stays correct under whatever filter is applied. A comparison composes two resolutions, so both must be exact: where a prior period is missing, the tile renders unavailable rather than treating the absence as a zero and reporting a confident growth figure.

That means a comparison needs a lattice or hybrid dataset. On a plain cube or a row-level dataset the tile says so and renders nothing.

What a tile cannot do

A published dashboard is served with Content-Security-Policy: sandbox allow-scripts. Scripts run, including a custom tile's js, but the page is placed in an opaque origin. That is not configurable.

CapabilityUnder the sandbox
Script executionallowed, which is what allow-scripts grants
localStorage, sessionStorage, IndexedDB, cookiesdenied, and access throws
Same-origin authenticated fetchdenied, because the origin is opaque
Cross-origin fetchnot restricted

This isolates the page from your Dashies account. It does not confine the page.

There is no connect-src and no default-src in that header, so a cross-origin fetch from a custom tile is not blocked. The product relies on exactly that: the row-level query engine is loaded cross-origin from data.dashies.xyz under this same header, and that cross-origin split is what preserves the isolation in the first place.

What the sandbox buys is the thing that matters on a shared origin. A published dashboard is served from a host the Dashies app also uses, so without the opaque origin any markup an author included could read a viewer's session out of localStorage. The sandbox makes that impossible. It is not a promise that the page talks to nothing.

Two variants add a framing rule on top: a private dashboard is served with frame-ancestors 'none', and a preview with frame-ancestors 'self'. Those constrain who may frame the page, not what the page may read.

The practical consequence for a custom tile is still that it should draw only from the datasets named in its reads, which the runtime hands it directly. Anything it fetches itself is outside the refresh contract: it is not versioned, not seeded, not re-run on the schedule, and not covered by any of the correctness checks on this site.

Check it worked

Open the published dashboard and change a filter. Every bound tile should either update or state a reason it cannot. A tile that renders a stale figure after a filter change is reading something other than the resolver, which for a custom tile means its js is holding its own copy of the numbers.