lodviz_core
Core visualization primitives and data structures for lodviz-rs — a pure-Rust, SVG-based data visualization library.
Features
- Tidy Data Model —
DataTable,DataRow, andFieldValuefor heterogeneous, column-oriented data - Grammar of Graphics — Declarative
EncodingandFieldtypes inspired by Vega-Lite - Scales —
LinearScale,BandScale, andOrdinalScalefor mapping data domains to screen ranges - LTTB Downsampling — Largest-Triangle-Three-Buckets algorithm for visually-preserving time-series reduction
- M4 Downsampling — Fast Min-Max-Min-Max algorithm for large OHLC/financial datasets
- Statistical Algorithms — KDE, box-plot stats, mean, median, percentiles
- ColorMap — Perceptually uniform color interpolation via Oklab; sequential palettes (Viridis, Plasma, Inferno, Magma, Cividis, Turbo, Grayscale) and diverging palettes (RdBu, PuOr, PiYG, BrBG)
- Beeswarm Layout — Deterministic jitter / greedy beeswarm placement for strip charts
- Sankey Layout — BFS column assignment + proportional node heights + cubic Bézier ribbons
- Chord Layout — Arc angles from flow totals + quadratic Bézier ribbon paths
- Contour Extraction — Marching squares iso-lines and iso-bands from 2-D scalar grids
- Theming —
ChartConfigand palette definitions reused across renderers - Accessibility — A11y primitives for screen-reader friendly SVG output
- WASM-compatible — Pure logic, no OS runtime dependencies
Installation
[]
= "0.2"
Usage
Working with data
use ;
let series = Series ;
let dataset = Dataset ;
LTTB downsampling
Reduce 10,000 points to 300 while preserving the visual shape:
use DataPoint;
use lttb_downsample;
let data: =
.map
.collect;
let reduced = lttb_downsample;
assert_eq!;
Scales
use LinearScale;
let scale = new;
let px = scale.map; // → 300.0
Encoding specification
use ;
let enc = new
.x
.y
.color;
Data Pipeline
lodviz_core accepts data at three levels of abstraction, from lowest to highest:
[1] Vec<DataPoint> ← raw Rust types, no parsing needed
[2] DataTable / DataRow ← tidy model, heterogeneous columns
[3] parse_csv(&str) ← CSV text → DataTable
Level 1 — Raw Rust types
The native input type for charts is Vec<DataPoint> (x/y as f64),
grouped into Series<DataPoint> and then Dataset.
No parsing, no extra allocation — construct data directly.
use ;
let series = new;
let dataset = from_series;
Dedicated types exist for specialised chart kinds:
| Type | Used by | DataTable conversion method |
|---|---|---|
Dataset (Vec<Series<DataPoint>>) |
LineChart, ScatterChart, AreaChart |
table.to_dataset(&enc) |
BarDataset |
BarChart |
table.to_bar_dataset(&enc) |
Vec<OhlcBar> |
CandlestickChart |
— |
Vec<WaterfallBar> |
WaterfallChart |
— |
GridData |
HeatmapChart, ContourChart |
table.to_grid_wide(label_col, value_cols) · table.to_grid_long(row_col, col_col, value_col, fill) |
Vec<StripGroup> |
StripChart |
table.to_strip_groups(group_col, value_col) |
SankeyData |
SankeyChart |
table.to_sankey(src_col, dst_col, value_col, color_col) |
ChordData |
ChordChart |
table.to_chord_matrix(label_col, value_cols) |
Level 2 — Tidy Data Model
When your data has heterogeneous columns (numbers, text, timestamps mixed),
use DataTable. Each row is a DataRow (HashMap<String, FieldValue>).
use ;
use ;
// Manual construction
let mut row: DataRow = new;
row.insert;
row.insert;
row.insert;
let table = from_rows;
// Define the encoding: which column maps to which axis / color channel
let enc = new.with_color;
// Convert to a chart-ready Dataset (auto group-by "region")
let dataset = table.to_dataset;
FieldValue supports implicit conversion from primitive Rust types:
let v: FieldValue = 3.14_f64.into; // Numeric
let v: FieldValue = "East".into; // Text
let v: FieldValue = true.into; // Bool
Level 3 — CSV parser
To load CSV (e.g. from an HTTP fetch in the browser), use parse_csv:
use parse_csv;
let csv = "\
month,value,region
1,420,North
2,380,South
3,510,North";
let table = parse_csv?;
// → same DataTable as Level 2, then apply encoding as above
Parser rules:
- First non-empty, non-comment (
#) line → header - Numeric cells →
FieldValue::Numeric(f64) - Non-numeric cells →
FieldValue::Text - Missing cells →
FieldValue::Null
Note: the parser accepts
&str. HTTP fetching and file I/O are the responsibility of the application — this crate contains no I/O.
Full pipeline
CSV &str
──parse_csv()──▶ DataTable
──to_dataset(&enc)──▶ Dataset
──lttb_downsample(n)──▶ Dataset (LOD)
──▶ SVG (lodviz_components)
Algorithm References
- LTTB: Sveinn Steinarsson (2013) — Downsampling Time Series for Visual Representation (PDF)
- M4: Uwe Jugel et al. (2014) — M4: A Visualization-Oriented Time Series Data Aggregation
- Oklab: Björn Ottosson (2020) — A perceptual color space for image processing (blog)
- Marching Squares: Lorensen & Cline (1987) — classic iso-contour extraction via 2×2 cell case table
License
MIT — see LICENSE