OpenIslands

Charts

A family of islands for shape, comparison, distribution, and geography — lines and bars, parts of a whole, scatter and radar, heatmaps, funnels, and a world map.

A family of islands for shape, comparison, distribution, and geography: lines and bars, parts of a whole, scatter and radar, heatmaps and a calendar, funnels, and a world map. Each preview below is a real OpenIslands renderer running the same code a live dashboard uses. For the full registry, see Islands.

timeseries.line

A line chart over time, the island for trends. y may be a single field or an array of fields, so one tile can track several measures at once; add a goal line with options.goalField. When two or more series render, a legend with each series' latest value appears beneath the chart.

manifest.json
{
  "type": "timeseries.line",
  "title": "Revenue vs target",
  "dataset": "monthly",
  "x": "month",
  "y": ["revenue_eur", "expenses_eur"],
  "options": { "goalField": "target_eur" },
  "format": "eur"
}
  • x: the date/time field; accepts YYYY-MM, YYYY-Www, YYYY-MM-DD, or a real timestamp (required).
  • y: a numeric field, or an array of fields for a multi-line chart (required).
  • series: split one y field into a line per distinct value; many values auto-show a searchable picker (options.seriesPicker forces or disables it).
  • options.goalField: a column drawn as a neutral goal line; options.area fills under the lines.
  • colors: CSS colors per y field (or per series value), overriding the palette; format styles the axis and tooltips.

Tip

With many series values, pass series and let the picker keep the chart legible: it draws one series at a time instead of crowding every line onto the canvas.

category.bar

A bar chart across discrete categories, the island for comparing groups. Add group for a bar per subgroup, and stacked: true to stack those subgroups into one bar per category.

manifest.json
{
  "type": "category.bar",
  "title": "Spend by category",
  "dataset": "spend",
  "x": "category",
  "y": "amount_eur",
  "group": "quarter",
  "format": "eur"
}
  • x: the category field (required); y: the numeric field (required).
  • group: a field that splits each category into a bar per distinct value.
  • stacked: true stacks the grouped bars into one bar per category (default false).
  • colors: CSS colors per series (group value or y field), overriding the palette.

category.combo

A dual-axis chart: bars on the primary y-axis and lines on a secondary one, the island for reading a level against a rate. Plot revenue against margin, volume against price, or any two measures whose scales would flatten each other on a shared axis. Both bars and lines accept a single field or an array.

manifest.json
{
  "type": "category.combo",
  "title": "Revenue vs. margin",
  "dataset": "monthly",
  "x": "month",
  "bars": "revenue_eur",
  "lines": "margin_pct",
  "format": "eur",
  "lineFormat": "pct"
}
  • x: the category or date field (required); accepts a category label or any date the bar chart understands.
  • bars: a numeric field, or an array of fields, drawn as bars on the primary y-axis (required).
  • lines: a numeric field, or an array of fields, drawn as lines on the secondary y-axis (required).
  • stacked: true stacks the bar series into one bar per category (default false).
  • colors: CSS colors per series (bars first, then lines), overriding the palette.
  • format / lineFormat: value formats for the bar (primary) and line (secondary) axes.

waterfall.bars

A waterfall, or bridge, chart: an opening anchor, signed +/ steps that float on the running total, and closing anchors. Reach for it to walk a P&L (revenue down to profit), explain a variance, or bridge an opening balance to a closing one. Mark each anchor row by setting its kind field to "total"; every other row is a signed delta. The running-total math lives in the renderer, so the dataset stays a flat list of (step, delta, kind) rows.

manifest.json
{
  "type": "waterfall.bars",
  "title": "Operating profit bridge",
  "dataset": "pnl_bridge",
  "label": "step",
  "value": "amount_eur",
  "kind": "kind",
  "format": "eur"
}
  • label: the step-name field on the x axis (required); value: the signed delta per step, or the absolute level for a total row (required).
  • kind: a field marking anchor rows — a row whose value here is "total" draws as an absolute bar from zero (opening, closing, or a subtotal). Omit it to make every row a delta.
  • colors: per-tone CSS colors overriding the defaults (increase green, decrease red, total neutral grey) — e.g. { "increase": "#16a34a", "decrease": "#dc2626" }.
  • format styles the y axis and the per-step tooltip, which shows each step's signed value.

divergence.bars

A diverging bar chart: one signed bar per category or day, extending above or below a zero baseline and colored by which value band it falls into. Reach for it to show deviation from a reference — a daily calorie surplus/deficit, budget variance, net cash flow, or a temperature anomaly. Pick it over category.bar when the values are signed and the up/down direction is the message, and over waterfall.bars when each bar stands on its own rather than accumulating into a running total. The island reads a pre-computed signed value; to diverge from a non-zero target, compute the delta in SQL.

manifest.json
{
  "type": "divergence.bars",
  "title": "Daily calorie delta",
  "dataset": "calorie_delta",
  "x": "day",
  "value": "delta",
  "buckets": [
    { "gte": 300, "color": "#16a34a", "label": "High surplus" },
    { "gte": 0, "lt": 300, "color": "#4ade80", "label": "Surplus" },
    { "gte": -500, "lt": 0, "color": "#fb923c", "label": "Deficit" },
    { "lt": -500, "color": "#ef4444", "label": "Large deficit" }
  ]
}
  • x: the category or date field — one bar per row (required); value: the signed numeric field, rising above the zero baseline when positive and dropping below it when negative (required). Rows with a null or non-numeric value are skipped.
  • buckets: color each bar by the band its value falls in, matched top-to-bottom with half-open bounds [gte, lt) (omit either bound for an open end). Give every bucket a label to show a legend; a value matching no band renders neutral grey. Omit buckets entirely for a default green-positive / red-negative two-tone.
  • format styles the y axis and the per-bar tooltip.

rank.list

A ranked Top-N list with proportional horizontal bars, the island for a leaderboard: top products, customers, errors, or movers. Rows are sorted by value, cut to limit, and each bar is sized against the largest in the visible set, so the list reads as a ranking at a glance.

manifest.json
{
  "type": "rank.list",
  "title": "Top products by revenue",
  "dataset": "product_revenue",
  "label": "product",
  "value": "revenue_eur",
  "secondary": "region",
  "sort": "descending",
  "limit": 5,
  "format": "eur"
}
  • label: the field naming each row (required); value: the numeric field rows are ranked by (required).
  • sort: descending (the default, largest first) or ascending to surface the smallest.
  • limit: the maximum number of rows shown (default 10).
  • secondary: an optional field shown beside each row's value (e.g. a region or owner).
  • color: a CSS color for the bars, overriding the default accent; format styles each row's value.

breakdown.treemap

A treemap of part-to-whole composition, the island for how a total splits across parts, optionally nested. Each leaf's area is proportional to its value; supply parent to group leaves under a hierarchy.

manifest.json
{
  "type": "breakdown.treemap",
  "title": "Portfolio allocation",
  "dataset": "portfolio",
  "label": "asset",
  "value": "value_eur",
  "parent": "class"
}
  • label: the field naming each leaf (required); value: the numeric field sizing it (required). Only positive values render.
  • parent: an optional field grouping leaves into a two-level hierarchy; omit it for a flat treemap.
  • colors: CSS colors cycled across the top-level nodes, overriding the palette.

category.pie

A pie, or a donut with donut: true, of one series' share across a handful of categories. Slices sum by label and sort largest-first; each shows its percentage and the tooltip carries the formatted value. Reach for a treemap instead when the parts nest or there are many of them.

manifest.json
{
  "type": "category.pie",
  "title": "Revenue by product",
  "dataset": "product_revenue",
  "label": "category",
  "value": "revenue",
  "donut": true,
  "format": "eur"
}
  • label: the field naming each slice (required); value: the numeric field sizing it (required). Slices sum by label; only positive values render.
  • donut: true cuts an inner radius (a donut); omit for a full pie.
  • colors: CSS colors per slice (largest-first), overriding the palette; format styles the tooltip values.

correlation.scatter

A scatter plot of two numeric fields, for exploring how they relate. Split points into colored series with series, and turn dots into bubbles by pointing size at a third field. The x/y fields (and their xFormat/format) drive the axes and the tooltip.

manifest.json
{
  "type": "correlation.scatter",
  "title": "Spend vs. conversions by channel",
  "dataset": "channel_performance",
  "x": "marketing_spend_eur",
  "y": "conversions",
  "series": "channel",
  "size": "customers",
  "label": "channel",
  "xFormat": "eur",
  "format": "int"
}
  • x, y: the numeric fields for the axes (both required); points with a non-numeric x or y are dropped.
  • series: splits points into one colored series per distinct value, with a legend.
  • size: a numeric field scaling each point into a bubble; omit for fixed-size dots.
  • label: names each point in the tooltip; colors overrides the per-series palette; xFormat/format style the x/y values.

distribution.heatmap

A matrix heatmap: one value across two categorical dimensions, each cell shaded on a continuous color scale. Reach for it to show day-by-hour activity, a cohort grid, or a correlation matrix. Pre-aggregate to one value per x/y cell in SQL; the renderer keeps the last value seen for a repeated cell.

manifest.json
{
  "type": "distribution.heatmap",
  "title": "Orders by weekday and hour",
  "dataset": "orders_by_hour",
  "x": "hour",
  "y": "weekday",
  "value": "orders",
  "format": "int"
}
  • x, y: the column and row category fields (both required); a cell sits at each x/y pair.
  • value: the numeric field shading each cell (required); the scale spans its range, and cell labels show for small grids.
  • colors: gradient stops overriding the default blues; format styles cells, tooltip, and the legend.

activity.calendar

A calendar heatmap of a daily value, GitHub-contributions style: each day is a cell shaded by its value, laid out in weeks across the months the data spans. Any parseable date works, and rows landing on the same day sum. Give it a half-width or wider tile.

manifest.json
{
  "type": "activity.calendar",
  "title": "Commits per day",
  "dataset": "commits",
  "date": "day",
  "value": "commits",
  "format": "int"
}
  • date: the day field; any parseable date or timestamp, bucketed to a UTC day (required).
  • value: a numeric field mapped to each day's color; same-day rows sum (required).
  • colors: gradient stops overriding the default blues; format styles the tooltip value.

funnel.steps

A funnel of sequential stages, for conversion or drop-off. Each stage's width is its share of the largest, so the narrowing reads as the fall-off between steps. By default the stages follow the row order; set sort to reorder them.

manifest.json
{
  "type": "funnel.steps",
  "title": "Signup conversion",
  "dataset": "signup_funnel",
  "label": "stage",
  "value": "users",
  "sort": "descending",
  "format": "int"
}
  • label: the stage-name field (required); value: the numeric count at each stage (required).
  • sort: none (the default, keeping row order), descending, or ascending.
  • colors: per-stage CSS colors overriding the palette; format styles the labels and tooltip.

compare.radar

A radar (spider) chart for comparing entities across several metrics at once. Each field in metrics becomes an axis, and each row becomes a polygon named by series. Share one max across every axis when the metrics are on a common scale (e.g. all 0-100 scores).

manifest.json
{
  "type": "compare.radar",
  "title": "Product comparison",
  "dataset": "product_scores",
  "metrics": ["performance", "price", "design", "support", "ecosystem"],
  "series": "product",
  "max": 100
}
  • metrics: the numeric fields that become the axes (at least one, required).
  • series: a field naming each row's polygon; omitted, polygons are numbered Series 1, 2, …
  • max: a fixed max shared by every axis; omitted, each axis maxes at its own metric's peak.
  • colors: per-polygon CSS colors overriding the palette; format styles the tooltip values.

map.choropleth

A geographic choropleth: regions shaded by a value on a continuous scale. The map ships as vendored GeoJSON, so it renders fully offline, with no tiles and no network. Each row's region must match the map's region name; for the built-in world map that is the English country name.

manifest.json
{
  "type": "map.choropleth",
  "title": "Revenue by country",
  "dataset": "revenue_by_country",
  "region": "country",
  "value": "revenue_eur",
  "format": "eur"
}
  • region: the field holding each row's region name, matching the map's names (required).
  • value: the numeric field shading each region (required); regions with no row stay neutral.
  • map: the registered map name (default world); colors overrides the gradient; format styles the tooltip and legend.

Tip

Region names must match the map exactly. The world map uses full English country names: United States of America (not "United States" or "USA"), United Kingdom, Russia, and so on. Normalize your data's names in SQL to match.

On this page