Kit API reference

The parts every safety.viz chart is built from, exported for a second chart library on the same page. Generated from src/kit.js — npm run docs:api fails on an undocumented member.

Members
36from 8 shared modules and Chart.js
Reached as
SafetyViz.kitor the kit export of the ES module bundle
Draws with
Chart.js 4.5.1the copy every chart in the bundle uses
Public surface
from v1.9.0a change to a member is a breaking change

Overview

The shared parts every safety.viz chart is built from, exported so a second chart library on the same page builds from them instead of copying them. Each member is the same function the charts themselves call. The object is flat and frozen.

Loading it beside another library

The kit is part of the safety.viz bundle, so there is nothing else to load. Put safety.viz first, then the library that builds on it:

<script src="dist/safety.viz-1.9.1/safety.viz.js"></script>
<script src="your-library.js"></script>
<script>
  const { renderShell, renderFilterControl, Chart } = SafetyViz.kit;
</script>

Or, from the ES module bundle:

import { kit } from './dist/safety.viz-1.9.1/safety.viz.esm.js';
const { renderShell, renderFilterControl, Chart } = kit;
  • One file is needed: dist/safety.viz-1.9.1/safety.viz.js for a script tag, or safety.viz.esm.js from the same folder for an import. The .map file beside each is its source map and is optional.
  • Use one bundle on a page, not both. The script-tag bundle and the ES module bundle are separate copies, each with its own Chart.js.
  • Take everything from that one copy. A library that brings its own Chart.js, or its own copy of these functions, draws charts and controls that drift from safety.viz's.
  • kit.Chart is Chart.js 4.5.1 with what the charts registered on it: the bar, line, scatter controllers, the bar, line, point elements, the category, linear, logarithmic scales, and the legend, title, tooltip plugins. A chart of one of those types needs nothing more; anything else is registered on the same constructor with kit.Chart.register().
  • A working page built this way is the fixture the browser tests drive, tests/e2e/fixtures/kit.html: a sidebar, a filter, a bar chart, a record listing and the participant rail, from the kit alone.

What is promised

  • The kit is public surface from v1.9.0: a change to any member, whether its name, its signature, what it returns or the elements and class names it produces, is a breaking change, and the release notes say so.
  • Every member is the function the charts in the bundle call, not a copy or a wrapper, so a page built from the kit behaves as the charts do. Unit tests hold each member to its module's export, and browser tests build a page from the committed bundle and the kit alone.
  • The kit is flat and frozen: members sit directly on it under the names below, and a library on the page cannot replace, add or remove one.
  • Adding a member is not a breaking change.
  • kmEstimate follows the Time-to-Event Explorer's Experimental status, which holds until an external clinical review confirms its Kaplan–Meier implementation (obot.roadmap#182): its estimates, intervals and at-risk counts may change after that review without counting as a breaking change. Its name and its arguments are kept.
  • The other 35 members are public surface in full.

Members

36 members, grouped by where they come from. Each signature is read from the function itself.

Chart.js

From Chart.js 4.5.1. The constructor the bundle contains, so a second library draws with the same copy.

MemberWhat it does
new Chart(item, userConfig)The Chart.js constructor this bundle contains: the one every safety.viz chart draws with, carrying the controllers, elements, scales and plugins the charts registered on it. Draw with it instead of loading a second Chart.js.

Shell and controls

From src/shell.js. The collapsible control sidebar, the slots a chart draws into, and the control builders.

MemberWhat it does
createElement(tag, className, text)Create a detached element with an optional class and text content.
option(select, value, label, selected)Append an option to a select.
multiSelect({ values, selected, onChange })Build the multiselect control: a collapsible checkbox list with an All row and a live summary. The selection is null for everything, or an array of the chosen values.
applyShellStyles()Inject the shared sv- stylesheet once per document. renderShell calls it, so a page that builds a shell need not.
renderShell(element, { moduleClass = '', onToggle } = {})Empty a container and build the shared layout into it: the collapsible control sidebar, the main column of notes, chart canvas, footnote, small multiples and listing, and the participant rail. Returns those slots by name.
controlBuilders(controls)The control builders bound to a shell's controls container: addSection, addRow, addControl and addReset.
renderViewSelector(addSection, { options, active, onChange, title = 'View' })Render a view selector into its own sidebar section: one button per view, the active one marked.

Filters

From src/filters.js. The filter contract: what a filter spec means, its opening state, its control and its test.

MemberWhat it does
ALL_VALUE = "__all__"The option value that stands for no restriction in a single-value filter.
normalizeFilterSpec(value, fallbackLabel)Normalize a column name or a filter spec to the filter contract: value_col, label, start, all and multiple.
initFilterState(specs)The opening filter state for a list of normalized specs: each spec's start value, or null for no restriction.
reconcileFilters(state, specs, valuesOf)Reconcile a filter state with the filters about to be drawn, so the selection each control shows is the selection the chart filters by: a filter with no control leaves no restriction behind, a new filter opens on its spec's start, a selection the data lacks falls back to All with a console warning, and with all: false the first value is selected. Returns the spec, values and selection for each control to draw. It is on the kit because every chart now calls it as it builds its filter controls: it joined the filter contract in the v1.8.0 review (safety.viz #166 and #171), after the kit's member list was first written.
filterMatches(rowValue, selection)Whether one row's value passes one filter's selection: null passes everything, an array is membership, anything else is equality.
renderFilterControl({ spec, values, selected, onChange })Build one filter control from its spec: a select with an optional All option, or the multiselect when the spec says multiple.

Axis limits

From src/axis-limits.js. The Lower and Upper inputs that show the limit in force and keep only what was edited.

MemberWhat it does
limitDigits(domain)Decimal places for a displayed axis limit: three significant figures of the axis range.
formatLimit(value, digits)Format a limit for its number input, dropping trailing zeros; blank when the value is not finite.
syncAxisLimits(state, domain, inputs = {})Record the domain a render resolved on state.axisDomain and write it into the Lower and Upper inputs.
seedLimitInput(state, key)The value a limit input carries when the controls are rebuilt: the user's override, or else the domain last in force.
applyLimitEdit(state, key, raw)Apply an edited limit to state.lower or state.upper: an empty entry returns that side to automatic, and a pair that crosses is swapped.
clearAxisLimits(state)Drop both overrides and the recorded domain, so the next render derives the limits from the data.

Record listing

From src/histogram/listing.js. The linked listing, with its search, sort, paging and CSV functions.

MemberWhat it does
renderListing(instance)Draw the record listing into instance.listingWrap, with its search box, paging buttons, sortable headers and CSV export. It reads the columns from instance.settings.details, the page size from settings.page_size, and the rows and view state from instance.currentTableData, listingSearch, listingSort and page. When instance.onListingRowClick is a function the rows are clickable and keyboard-focusable, and rows whose settings.id_col value equals instance.listingSelectedId are marked.
searchRows(rows, cols, query)The rows in which any listed column contains the query, ignoring case.
sortRows(rows, sort)A sorted copy of the rows by one column, ascending or descending: numeric when both values are numbers, otherwise as text.
paginate(rows, page, pageSize)One page of rows, with the number of pages and the page number held within it.
buildCsv(rows, cols)The listing as CSV text: a header of column labels, then one line of quoted values per row.
exportCsv(rows, cols)Download the listing as a CSV file. The file is named safety-histogram-listing.csv.

Participant rail

From src/profile-host.js. What a host chart calls to open the participant profile beside itself.

MemberWhat it does
buildProfileRows(rawData, mapping)Build the rows the participant rail reads, from a host's raw lab records and its column mapping, once per data load. Rows with no positive upper limit of normal are dropped.
mountProfileRail(host, settingsFn, { target = null } = {})Mount the participant rail into host.railWrap and subscribe it to the participantsSelected event on host.root, or on options.target. The event's detail.data is the list of participant ids, and an empty list clears the rail. It does nothing unless host.settings.profile is set, and reads the rows from host.profileRows.
unmountProfileRail(host)Unsubscribe the rail, destroy its charts and empty its slot.
syncProfileRail(host, settingsFn)Reconcile the rail with the host's current settings: mount or unmount it when profile changes, otherwise hand it the current rows and settings.
resetProfileRail(host)Empty the rail when the host resets its own selection.

Box drawing

From src/box-whisker.js. Box-and-whisker marks on a Chart.js canvas, and the plugin that draws them.

MemberWhat it does
drawBoxWhisker(ctx, { scales, chartArea }, specs)Draw box-and-whisker marks on a canvas through a chart's x and y scales: for each spec a box from the first to the third quartile, whiskers to the 5th and 95th percentiles, a median line and a mean marker.
boxWhiskerPlugin(idPrefix, getSpecs)A Chart.js plugin that draws the box-and-whisker marks for whatever specs its getter returns at draw time.

Measure list

From src/measure-list.js. Which measures a Measure control offers, and in what order.

MemberWhat it does
resolveMeasureList(present, configured, { warn = true } = {})The labels a Measure control offers: the configured measures in their order, or every measure in the data, sorted, when none is configured or none is found.
presentMeasures(rows, settings, label)The distinct measures in cleaned rows, in first-seen order, as the label and raw name that resolveMeasureList takes.

Kaplan–Meier estimator

From src/time-to-event/km.js. The estimator behind the Time-to-Event Explorer.

MemberWhat it does
kmEstimate(observations)The Kaplan–Meier estimate for one group, from one observation per participant of a time, whether it ends in the event, and an id: the steps with their at-risk and event counts, standard errors and pointwise 95% intervals, the censoring times, and a reader for the at-risk table. Follows the Time-to-Event Explorer's Experimental status: see what is promised.

Not in the kit

  • The chart factories. SafetyViz.histogram() and the rest are the library's own public surface, documented on each chart's API reference; the kit is what they are built from.
  • prototypeBanner and experimentalBanner, which src/shell.js also exports: their wording is safety.viz's own release status.
  • hexToRgba, which src/box-whisker.js also exports: a colour helper private to the box drawing.
  • Everything else under src/: each chart's data preparation, scales and plugins stay internal and can change without notice.