Custom
Turning quantitative values into geometric shapes.
AI assisted, human approved — novem uses AI to review and keep our documentation up to date.
Novem custom plots run in a sandboxed iframe so that the plot author
can use any JavaScript library they like without affecting the
surrounding document. The iframe still inherits the parent document's
theme however, with every --novem-* value propagated in two ways: as
CSS variables on the iframe's root, and as a JavaScript object available
to the plot's render function.
Variables are injected into the iframe's :root before your stylesheet
runs, so you can use them directly anywhere you'd write a colour or a
font.
body {
font-family: var(--novem-font-body);
font-size: var(--novem-font-size);
color: var(--novem-text);
background: var(--novem-bg);
}
.tooltip {
background: var(--novem-tooltip-bg);
color: var(--novem-tooltip-text);
border-radius: var(--novem-tooltip-radius);
}
Every variable is also exposed on render.theme as a camelCase value,
which is useful when you build SVG or canvas content from JavaScript.
The categorical palette is an array indexed from zero.
const t = render.theme;
const svg = d3.select(node).append("svg")
.attr("width", width)
.attr("height", height)
.style("font-family", t.fontBody)
.style("background", "transparent");
const color = d3.scaleOrdinal(t.colors); // 10 categorical entries
svg.append("text")
.attr("fill", t.text)
.attr("font-weight", t.fontWeightHeading)
.text("My chart");
const arc = d3.arc()
.innerRadius(parseFloat(t.pieInnerRadius) * r)
.outerRadius(r);
render.theme is dark-mode aware. The value of t.text already
reflects whichever mode is active, so you don't need to branch on
render.dark to pick a foreground colour. The boolean is still there
if you want it for finer distinctions.