Skip to content
This repository was archived by the owner on May 5, 2026. It is now read-only.

Commit f766f83

Browse files
noahgiftclaude
andcommitted
Update book documentation for Phase 3 examples
- charts.md: Added 7 new chart examples (scatter, heatmap, boxplot, area, donut, sparkline, multi-axis) - dashboard.md: Added 5 dashboard examples (performance, pipeline, infrastructure, research, alerts) - edge-cases.md: New chapter covering Unicode, RTL, numeric, slow data, cardinality, theming - data-management.md: New chapter for version history, lineage, batch upload - SUMMARY.md: Added new chapters to navigation - changelog.md: Updated test counts and feature list 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 9d5914b commit f766f83

7 files changed

Lines changed: 1075 additions & 113 deletions

File tree

book/src/SUMMARY.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,12 @@
9999
- [Hello World](./examples/hello-world.md)
100100
- [Counter App](./examples/counter-app.md)
101101
- [Dashboard](./examples/dashboard.md)
102+
- [Charts](./examples/charts.md)
103+
- [Edge Cases](./examples/edge-cases.md)
104+
- [Data Management](./examples/data-management.md)
102105
- [Fraud Detection Dashboard](./examples/fraud-detection.md)
103106
- [MNIST Explorer](./examples/mnist-explorer.md)
104107
- [Data Table](./examples/data-table.md)
105-
- [Charts](./examples/charts.md)
106108
- [Model Card Display](./examples/model-card-display.md)
107109

108110
# Development Guide

book/src/appendix/changelog.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ PATCH - Bug fixes (backward compatible)
2424
| Canvas2D fallback | Software rendering for non-WebGPU browsers |
2525
| Hot reload | Live reload during development with WebSocket |
2626
| Chart primitives | Interpolation, Bezier curves, arc geometry, histogram binning |
27+
| Chart examples | Scatter/bubble, heatmap, boxplot, area stacked, donut, sparkline, multi-axis |
28+
| Dashboard examples | Performance monitoring, pipeline viz, infrastructure, research, alerts |
29+
| Edge case examples | Unicode/CJK, RTL, numeric edge cases, slow data, high cardinality, theming |
30+
| Data management | Model version history, dataset lineage tracking, batch upload preview |
2731
| Test fixtures | TAR-based fixture loading for integration tests |
2832
| BDD testing | `describe()`, `expect()`, `TestContext` for behavior specs |
2933
| Virtualization | Scroll virtualization for large lists (60fps at 100k items) |
@@ -40,7 +44,7 @@ PATCH - Bug fixes (backward compatible)
4044
| Area | Enhancement |
4145
|------|-------------|
4246
| Coverage | 91.18% line coverage, 94.97% function coverage |
43-
| Tests | 3,423 tests across workspace |
47+
| Tests | 3,463+ tests across workspace (194 new example tests) |
4448
| Lint | All clippy warnings resolved with targeted allows |
4549
| YAML | Expression executor with aggregations and transforms |
4650
| Quality | Grade system (F-A) with configurable gates |

book/src/examples/charts.md

Lines changed: 217 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,209 @@
11
# Charts
22

3-
Data visualization with Chart widget.
3+
Comprehensive data visualization with Chart widgets. Presentar provides a rich set of chart types with full test coverage.
44

55
## Chart Types
66

7-
| Type | Use Case |
8-
|------|----------|
9-
| Line | Trends over time |
10-
| Bar | Category comparison |
11-
| Pie | Part of whole |
12-
| Scatter | Correlation |
13-
| Area | Cumulative values |
7+
| Type | Use Case | Example |
8+
|------|----------|---------|
9+
| Line | Trends over time | `cht_sparkline` |
10+
| Bar | Category comparison | `cht_boxplot` |
11+
| Pie/Donut | Part of whole | `cht_donut` |
12+
| Scatter/Bubble | Correlation | `cht_scatter_bubble` |
13+
| Area | Cumulative values | `cht_area_stacked` |
14+
| Heatmap | 2D density | `cht_heatmap_basic` |
15+
| Multi-Axis | Dual metrics | `cht_multi_axis` |
1416

15-
## Basic Line Chart
17+
## Scatter Plot with Size (CHT-004)
1618

17-
```yaml
18-
widgets:
19-
- type: Chart
20-
chart_type: line
21-
data:
22-
- [0, 10]
23-
- [1, 20]
24-
- [2, 15]
25-
- [3, 30]
26-
x_label: "Time"
27-
y_label: "Value"
19+
Bubble charts map a third dimension to point radius:
20+
21+
```rust
22+
// From cht_scatter_bubble.rs
23+
pub struct BubbleChart {
24+
points: Vec<BubblePoint>,
25+
min_radius: f32,
26+
max_radius: f32,
27+
}
28+
29+
impl BubbleChart {
30+
pub fn size_to_radius(&self, size: f32) -> f32 {
31+
let (min_size, max_size) = self.size_range();
32+
if (max_size - min_size).abs() < 0.0001 {
33+
return (self.min_radius + self.max_radius) / 2.0;
34+
}
35+
let normalized = (size - min_size) / (max_size - min_size);
36+
self.min_radius + normalized * (self.max_radius - self.min_radius)
37+
}
38+
}
39+
```
40+
41+
Run: `cargo run --example cht_scatter_bubble`
42+
43+
## Heatmap (CHT-005)
44+
45+
2D heatmaps with colormap support:
46+
47+
```rust
48+
// From cht_heatmap_basic.rs
49+
pub enum Colormap {
50+
Viridis, Plasma, Inferno, Blues, Reds, Greens, Grayscale
51+
}
52+
53+
impl Colormap {
54+
pub fn map(&self, t: f32) -> Color {
55+
let t = t.clamp(0.0, 1.0);
56+
match self {
57+
Colormap::Viridis => {
58+
let r = 0.267 + t * (0.993 - 0.267);
59+
let g = 0.004 + t * (0.906 - 0.004);
60+
let b = 0.329 + t * (0.143 - 0.329);
61+
Color::new(r, g, b, 1.0)
62+
}
63+
// ... other colormaps
64+
}
65+
}
66+
}
67+
```
68+
69+
Run: `cargo run --example cht_heatmap_basic`
70+
71+
## Box Plot (CHT-006)
72+
73+
Statistical box plots with quartile calculation:
74+
75+
```rust
76+
// From cht_boxplot.rs
77+
pub struct BoxPlotStats {
78+
pub min: f32,
79+
pub q1: f32,
80+
pub median: f32,
81+
pub q3: f32,
82+
pub max: f32,
83+
pub mean: f32,
84+
pub outliers: Vec<f32>,
85+
}
86+
87+
impl BoxPlotStats {
88+
pub fn from_data(data: &[f32]) -> Option<Self> {
89+
// Calculates quartiles, IQR, and detects outliers
90+
// using 1.5 * IQR fence rule
91+
}
92+
93+
pub fn iqr(&self) -> f32 {
94+
self.q3 - self.q1
95+
}
96+
}
97+
```
98+
99+
Run: `cargo run --example cht_boxplot`
100+
101+
## Stacked Area Chart (CHT-007)
102+
103+
Area charts with proper stacking order:
104+
105+
```rust
106+
// From cht_area_stacked.rs
107+
impl StackedAreaChart {
108+
pub fn stacked_values(&self) -> Vec<Vec<f32>> {
109+
let n = self.data_points();
110+
let mut result = Vec::with_capacity(self.series.len());
111+
let mut cumulative = vec![0.0f32; n];
112+
113+
for series in &self.series {
114+
let mut stacked = Vec::with_capacity(n);
115+
for (i, &val) in series.values.iter().enumerate() {
116+
cumulative[i] += val;
117+
stacked.push(cumulative[i]);
118+
}
119+
result.push(stacked);
120+
}
121+
result
122+
}
123+
}
28124
```
29125

30-
## Bar Chart
126+
Run: `cargo run --example cht_area_stacked`
127+
128+
## Donut Chart (CHT-008)
129+
130+
Pie charts with configurable inner radius and center metric:
131+
132+
```rust
133+
// From cht_donut.rs
134+
pub struct DonutChart {
135+
segments: Vec<DonutSegment>,
136+
inner_radius_ratio: f32, // 0.0 = pie, 0.6 = donut
137+
center_label: Option<String>,
138+
center_value: Option<String>,
139+
}
140+
141+
impl DonutChart {
142+
pub fn segment_angles(&self, index: usize) -> Option<(f32, f32)> {
143+
// Returns (start_angle, end_angle) in radians
144+
// Starting at 12 o'clock (-π/2)
145+
}
146+
}
147+
```
148+
149+
Run: `cargo run --example cht_donut`
150+
151+
## Sparkline (CHT-009)
152+
153+
Compact inline charts for dashboards:
154+
155+
```rust
156+
// From cht_sparkline.rs
157+
impl Sparkline {
158+
pub fn render_inline(&self) -> String {
159+
let blocks = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
160+
self.values
161+
.iter()
162+
.map(|&v| {
163+
let normalized = self.normalize(v);
164+
let idx = ((normalized * 7.0).round() as usize).min(7);
165+
blocks[idx]
166+
})
167+
.collect()
168+
}
169+
170+
pub fn trend_percentage(&self) -> f32 {
171+
// Calculate percentage change from first to last value
172+
}
173+
}
174+
```
175+
176+
Run: `cargo run --example cht_sparkline`
177+
178+
## Multi-Axis Chart (CHT-010)
179+
180+
Dual y-axis for correlation visualization:
181+
182+
```rust
183+
// From cht_multi_axis.rs
184+
impl MultiAxisChart {
185+
pub fn correlation(&self) -> Option<f32> {
186+
// Calculates Pearson correlation coefficient
187+
// between left and right axis data
188+
}
189+
190+
pub fn normalize(&self, value: f32, axis: AxisSide) -> f32 {
191+
// Normalizes value to 0-1 range for specific axis
192+
}
193+
}
194+
```
195+
196+
Run: `cargo run --example cht_multi_axis`
197+
198+
## YAML Configuration
31199

32200
```yaml
33201
widgets:
34202
- type: Chart
35-
chart_type: bar
36-
data:
37-
- { label: "A", value: 30 }
38-
- { label: "B", value: 50 }
39-
- { label: "C", value: 20 }
40-
colors:
41-
- "#4285f4"
42-
- "#ea4335"
43-
- "#fbbc05"
203+
chart_type: line
204+
data: "{{ data.timeseries }}"
205+
x_label: "Time"
206+
y_label: "Value"
44207
```
45208
46209
## Data Binding
@@ -56,47 +219,44 @@ widgets:
56219
data: "{{ sales | select('date', 'revenue') }}"
57220
```
58221
59-
## Styling
222+
## Styling Options
60223
61224
| Property | Description |
62225
|----------|-------------|
63226
| `colors` | Series colors |
64227
| `grid` | Show grid lines |
65228
| `legend` | Legend position |
66229
| `axis_*` | Axis configuration |
230+
| `colormap` | Heatmap colormap |
67231

68-
## Responsive
232+
## Test Coverage
69233

70-
```yaml
71-
widgets:
72-
- type: Chart
73-
responsive: true
74-
aspect_ratio: 16:9
75-
```
234+
All chart examples include comprehensive tests:
235+
236+
| Example | Tests | Coverage |
237+
|---------|-------|----------|
238+
| cht_scatter_bubble | 6 | Bounds, sizing, transform |
239+
| cht_heatmap_basic | 7 | Colormap, normalization |
240+
| cht_boxplot | 7 | Quartiles, outliers |
241+
| cht_area_stacked | 8 | Stacking, percentages |
242+
| cht_donut | 9 | Angles, segments |
243+
| cht_sparkline | 11 | Trends, rendering |
244+
| cht_multi_axis | 8 | Correlation, normalization |
76245

77246
## Verified Test
78247

79248
```rust
80249
#[test]
81-
fn test_charts_data_point() {
82-
// Chart data point structure
83-
#[derive(Debug, PartialEq)]
84-
struct DataPoint {
85-
x: f32,
86-
y: f32,
87-
}
88-
89-
let points = vec![
90-
DataPoint { x: 0.0, y: 10.0 },
91-
DataPoint { x: 1.0, y: 20.0 },
92-
DataPoint { x: 2.0, y: 15.0 },
93-
];
94-
95-
assert_eq!(points.len(), 3);
96-
assert_eq!(points[1].y, 20.0);
250+
fn test_bubble_chart_radius() {
251+
let mut chart = BubbleChart::new(5.0, 25.0);
252+
chart.add_point(0.0, 0.0, 10.0, None);
253+
chart.add_point(100.0, 100.0, 50.0, None);
97254
98-
// Find min/max for axis scaling
99-
let max_y = points.iter().map(|p| p.y).fold(f32::MIN, f32::max);
100-
assert_eq!(max_y, 20.0);
255+
// Size 10 is minimum -> min radius
256+
assert_eq!(chart.size_to_radius(10.0), 5.0);
257+
// Size 50 is maximum -> max radius
258+
assert_eq!(chart.size_to_radius(50.0), 25.0);
259+
// Size 30 is middle -> middle radius
260+
assert_eq!(chart.size_to_radius(30.0), 15.0);
101261
}
102262
```

0 commit comments

Comments
 (0)