DatumHueEnterprise v0.0.24datumhue.com
Contents

handle30 methods, 2 fields

PlotArea

A plot area inside a canvas, created by canvas:chart(opts). Hosts marks, axes, legends, scales, and interaction behaviors.

Obtained from
DrawCanvas:chart, DrawCanvas:charts, Book:element

The examples on this page start from:

lua
local vec2 = datumhue.math.vec2
local color = datumhue.color
local canvas = datumhue.draw.new({ width = 400, height = 300 })
canvas:mount({ width = 400, height = 300 })
local plot = canvas:chart({
    margin = { left = 40, right = 16, top = 40, bottom = 40 },
})

Fields 2

FieldTypeAccessDescription
x_scaleScale?read-onlyThe area's x-axis Scale handle — the one passed at construction, or the default linear scale created for the area when none was passed (removed with the area). Read-only; swap scales via area:update({x_scale = ...}).
y_scaleScale?read-onlyThe area's y-axis Scale handle. Mirror of x_scale; swap via area:update({y_scale = ...}).

Methods 30

PlotArea:line

method
PlotArea:line(options: chart.LineMarkOptions) -> Mark

Add a line mark. Exactly one of points, data, or view is required. Rows with null values are skipped; a null in the x or y column breaks the line at that row.

Example
-- Exactly one of points, data or view; data names its two columns.
local temps =
    datumhue.bytes("hour,temp\n6,180\n7,215\n8,230\n9,224\n"):csv()
plot:line({
    data = temps,
    x_column = "hour",
    y_column = "temp",
    width = 2,
    color = color("#e69875"),
})

options chart.LineMarkOptions options 15 keys, 11 inherited

KeyTypeDefaultDescription
widthnumber1.5Stroke width.
series_columnstringone seriesCategory column splitting rows into one series per distinct value (data sources only). Each series draws as its own line, takes a color from color_scale or the category palette in first-seen order, and contributes its own legend item.
color_scaleColorScalethe category paletteCategory color scale assigning per-series colors; requires series_column.
readout"interpolate" | "nearest""interpolate"Crosshair readout interpolation mode.

Also takes every key of chart.DataMarkBase (11 keys).

PlotArea:points

method
PlotArea:points(options: chart.PointsMarkOptions) -> Mark

Add a scatter (dots) mark. Exactly one of points, data, or view is required; data-bound points render every row in the visible range. Rows with null values are skipped.

Example
-- Dots take their proof's color; a pending domain fits the column.
local csv = "grams,rise,proof\n790,4.1,40\n812,4.6,55\n805,4.4,70"
local proof = datumhue.chart.scale.color({ palette = "viridis" })
plot:points({
    data = datumhue.bytes(csv):csv(),
    x_column = "grams",
    y_column = "rise",
    color_column = "proof",
    color_scale = proof,
})
datumhue.time.wait_frames(1)
print(proof.domain.min, proof.domain.max) --> 40.0 70.0

options chart.PointsMarkOptions options 17 keys, 11 inherited

KeyTypeDefaultDescription
sizenumber4Dot size.
size_columnstringevery dot takes sizeColumn driving per-dot size.
size_scaleScalethe call raises with size_columnScale whose domain normalizes size_column values.
size_rangetablethe call raises with size_column{min, max} output dot sizes in pixels for size_column values.
color_columnstringevery dot takes colorColumn driving per-dot color.
color_scaleColorScalethe call raises with color_columnColor scale for color_column. A ramp whose domain is pending fits the column's extent once the data loads, and again when Mark:replace_data swaps the data.

Also takes every key of chart.DataMarkBase (11 keys).

PlotArea:area

method
PlotArea:area(options: chart.AreaMarkOptions) -> Mark

Add a filled-area mark — closed polygon between a data line and a numeric baseline. Exactly one of points, data, or view required. Rows with null values are skipped; a null in the x or y column breaks the area at that row.

Example
-- Fills between the line and the baseline, in data units; without a
-- color, in the theme's chart-label color at half opacity.
plot:area({
    points = { vec2(0, 2), vec2(1, 5), vec2(2, 3), vec2(3, 6) },
    baseline = 1,
})

options chart.AreaMarkOptions options 15 keys, 10 inherited

KeyTypeDefaultDescription
baselinenumber0Numeric baseline the area fills to.
series_columnstringone seriesCategory column splitting rows into one series per distinct value (data sources only). Each series draws as its own area, takes a color from color_scale or the category palette in first-seen order, and contributes its own legend item.
color_scaleColorScalethe category paletteCategory color scale assigning per-series colors; requires series_column.
readout"interpolate" | "nearest""interpolate"Crosshair readout interpolation mode.
colorColorthe theme's chart-label color at half opacity, restyled on a theme switchFill color.

Also takes the other 10 keys of chart.DataMarkBase.

PlotArea:rule

method
PlotArea:rule(options: chart.RuleMarkOptions) -> Mark

Add a horizontal or vertical reference line at a data-space value.

Example
-- value is in data units on the axis the line crosses.
plot.x_scale.domain = { min = 0, max = 10 }
plot.y_scale.domain = { min = 0, max = 10 }
plot:rule({
    orientation = "horizontal",
    value = 5,
    width = 2,
    color = color("#e67e80"),
    value_label = "target",
})

options chart.RuleMarkOptions options 5 keys

KeyTypeDefaultDescription
orientation required"vertical" | "horizontal"no defaultReference-line direction.
value requirednumber | stringno defaultData-space position of the line. A category name resolves to the band scale's slot center when the mark is created; raises when the axis scale isn't a band scale or the category is unknown.
colorColorthe theme's chart-label color, restyled on a theme switchLine color.
widthnumber1Line width.
value_labelstringno labelLabel drawn at the line.

PlotArea:text

method
PlotArea:text(options: chart.TextMarkOptions) -> Mark

Add a text annotation at a data-space position.

Example
-- pos is in data units; offset moves the text in pixels, y up.
plot.x_scale.domain = { min = 0, max = 10 }
plot.y_scale.domain = { min = 0, max = 10 }
plot:text({
    pos = vec2(5, 5),
    text = "halfway",
    align = "bottom_left",
    offset = vec2(6, 6),
    font_size = 18,
    color = color("#e69875"),
})

options chart.TextMarkOptions options 8 keys

KeyTypeDefaultDescription
pos requiredVec2 | chart.TextPosno defaultData-space anchor position. In the table form a category name resolves to the band scale's slot center when the mark is created; raises when that axis's scale isn't a band scale or the category is unknown.
text requiredstringno defaultAnnotation text.
colorColorthe theme's chart-label color, restyled on a theme switchText color.
font_sizenumber | string12Font size — a number (px) or a unit string like "1.5rem"/"50vw".
font_weightnumber | "thin" | "extralight" | "light" | "regular" | "normal" | "medium" | "semibold" | "bold"the body text weightText weight on the brand font's variable axis.
font_style"normal" | "italic" | "oblique"the upright faceText face.
alignchart.TextAnchor"center"Anchor point of the text box relative to pos.
offsetVec2datumhue.math.vec2(0, 0)Pixel offset from pos.

PlotArea:band

method
PlotArea:band(options: chart.BandMarkOptions) -> Mark

Add a filled highlighted region spanning a [from, to] range on one axis and the full inner rect on the orthogonal axis.

Example
-- Shades x from 2 to 4 across the full height of the area.
plot.x_scale.domain = { min = 0, max = 10 }
plot:band({
    axis = "x",
    from = 2,
    to = 4,
    color = color("#dbbc7f"),
})

options chart.BandMarkOptions options 4 keys

KeyTypeDefaultDescription
axis required"x" | "y"no defaultAxis the [from, to] range spans.
from requirednumberno defaultRange start (data space).
to requirednumberno defaultRange end (data space).
colorColorthe theme's chart-label color at 20% opacity, restyled on a theme switchFill color.

PlotArea:bars

method
PlotArea:bars(options: chart.BarsMarkOptions) -> Mark

Add a bar mark — one rectangle per category, from inline entries/series or a data source grouped by category. Requires a band scale on the categorical axis; discovered categories append to it.

Example
-- Bars need a band scale on their category axis: the area's, or one
-- given to the mark, which the area lays out.
local days = datumhue.chart.scale.band({ domain = { "Mon", "Tue" } })
plot:bars({
    entries = {
        { category = "Mon", value = 42 },
        { category = "Tue", value = 30 },
    },
    x_scale = days,
})

options chart.BarsMarkOptions options 15 keys

KeyTypeDefaultDescription
entriestablethe series or data sourceArray of {category, value} entries. Exactly one of entries, series, or data.
seriestablethe entries or data sourceArray of {name?, color?, entries} series for stacked/grouped layouts; a series without a color takes the category palette's. Requires mode.
dataDataHandlethe entries or series sourceTabular source; requires category_column. Bars aggregate per category — no row becomes a Lua table. Rows with a null category or value are skipped.
category_columnstringthe call raises with dataCategory column to group by (data sources).
value_columnstringonly the count aggregateNumeric column to aggregate; required for every aggregate except count.
series_columnstringone seriesCategory column splitting rows into one series per distinct value (data sources). Requires mode; series take palette colors in first-seen order.
aggregate"sum" | "mean" | "min" | "max" | "count"sum with a value_column, count without onePer-category aggregation for data sources.
mode"stacked" | "grouped"one series; the call raises with series or series_columnMulti-series layout. Stacked accumulates per category from the baseline (negatives stack downward); grouped subdivides each band per series.
group_paddingnumber0.1Gap between grouped sub-bars as a 0..1 fraction.
orientation"vertical" | "horizontal""vertical"Bar orientation.
colorColorthe theme's chart-label color, restyled on a theme switchBar color.
baselinenumber0Numeric baseline the bars grow from.
namestringno name; automatic legends skip the markLegend name.
x_scaleScalethe area's x scaleX scale.
y_scaleScalethe area's y scaleY scale.

PlotArea:histogram

method
PlotArea:histogram(options: chart.HistogramMarkOptions) -> Mark

Add a histogram — contiguous bins over a numeric column or inline values. Pending scales fit to the bin extent and peak; a zoomed x scale re-bins over the visible domain. Rows with null values are skipped.

Example
-- bin_width is in data units; "fraction" makes the bars sum to 1.
plot:histogram({
    values = { 1.2, 1.9, 2.1, 2.4, 2.8, 3.1, 3.3, 4.6 },
    bin_width = 1,
    normalize = "fraction",
})

options chart.HistogramMarkOptions options 11 keys

KeyTypeDefaultDescription
valuesnumber[]the data sourceInline values to bin. Exactly one of values or data.
dataDataHandlethe values sourceTabular source; requires column. Binning reads the column — no row becomes a Lua table.
columnstringthe call raises with dataColumn to bin (data sources).
binsnumber | string"auto", or the bin_width spacing when that is setBin count, or "auto" for width-by-spread with a count floor. Mutually exclusive with bin_width.
bin_widthnumberthe spacing bins givesExplicit bin width in data units. Mutually exclusive with bins.
normalize"count" | "fraction" | "density""count"Bar heights.
rangetablethe data extent{min, max} bin extent; a zoomed x scale re-bins over the visible domain.
colorColorthe theme's chart-label color, restyled on a theme switchBar color.
namestringno name; automatic legends skip the markLegend name.
x_scaleScalethe area's x scaleX scale.
y_scaleScalethe area's y scaleY scale.

PlotArea:heatmap

method
PlotArea:heatmap(options: chart.HeatmapMarkOptions) -> Mark

Add a categorical heatmap — one colored cell per (x, y) category pair, from inline cells, a matrix, or a data source grouped by category pair. Both axes need band scales; discovered categories append to them.

Example
-- Both axes need band scales, here the mark's own; matrix row 1 is the
-- bottom row.
local band = datumhue.chart.scale.band
plot:heatmap({
    matrix = { { 3, 8, 5 }, { 6, 2, 9 } },
    x_categories = { "Mon", "Tue", "Wed" },
    y_categories = { "Bread", "Buns" },
    x_scale = band({ domain = { "Mon", "Tue", "Wed" } }),
    y_scale = band({ domain = { "Bread", "Buns" } }),
    color_scale = datumhue.chart.scale.color({ palette = "viridis" }),
})

options chart.HeatmapMarkOptions options 14 keys

KeyTypeDefaultDescription
cellstablethe matrix or data sourceArray of {x, y, value} cells (x/y are category strings). Exactly one of cells, matrix, or data.
matrixtablethe cells or data sourceRow-major {{number, ...}, ...} values; requires x_categories and y_categories (row index follows y_categories).
x_categoriesstring[]the call raises with matrixColumn categories for matrix.
y_categoriesstring[]the call raises with matrixRow categories for matrix.
dataDataHandlethe cells or matrix sourceTabular source; requires x_column and y_column. Cells aggregate per category pair.
x_columnstringthe call raises with dataCategory column for cell columns (data sources).
y_columnstringthe call raises with dataCategory column for cell rows (data sources).
value_columnstringonly the count aggregateValue column to aggregate; required for sum/mean.
aggregate"count" | "sum" | "mean"mean with a value_column, count without oneCell aggregation for data sources.
color_scale requiredColorScaleno defaultMaps cell values to colors. A pending domain fits the cell extent and keeps tracking it.
gapnumber0Pixel gap between cells.
namestringno name; automatic legends skip the markLegend name.
x_scaleScalethe area's x scaleBand scale for columns. Discovered categories are appended in first-seen order.
y_scaleScalethe area's y scaleBand scale for rows. Discovered categories are appended in first-seen order.

PlotArea:box

method
PlotArea:box(options: chart.BoxMarkOptions) -> Mark

Add a box-and-whisker mark — one five-number summary per category, from pre-computed entries or a data source grouped by category. Requires a band scale on the categorical axis; discovered categories append to it.

Example
-- Quartiles, whiskers and outliers are computed from the rows.
local csv = "bread,grams\nRye,780\nRye,795\nRye,800\nRye,806\nRye,822"
local loaves = datumhue.bytes(csv):csv()
local breads = datumhue.chart.scale.band({ domain = { "Rye" } })
plot:update({ x_scale = breads })
plot:box({
    data = loaves,
    category_column = "bread",
    value_column = "grams",
})

options chart.BoxMarkOptions options 12 keys

KeyTypeDefaultDescription
entrieschart.BoxEntry[]the data sourcePre-computed summaries (low/high are the whisker ends). Exactly one of entries or data.
dataDataHandlethe entries sourceTabular source; requires category_column and value_column. Summaries take quartiles by linear interpolation, whiskers at the farthest values inside the 1.5 IQR fences, and the rest as outliers.
category_columnstringthe call raises with dataCategory column to group by (data sources).
value_columnstringthe call raises with dataNumeric column to summarize (data sources).
box_widthnumber0.6Box width as a 0..1 fraction of the band slot.
orientation"vertical" | "horizontal""vertical"Box orientation. The category axis is x when vertical, y when horizontal.
colorColorthe theme's chart-label color, restyled on a theme switchBox and whisker color.
median_colorColordatumhue.color(0, 0, 0)Median line color.
outlier_colorColorthe box colorOutlier point color.
namestringno name; automatic legends skip the markLegend name.
x_scaleScalethe area's x scaleX scale. Discovered categories append to the band scale on the category axis.
y_scaleScalethe area's y scaleY scale.

PlotArea:histogram2d

method
PlotArea:histogram2d(options: chart.Histogram2dMarkOptions) -> Mark

Add a 2D density heatmap — numeric (x, y) pairs binned into a colored grid. Zoomed scales re-bin over the visible window.

Example
-- Counts the points falling in each cell of an 8 x 6 grid.
local rng = datumhue.random.new(3)
local points = {}
for i = 1, 300 do
    points[i] = vec2(rng:next() + rng:next(), rng:next())
end
plot:histogram2d({
    points = points,
    x_bins = 8,
    y_bins = 6,
    color_scale = datumhue.chart.scale.color({ palette = "magma" }),
})

options chart.Histogram2dMarkOptions options 12 keys

KeyTypeDefaultDescription
pointstablethe data sourceInline vec2 points to bin. Exactly one of points or data.
dataDataHandlethe points sourceTabular source; requires x_column and y_column.
x_columnstringthe call raises with dataNumeric column for x (data sources).
y_columnstringthe call raises with dataNumeric column for y (data sources).
x_binsnumber | string"auto"Bin count for x, or "auto".
y_binsnumber | string"auto"Bin count for y, or "auto".
normalize"count" | "fraction""count"Cell values.
color_scale requiredColorScaleno defaultMaps cell values to colors. A pending domain fits the cell extent and keeps tracking it across zoom re-bins.
gapnumber0Pixel gap between cells.
namestringno name; automatic legends skip the markLegend name.
x_scaleScalethe area's x scaleNumeric x scale.
y_scaleScalethe area's y scaleNumeric y scale.

PlotArea:axis

method
PlotArea:axis(options: chart.AxisOptions) -> Axis

Add an axis bound to a scale.

Example
-- tick_values are data values; format gives each label one decimal.
plot.x_scale.domain = { min = 0, max = 10 }
plot.y_scale.domain = { min = 0, max = 1 }
plot:axis({ scale = plot.x_scale, side = "bottom", label = "hour" })
plot:axis({
    scale = plot.y_scale,
    side = "left",
    tick_values = { 0.2, 0.5, 0.8 },
    format = "{:.1}",
    grid = true,
})

options chart.AxisOptions options 10 keys

KeyTypeDefaultDescription
scale requiredScaleno defaultScale the axis is bound to.
side required"bottom" | "left" | "top" | "right"no defaultEdge of the plot area the axis sits on.
ticksinteger6Target tick count.
tick_valuesnumber[]positions picked for the ticks targetExplicit tick positions as data values; on a band scale, 0-based band indices (0 is the first category), as scale:map takes them.
labelstringno axis titleAxis title, centered along the axis beyond the tick labels; on a vertical axis it reads along the axis.
font_sizenumber | stringthe theme's small text sizeSize of the tick labels and the axis label — a number (px) or a unit string like "1.5rem"/"50vw". The gaps between the axis line, tick labels, and axis label grow with it.
formatstringthe scale's own tick labelsTick-label format string; the scale's kind selects how it is read. On a time scale it is a UTC date pattern of literal text plus %Y %m %d %H %M %S (%% for a percent sign), and an unknown specifier raises. On every other scale it is a numeric dialect with three forms: {:.N} for N fixed decimals, {} for plain stringification, or literal text with each {value} substituted.
gridbooleanfalseDraw grid lines.
colorColorthe theme's chart axis colorAxis / tick color.
grid_colorColorthe theme's chart grid colorGrid-line color.

PlotArea:legend

method
PlotArea:legend(options: chart.LegendOptions) -> Legend

Add a legend.

Example
plot:legend({
    items = {
        { label = "North", color = color("#e69875") },
        { label = "South", color = color("#7fbbb3") },
    },
    anchor = "top_left",
})

options chart.LegendOptions options 10 keys

KeyTypeDefaultDescription
kind"items" | "gradient""items"Legend form; a gradient legend renders color_scale's ramp with its domain bounds as labels.
color_scaleColorScalethe call raises for a gradient legendColor scale rendered as the gradient ramp; an items legend rejects it. A pending domain renders once its fit lands.
itemschart.LegendItem[] | stringthe area's named marksLegend entries array, or "auto". Only applies to items legends.
posVec2the anchor cornerPanel position.
anchor"top_left" | "top_right" | "bottom_left" | "bottom_right" | "top_center" | "bottom_center""top_right"Corner / edge the legend anchors to.
orientation"vertical" | "horizontal""vertical"Stack direction of legend items.
backgroundColorthe theme's legend backgroundPanel background color.
borderColorthe theme's legend borderPanel border color.
colorColorthe theme's legend text colorItem label color.
font_sizenumber | stringthe theme's small text sizeSize of the item labels, or of a gradient legend's value labels — a number (px) or a unit string like "1.5rem"/"50vw". Swatches, row height, and panel padding scale with it.

PlotArea:update

method
PlotArea:update(options: chart.PlotAreaUpdateOptions)

Update the area geometry, scales, or background in place. Pass background = color(...) to pin a concrete fill, or background = false to opt back into the theme default.

Example
-- A margin table's sides are pixels; a side left out is 0.
plot:update({
    margin = { left = 80, top = 80 },
    background = color("#dbbc7f"),
})

options chart.PlotAreaUpdateOptions options 7 keys Omitted keys keep their current value.

KeyTypeDescription
posVec2Area position within the canvas.
widthnumberArea width.
heightnumberArea height.
marginnumber | tableInner margin: a {top, right, bottom, left} table, whose omitted sides are 0.
x_scaleScaleReplacement x scale.
y_scaleScaleReplacement y scale.
backgroundColor | booleanFill color to pin, or false to opt back into the theme default.

PlotArea:world_to_data

method
PlotArea:world_to_data(pos: Vec2) -> chart.DataPos?

Canvas coord → data coord using current scales. Exact for time scales (full-precision epoch-ms).

Example
-- Canvas pixels, y up, to data. The margins put the center of the
-- inner rect at x = 12.
plot:line({ points = { vec2(0, 0), vec2(100, 10) } })
-- The scales fit the line when the frame ends.
datumhue.time.wait_frames(1)
local mid = plot:world_to_data(vec2(12, 0))
print(mid.x, mid.y) --> 50.0 5.0

returns chart.DataPos options 2 keys

KeyTypeDefaultDescription
x requirednumberno defaultData-space x. Exact for time scales (full-precision epoch-ms).
y requirednumberno defaultData-space y.

PlotArea:data_to_world

method
PlotArea:data_to_world(pos: Vec2 | chart.DataPos) -> Vec2?

Data coord → canvas coord. An {x, y} table keeps a time-scale x exact (a vec2's single-precision x rounds epoch-ms first).

Example
-- Data to canvas pixels; an {x, y} table keeps a time x exact.
plot:line({ points = { vec2(0, 0), vec2(100, 10) } })
datumhue.time.wait_frames(1)
print(plot:data_to_world({ x = 100, y = 10 })) --> vec2(184.0, 110.0)

pos chart.DataPos options 2 keys

KeyTypeDefaultDescription
x requirednumberno defaultData-space x. Exact for time scales (full-precision epoch-ms).
y requirednumberno defaultData-space y.

PlotArea:rescale

method
PlotArea:rescale(opts?: chart.RescaleOptions)

Clear both scale domains and refit against only currently-visible marks. Scales the user has pinned with pan / zoom / box-zoom are left alone. Pass {force = true} to always refit, matching the double-click-reset gesture.

Example
-- Refits both domains to the marks still shown.
plot:line({ points = { vec2(0, 1), vec2(4, 2) } })
local high = plot:line({ points = { vec2(0, 8), vec2(4, 9) } })
datumhue.time.wait_frames(1)
high.visible = false
plot:rescale({ force = true })
datumhue.time.wait_frames(1)
print(plot.y_scale.domain.min, plot.y_scale.domain.max) --> 1.0 2.0

opts chart.RescaleOptions options 1 key

KeyTypeDefaultDescription
forcebooleanfalseAlways refit, even over scales the user has pinned with pan / zoom.

PlotArea:title

method
PlotArea:title(options: chart.TitleOptions)

Pin a title to the plot area. One title per area — re-calling replaces any prior title. Auto-repositions on area resize. Raises if the plot area was removed.

Example
-- The title sits in the top margin; a second call replaces it.
plot:title({ text = "Loaves sold", font_size = 18, align = "center" })

options chart.TitleOptions options 8 keys

KeyTypeDefaultDescription
textstring""Title text.
font_sizenumber | string20Font size — a number (px) or a unit string like "1.5rem"/"50vw".
font_weightnumber | "thin" | "extralight" | "light" | "regular" | "normal" | "medium" | "semibold" | "bold"the heading weightTitle weight on the brand font's variable axis.
font_style"normal" | "italic" | "oblique"the upright faceTitle face.
colorColorthe theme's chart-label color, restyled on a theme switchTitle color.
side"top" | "bottom""top"Edge the title sits on.
align"left" | "center" | "right""left"Horizontal alignment.
insetnumber10Inset from the edge.

PlotArea:remove_title

method
PlotArea:remove_title()

Remove the plot area's title (if any).

PlotArea:crosshair

method
PlotArea:crosshair(options?: chart.CrosshairOptions) -> Crosshair

Draw a hover crosshair: guide lines at the cursor, a readout text with the cursor's data-space x/y, and dots + labels at every line / area mark's y(cursor.x). Overlays redraw each frame; nothing persists when the cursor leaves the plot area. One crosshair per area — raises while one is active; update or remove it instead.

Example
-- Guide lines and a readout follow the pointer over the area.
plot:line({ points = { vec2(0, 1), vec2(8, 3) } })
plot:crosshair({ readout = true, line_color = color("#e67e80") })

options chart.CrosshairOptions options 5 keys

KeyTypeDefaultDescription
linesbooleantrueDraw the crosshair lines.
line_colorColorthe theme's chart axis color at 35% opacityCrosshair line color.
readoutbooleantrueShow the value readout.
readout_colorColorthe theme's chart axis-label colorReadout text color.
mark_valuesbooleantrueHighlight nearest mark values.

PlotArea:pan_zoom

method
PlotArea:pan_zoom(options?: chart.PanZoomOptions) -> PanZoom

Enable built-in pan / zoom / box-zoom / double-click-reset interaction on the plot area. Works on linear, log, and time scales; band scales are skipped. Data-bound marks re-downsample at every zoom so detail stays pixel-faithful at any zoom level. One per area — raises while one is active; update or remove it instead.

Example
-- Pans and zooms x only, with the right-drag box zoom turned off.
plot:pan_zoom({ y = false, box_zoom_button = false })

options chart.PanZoomOptions options 8 keys

KeyTypeDefaultDescription
xbooleantruePan / zoom the x axis.
ybooleantruePan / zoom the y axis.
pan_button"left" | "right" | "middle" | "back" | "forward" | boolean"left"Drag button for panning, or false to disable.
zoombooleantrueEnable scroll-wheel zoom.
zoom_stepnumber0.8Zoom step per scroll tick.
box_zoom_button"left" | "right" | "middle" | "back" | "forward" | boolean"right"Drag button for box-zoom, or false to disable.
double_click_resetbooleantrueReset view on double-click.
double_click_msnumber300Double-click window in milliseconds.

PlotArea:brush

method
PlotArea:brush(options?: chart.BrushOptions) -> Brush

Enable a brush selection gesture on the plot area. Dragging sweeps a tinted selection region; releasing delivers the selection's data-space bounds to on_brush, and a plain click clears the selection and delivers nil. The selection region persists until cleared, replaced, or the brush is removed. One brush per area — raises while one is active; update or remove it instead.

Example
-- on_brush gets the bounds in data units, or nil when a click
-- clears the selection.
plot:brush({
    axis = "x",
    on_brush = function(selection)
        if selection then
            print(selection.x_min, selection.x_max)
        end
    end,
})

options chart.BrushOptions options 4 keys

KeyTypeDefaultDescription
axis"x" | "y" | "both""x"Which axes the brush selects on. Single-axis brushes span the full plot on the other axis.
button"left" | "right" | "middle" | "back" | "forward""left"Mouse button that drags the brush.
colorColordatumhue.color(0.4, 0.55, 0.9, 0.25)Selection region fill.
on_brushfun(selection: chart.BrushSelection?)no defaultFires when a selection commits (bounds table) or a click clears it (nil).

PlotArea:on_hover

method
PlotArea:on_hover(fn: fun(data_pos: chart.DataPos))

Register a callback fired every frame the cursor is inside the plot area's inner rect, with the cursor in data space (exact for time scales). Pass nil to clear.

PlotArea:on_click

method
PlotArea:on_click(fn: fun(data_pos: chart.DataPos, button: input.MouseButton))

Fire a callback on mouse-button release inside the area's inner rect, with the cursor in data space (exact for time scales). Pass nil to clear.

PlotArea:value_at

method
PlotArea:value_at(x: number) -> chart.MarkValue[]

Y-value at data-space x for each line / area mark on this area. Rows match the mark's readout setting. Empty if no mark has a value at x.

Example
-- The y of each line or area mark at x, in data units.
plot:line({ points = { vec2(0, 1), vec2(10, 3) }, name = "North" })
datumhue.time.wait_frames(1)
local values = plot:value_at(5)
print(#values, values[1].name, values[1].value) --> 1 North 2.0

returns chart.MarkValue record 5 keys

KeyTypeDescription
markMarkThe mark this value belongs to.
xnumberData-space x (the sample x for nearest readouts, the query x for interpolate).
valuenumberThe mark's y-value at x.
colorColorThe mark's color.
name?stringThe mark's name, when set.

PlotArea:mouse_data_position

method
PlotArea:mouse_data_position() -> chart.DataPos?

The cursor in data space. Exact for time scales (full-precision epoch-ms). nil when the cursor is outside the plot area's inner rect, or while either scale's domain is pending.

returns chart.DataPos options 2 keys

KeyTypeDefaultDescription
x requirednumberno defaultData-space x. Exact for time scales (full-precision epoch-ms).
y requirednumberno defaultData-space y.

PlotArea:cursor

method
PlotArea:cursor() -> chart.CursorInfo?

The cursor in data and canvas space, with whether it is inside the area. Unlike mouse_data_position, returns a value even when the cursor is outside the area. nil when the cursor is not over the canvas, or while either scale's domain is pending.

returns chart.CursorInfo record 3 keys

KeyTypeDescription
datachart.DataPosCursor in data space. Exact for time scales (full-precision epoch-ms).
worldVec3Cursor in canvas space.
in_areabooleanWhether the cursor is inside the plot area's inner rect.

PlotArea:clear

method
PlotArea:clear()

Remove the area's content — every mark (line / points / bars / area / rule / text / band / histogram / heatmap / box), axis, legend, group, and its title. The area keeps its background, interaction overlays, and scales; the canvas survives.

PlotArea:group

method
PlotArea:group(marks: table) -> ChartGroup

Bundle a set of mark handles for synchronized visibility toggles and lifecycle. Not a hierarchy — marks render where they were created. Raises if the plot area was removed.

Example
-- Hiding the group hides both lines.
local north = plot:line({ points = { vec2(0, 1), vec2(8, 3) } })
local south = plot:line({ points = { vec2(0, 2), vec2(8, 1) } })
local both = plot:group({ north, south })
both.visible = false
print(north.visible, south.visible) --> false false

PlotArea:remove

method
PlotArea:remove()

Destroy the plot area and everything on it — marks, axes, legends, groups, its title and overlays, and the scales it created for itself. The canvas survives.

Types 23

chart.AxisSide

enum
ValueDescription
"bottom"
"left"
"top"
"right"

Nested in: chart.AxisOptions

chart.BandAxis

enum
ValueDescription
"x"
"y"

Nested in: chart.BandMarkOptions

chart.BarsAggregate

enum
ValueDescription
"sum"
"mean"
"min"
"max"
"count"

Nested in: chart.BarsMarkOptions

chart.BarsMode

enum
ValueDescription
"stacked"
"grouped"

Nested in: chart.BarsMarkOptions

chart.BoxEntry

options

options 7 keys

KeyTypeDefaultDescription
category requiredstringno defaultCategory the summary belongs to.
low requirednumberno defaultLower whisker end.
q1 requirednumberno defaultFirst quartile.
median requirednumberno defaultMedian.
q3 requirednumberno defaultThird quartile.
high requirednumberno defaultUpper whisker end.
outliersnumber[]no outlier pointsPoints beyond the whiskers.

Nested in: chart.BoxMarkOptions

chart.BrushAxis

enum
ValueDescription
"x"
"y"
"both"

Nested in: chart.BrushOptions

chart.BrushOptions

options

options 4 keys

KeyTypeDefaultDescription
axis"x" | "y" | "both""x"Which axes the brush selects on. Single-axis brushes span the full plot on the other axis.
button"left" | "right" | "middle" | "back" | "forward""left"Mouse button that drags the brush.
colorColordatumhue.color(0.4, 0.55, 0.9, 0.25)Selection region fill.
on_brushfun(selection: chart.BrushSelection?)no defaultFires when a selection commits (bounds table) or a click clears it (nil).

Used by: PlotArea:brush, Brush:update

chart.CrosshairOptions

options

options 5 keys

KeyTypeDefaultDescription
linesbooleantrueDraw the crosshair lines.
line_colorColorthe theme's chart axis color at 35% opacityCrosshair line color.
readoutbooleantrueShow the value readout.
readout_colorColorthe theme's chart axis-label colorReadout text color.
mark_valuesbooleantrueHighlight nearest mark values.

Used by: PlotArea:crosshair, Crosshair:update

chart.DataMarkBase

options

options 11 keys

KeyTypeDefaultDescription
pointstablethe data or view sourceInline points, an array of vec2s.
dataDataHandlethe points or view sourceBind to a tabular data source.
viewDataViewthe points or data sourceBind to a streaming data view.
x_columnstringthe call raises with dataX column name of a data source.
y_columnstringthe call raises with dataY column name of a data source.
x_scaleScalethe area's x scaleX scale.
y_scaleScalethe area's y scaleY scale.
colorColorthe theme's chart-label color, restyled on a theme switchMark color.
namestringno name; automatic legends skip the markLegend name.
max_pointsintegerevery point is keptMost points an inline-points mark keeps: past it, each Mark:push_point drops the oldest.
on_errorfunctionno defaultCalled when the data source fails to load.

Extended by: chart.AreaMarkOptions, chart.LineMarkOptions, chart.PointsMarkOptions

chart.DataPos

options

options 2 keys

KeyTypeDefaultDescription
x requirednumberno defaultData-space x. Exact for time scales (full-precision epoch-ms).
y requirednumberno defaultData-space y.

Used by: Mark:nearest, Mark:push_point, PlotArea:world_to_data, PlotArea:data_to_world, PlotArea:on_hover, PlotArea:on_click, PlotArea:mouse_data_position

Nested in: chart.CursorInfo

chart.HeatAggregate

enum
ValueDescription
"count"
"sum"
"mean"

Nested in: chart.HeatmapMarkOptions

chart.Histogram2dNormalize

enum
ValueDescription
"count"
"fraction"

Nested in: chart.Histogram2dMarkOptions

chart.HistogramNormalize

enum
ValueDescription
"count"
"fraction"
"density"

Nested in: chart.HistogramMarkOptions

chart.LegendAnchor

enum
ValueDescription
"top_left"
"top_right"
"bottom_left"
"bottom_right"
"top_center"
"bottom_center"

Nested in: chart.LegendOptions, chart.LegendUpdateOptions

chart.LegendItem

options

options 2 keys

KeyTypeDefaultDescription
label requiredstringno defaultThe item's label text.
colorColordatumhue.color(1, 1, 1)The item's swatch color.

Nested in: chart.LegendOptions

chart.LegendKind

enum
ValueDescription
"items"
"gradient"

Nested in: chart.LegendOptions

chart.Orientation

enum
ValueDescription
"vertical"
"horizontal"

Nested in: chart.BarsMarkOptions, chart.BoxMarkOptions, chart.LegendOptions, chart.LegendUpdateOptions, chart.RuleMarkOptions

chart.PanZoomOptions

options

options 8 keys

KeyTypeDefaultDescription
xbooleantruePan / zoom the x axis.
ybooleantruePan / zoom the y axis.
pan_button"left" | "right" | "middle" | "back" | "forward" | boolean"left"Drag button for panning, or false to disable.
zoombooleantrueEnable scroll-wheel zoom.
zoom_stepnumber0.8Zoom step per scroll tick.
box_zoom_button"left" | "right" | "middle" | "back" | "forward" | boolean"right"Drag button for box-zoom, or false to disable.
double_click_resetbooleantrueReset view on double-click.
double_click_msnumber300Double-click window in milliseconds.

Used by: PlotArea:pan_zoom, PanZoom:update

chart.ReadoutMode

enum
ValueDescription
"interpolate"
"nearest"

Nested in: chart.AreaMarkOptions, chart.LineMarkOptions

chart.TextAnchor

enum
ValueDescription
"center"
"top_left"
"top_center"
"top_right"
"center_left"
"center_right"
"bottom_left"
"bottom_center"
"bottom_right"

Nested in: chart.TextMarkOptions

chart.TextPos

options

options 2 keys

KeyTypeDefaultDescription
x requirednumber | stringno defaultAnchor x — a data value, or a category name on a band x scale.
y requirednumber | stringno defaultAnchor y — a data value, or a category name on a band y scale.

Nested in: chart.TextMarkOptions

chart.TitleAlign

enum
ValueDescription
"left"
"center"
"right"

Nested in: chart.TitleOptions

chart.TitleSide

enum
ValueDescription
"top"
"bottom"

Nested in: chart.TitleOptions

datumhue.com

(c) 2026 Shuusei AB. Quote excerpts of this manual, with attribution to DatumHue, in your own documentation, tutorials, course materials, reviews, and other writing or video. Republishing it in whole or in substantial part needs written permission: support@datumhue.com.

Victor Mono is licensed under the SIL Open Font License 1.1
Copyright (c) 2024, Rune Bjørnerås (https://github.com/rubjo)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Try

    ↑↓ selectEnter openTab filter

    Settings

    Theme
    Text
    Print

    Keyboard shortcuts

    / or Ctrl KSearch
    ↑ ↓ EnterPick a result
    TabNext result filter
    j kNext or previous entry
    [ ]Previous or next page
    yCopy a link to the current entry
    ?These shortcuts
    EscClose

    On this page