An HTML + JS custom visual draws its tile with the uni global: the rows the report sends, selection, saved state, the report's theme, assets, libraries and the outside content the sandbox allows. This page is the developer reference for that global and the platform limits around it. For the editor around your code, see The custom visual Studio; for the tier that runs no JavaScript, Custom visual templates.
uni. version), and everything your code does runs inside the sandbox, which has no network of its own.uni. mode is view, edit, preview, print or export; uni. root is the element your drawing goes into; uni. locale is the locale the tile formats in.uni. capabilities mirrors what the tile may do: select, composite, openUrl, assets, export, slicer, highlight and the allowed hosts. Some of these follow the Visual tab's Interactions section (Acts as, Selection from other tiles, Allow links); the allowed hosts come from the administrator's list.uni. size carries width, height, scale, dpr and visible, and it stays current as the tile resizes.uni. options holds the option values the viewer set, and uni. filters holds the filters the report applied to this visual, each with its label, operator, values and source.The groups behind the global:
| Group | Members | Use it for |
|---|---|---|
uni. | status, fields, dimensions, measures, rows, total, loaded, hasMore, isEmpty, error, field, role, value, text, number, sum, avg, min, max, count, groupBy, sortBy, requestMore | Reading what the tile received |
uni. | appearance, tokens, chartColors, color, hex, chart, series, ramp, diverging, echarts, chartjs, vegaConfig, plot | Colours and chart-library themes |
uni. | value, number, percent, abbrev, date | Formatting values yourself |
uni. | own, origin, isSelected | Your marks and the highlight state |
uni. | enabled, field, values, set, clear, autoPick | The slicer role |
uni. | get, set, reset | The viewer's saved state |
uni. | onSnapshot, onNative, pageCount, setPage | The export picture |
uni. | url, bytes, list, has, json | The report's asset files |
uni. | started, finished, failed | Long paints |
uni. render(fn) registers the paint. The host runs it on mount and again on every data, size, theme, selection, filters, options, state, reset or mode change.root, data, size, theme, selection, state, options, mode and reason; the reason is mount, swap, or the change that triggered the paint.uni. render. started() before the work and uni. render. finished() when it is drawn; a paint that settles without started() counts as finished. uni. ready() signals readiness when there is nothing to paint, and uni. render. failed(reason) (also exposed as uni. failed(reason)) reports a failure.uni.render((ctx) => {
const label = ctx.data.isEmpty ? 'No rows' : `${ctx.data.count()} rows`;
uni.text(ctx.root, label);
});uni. on(event, cb) listens to one render event (data, size, theme, selection, filters, options, state, reset, mode) and returns a function that removes the listener; an unknown event throws uni. on: unknown event ". . . ".uni. onDispose(cb) runs when your code is replaced or the tile closes, newest callbacks first. Register once at the top of the file, never inside the paint, and cancel timers, animation frames and observers there.uni. state. set made inside a paint is applied when the paint ends, and a paint that keeps repeating in one frame is stopped and recorded as a render loop in the Diagnostics.uni. data. fields lists the bound fields, each with id, label, role, kind, type, biType, filterable and its display format; dimensions and measures split the same list. uni. data. role('roleId', index) returns the field bound to a data role.uni. data. field(idOrLabel) resolves a field by id first, then by a unique label, and throws listing the available names: uni. data. field(". . . "): no such field. Available fields: . . ..__index (its position) and __selected (on, off or neutral).value, text (formatted with the field's own format), number, sum, avg, min, max and count read the rows; groupBy returns groups in first-appearance order, each with key, label and rows, and sortBy sorts rows, ascending or desc. An aggregate over a column with no numeric values returns NaN.status is loading, ready, refreshing, error or rlsDenied; total, loaded, hasMore, isEmpty and error describe the result.requestMore() cannot fetch more in SDK v1: it resolves false and records the warning uni. data. requestMore() is not available in SDK v1; the row limit is fixed by the tile. Set the tile's rows under General > Limits; see Custom visual options, data and limits.uni. select(target, { additive: true }) marks a value; a target is { field, value }, or { row, fields } to select a row's fields. Only filterable fields count, and the value must come from the rows the tile received.uni. selectComposite([{ field, value }, . . . ]) posts several fields as one tuple, for values that belong together; uni. clearSelection() clears the tile's own mark, and uni. isAdditive(event) is true on Ctrl or Cmd when you handle a click yourself.uni. selection. isSelected(row) reads a row's state; uni. selection. own is the tile's own mark, and origin says whose selection is showing (own, or a sibling tile's under Highlight).uni. slicer takes over: field is the first filterable dimension in the Data well, set(values, operator) replaces the selection (at most 1,000 values per set), clear() clears it, and autoPick(values) applies a starting pick that is never saved as the report default. The operators are in, eq, neq, between, gt, lt, gte, lte, isnull and notnull.uni. slicer: this visual is not a slicer (set interactions. role to "slicer" in the Visual pane) off the role, uni. slicer. <method>: bind a dimension to the Data well first with nothing bound, and uni. select: selection is disabled for this visual (interactions. select = false) with selection switched off. uni. select is disabled in the slicer role.data-uni-select, which needs a row or a group of that field in scope: data-uni-select=". . . " needs a row or a group of that field in scope; put it inside data-uni-repeat.uni. state. get(), uni. state. set(patch) and uni. state. reset() keep small state for the viewer, handed back on the next visit. The set is capped at 16 KB; a bigger patch is refused with uni. state. set: state would be . . . bytes, above the 16384-byte cap; keep only what the visual needs to restore itself. For how long the state is kept, see Custom visual options, data and limits.uni. format. value(value, field) formats a value with the field's saved format, and number, percent, abbrev and date are stable helpers that do not depend on the viewer's locale.uni. options is read-only in your code; the controls around it are the ones the visual's author declares, described in Custom visual options, data and limits.uni. html builds markup from a tagged template and escapes every interpolated value; uni. unsafeHtml is the only entry that takes raw markup, and it runs the sandbox's sanitiser first.uni. repeat(items, fn), uni. mount(target, template) and uni. text(el, value) build and place that markup; uni. mount takes a template from the two builders above.uni. tooltip. show(req) and uni. tooltip. hide() draw the tile's tooltip through the app.uni. log(level, . . . args) writes to the tile's console and the Diagnostics: debug and info read as log entries, warn and error keep their level. Plain console calls from your code are collected the same way.uni. theme. appearance is light or dark, and the report's tokens are applied to the visual as CSS variables: each --name token holds colour channels, a --uni-name mirror wraps it in hsl(. . . ), and the frame carries the light or dark class. A theme switch runs the paint again.uni. theme. color(name, alpha), hex(name), chart(index) and series(labels) read the palette; ramp(from, to, steps) and diverging(steps) build scales with at least 2 and 3 steps.uni. theme. echarts(), chartjs(), vegaConfig() and plot(); give chart datasets uni. theme. chart(i) for their series colours. Vega views take the interpreter the vega library ships, because the sandbox does not evaluate expressions.status-good to status-success, status-bad to status-error, status-neutral to status-pending, status-warn to status-warning, diverging-min to status-error, diverging-center to muted, diverging-max to status-success and foreground-muted to muted-foreground. An unknown name throws uni. theme: unknown token ". . . ". Available: . . ..uni. assets. url(name) returns a data: URL for image, font and data files and a blob: URL for binary ones; bytes(name) returns the raw bytes, list() and has(name) describe the attached files, and json(name) parses a JSON or GeoJSON asset, rejecting with uni. assets. json: unknown asset ". . . " or the parse error.uni. image(url) loads an https image through the app and resolves to a data: URL, cached per address. It rejects with a code: host-not-allowed, not-https, not-an-image, too-large or upstream; the first four are remembered, so a repeat fails the same way, while an upstream failure is retried. A refused host reads uni. image: host ". . . " is not in the sandbox allowlist.uni. embed(el, url) marks an element as an embedded player's box: the app draws the player in view, edit and preview, and a thumbnail stands in for it in export and print. It takes an https address, up to 32 embeds per visual (uni. embed: at most 32 embeds per visual; extra ones are ignored), and anything else warns uni. embed: only https URLs can be embedded, got ". . . ".uni. openUrl(url) opens an https link to an allowed host, with noopener, and a host allowed only by * asks the viewer first. With links switched off it warns uni. openUrl: links are disabled for this visual (interactions. openUrl = false), and it refuses anything but http(s) with uni. openUrl: only http(s) URLs are allowed, got ". . . ".import * as d3 from 'd3'; the bare names include d3, d3-sankey, chart. js, echarts, vega, vega-lite and @observablehq/ plot, and the Libraries menu of the Studio declares which of them a visual gets. Anything else is refused and the refusal names it.uni. icon(name) draws a bundled icon as inline SVG in currentColor, with size, strokeWidth, className and label options; an unknown name throws uni. icon: unknown icon ". . . ". Available: . . ..uni. exportHooks. onSnapshot(handler) lets the visual provide its own picture (a canvas, an SVG or a blob) for export and print; without it, the sandbox captures the drawn tile.uni. exportHooks. onNative(handler) provides the native pieces the export file can carry, and pageCount with setPage turn a tall visual into several pages.| What | Limit |
|---|---|
| Template render | 20,000 nodes (see Custom visual templates) |
| Viewer state | 16 KB |
| Slicer set | 1,000 values |
| Embeds | 32 per visual |
uni. ready() or a finished paint) is reported failed with missing-ready; export and print allow far longer than a report on screen.javascript: addresses; template style values refuse url(), expression() and javascript:, and @import is stripped from template CSS.uni. returns the field bound to that role, and the index picks among several fields in the same role. Bound fields also carry their role id in field., and uni. lists them all.
The paint's context carries reason: mount for the first paint, swap when the code is replaced, or the change that triggered it (data, size, theme, selection, filters, options, state, reset or mode). Use it to skip work a paint does not need.
In the Studio's Diagnostics. uni. writes a console entry (debug and info read as log entries, warn and error keep their level), and plain console calls from your code are collected the same way.
Read uni. (light or dark) and draw with the tokens: the report's tokens are applied to the visual as CSS variables, with a --uni- mirror in hsl(. form and a light or dark class on the frame. A theme switch runs the paint again, so a repaint picks the new values up.
Any token in uni., plus the names that fall back when the report does not define them, such as status-good to status-success and status-bad to status-error. An unknown name throws uni. with the list of known names. Ask through uni., hex(), chart() or series() rather than reading raw channel values.
uni. returns an inline SVG you can append to the drawing, and it accepts size, strokeWidth, className and label options. An unknown name throws uni. with the available names.
The sandbox notices a paint that keeps repeating in one frame, stops it and records a render loop in the Diagnostics. A uni. made inside a paint waits until the paint ends, so it cannot start a new paint on its own.
With uni.: the handler is asked for a canvas, an SVG or a blob when the report is exported or printed. onNative provides native pieces instead, and pageCount with setPage handle a visual that spans several pages.
The declared libraries install once per frame, so changing the set replaces the frame with one that carries the new set. Libraries the visual does not declare are refused, and the refusal names them.
Read uni.: draw a loading state for loading and refreshing, the tile's empty or error state for error, and an empty state for rlsDenied, where row-level security withholds the rows. An empty result is isEmpty.