You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update DESIGN.md with all recent compare view features
Major documentation updates:
- Multi-group-by with auto-grouping and chip reordering
- Hierarchical group-by headers (pivot-table-like)
- Series-by removed (replaced by full auto-grouping)
- Click-to-pin with reference lines and bar dimming
- Per-sample metric selection
- Metric filter support (gt/ge/lt/le)
- Breakout chart type selector (bars/stacked/lines)
- Breakout sidebar table with rowSpan and text dedup
- Bar value labels with conditional display
- Supplemental panels below primary chart
- Hide fields feature
- Iteration-targeted supplemental metric queries
- Updated URL state format (groupBy as array, no seriesBy)
- Updated known limitations and planned features
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.**Hierarchical group headers**: Each group-by dimension gets its own row above the chart. Each row shows the dimension name on the left and value labels spanning the bars they cover, creating a pivot-table-like header.
279
+
3.**Bar labels** (X-axis): Only the remaining varying dimension(s) not used in group-by
280
+
4.**Bar value labels**: Metric values shown inside bars when they fit (checked against bar width and height). Hidden automatically when bars are too narrow.
281
+
5.**Value consolidation**: Params/tags with the same value are grouped in labels (e.g., `bs,rw,size=4k` instead of repeating `=4k` three times)
281
282
282
-
**Example:** If you group by `param:nthreads` and series by `tag:gro`:
283
-
- Subtitle: `benchmark=uperf, protocol=tcp` (common to all)
284
-
- Group headers: `nthreads=1` (with `wsize=64` if wsize is the same within that group), `nthreads=8`
285
-
- Bar labels: Only remaining varying dimensions (e.g., `wsize=256`)
286
-
- Legend: `gro=on` (blue), `gro=off` (green)
283
+
### Auto-Grouping
284
+
285
+
When entering the compare view, group-by dimensions are auto-populated:
286
+
1.`buildDimOptions()` scans iterations for varying dimensions only
287
+
2. Dimensions sorted by distinct value count (fewest first — best grouping levels)
288
+
3. All but the last dimension become group-by levels
289
+
4. The last dimension stays as the bar label
290
+
5. User can reorder chips with left/right arrow buttons
291
+
6. "Auto" button recomputes; "Clear" removes all
292
+
293
+
### Hide Fields
294
+
295
+
Users can hide specific params/tags from the compare view:
296
+
- Hidden fields excluded from group-by/series-by dropdowns, common/varying computation, and bar labels
297
+
- Shown as red strikethrough chips
298
+
- Hiding auto-removes from group-by if currently used
299
+
300
+
### Click-to-Pin and Selection Indicators
301
+
302
+
-**Click a bar** in the primary chart to pin its data in all sidebars
303
+
-**Red dashed ReferenceLine** appears at the selected bar's position in all chart panels
304
+
-**Non-selected bars dim to 20% opacity** across all panels
305
+
- Click the same bar again to unpin
287
306
288
307
### Grouping Implementation
289
308
290
309
1.`buildDimOptions()` scans iterations for varying dimensions only (>1 distinct value) — common dimensions are excluded from dropdowns
291
-
2. Iterations sorted by `naturalCompare` (numeric-aware: 64 before 256 before 1024)
292
-
3. Per-group common items computed: params/tags that vary globally but are constant within a group
293
-
4.`buildIterLabel()` excludes group-by dimension and per-group common items from bar labels
294
-
5. Gap entries (`{ isGap: true }`) inserted between groups for visual separation
295
-
6. Group headers rendered as proportionally-sized tabs above the chart using flex layout
310
+
2. Multi-group-by: `groupByList` is an array of dimension strings, compound key computed by `getCompoundGroupValue()`
311
+
3. Iterations sorted by compound group key using `naturalCompare` (numeric-aware: 64 before 256 before 1024)
312
+
4. Per-group common items computed: params/tags that vary globally but are constant within a group
313
+
5.`buildIterLabel()` excludes all group-by dimensions and per-group common items from bar labels; consolidates params with same value
314
+
6. Gap entries (`{ isGap: true }`) inserted between groups for visual separation
315
+
7. Hierarchical headers rendered inside `compare-chart-area` with matching chart margins
296
316
297
317
### Y-Axis Management
298
318
@@ -302,6 +322,7 @@ The chart applies a hierarchical approach to reduce label redundancy:
302
322
-**Alignment**: Hidden right Y-axis (width=80 or width=1) added to all charts so bars align across panels
303
323
-**HTML labels**: Y-axis metric names rendered as HTML `<div>` elements outside the SVG to avoid Recharts clip-path issues
304
324
-**Tick formatting**: `formatYTick()` adapts precision based on magnitude (e.g., "1.2k", "0.423", "80")
325
+
-**Sidebar**: Each chart panel has a sidebar (300px) showing pinned iteration values
305
326
306
327
---
307
328
@@ -319,21 +340,34 @@ The chart applies a hierarchical approach to reduce label redundancy:
319
340
320
341
Each added metric is displayed as a row with:
321
342
- Colored left border (consistent color across chart and panel)
322
-
- Metric name (source::type)
323
-
- Display mode label ("overlay" or "panel")
343
+
- Metric name (source::type) in monospace font
344
+
- Display mode badge ("overlay" or "panel")
324
345
-**+ Breakout** dropdown (populated with `remainingBreakouts` from server)
346
+
-**Chart type** selector (Bars, Stacked, Lines) — visible when breakouts are active
347
+
-**Sample** selector — choose which sample to display (auto-selects the sample closest to the primary metric mean)
4. Server also returns updated `remainingBreakouts` for further drilling
334
-
5. Chart renders one bar/line per label
366
+
5. Chart renders one bar/line per label; chart type selectable (Bars/Stacked/Lines)
335
367
6. User can add another breakout level (e.g., "hostname") — labels become `"<rx>-<host1>"`, etc.
336
-
7. Removing a breakout re-queries with the reduced breakout array
368
+
7. Breakout chips have editable filter inputs accepting exact values, `val1+val2`, `r/regex/`, or `R/regex/`
369
+
8. "Apply" button re-queries with the filter applied
370
+
9. Removing a breakout re-queries with the reduced breakout array
337
371
338
372
### Data Format
339
373
@@ -351,12 +385,40 @@ The empty string label `""` with no breakouts is correct — it means there's no
351
385
352
386
### Chart Rendering with Breakouts
353
387
354
-
**Panel mode:** Each label becomes its own `<Bar>` component with a distinct color.
388
+
**Panel mode:** Each label becomes its own `<Bar>` component with a distinct color. Chart type selectable:
389
+
-**Bars**: Side-by-side bars per breakout label
390
+
-**Stacked**: Bars stacked using Recharts `stackId`
391
+
-**Lines**: Line chart with dots per breakout label
355
392
356
393
**Overlay mode:** Each label becomes its own `<Line>` component on the right Y-axis.
357
394
395
+
**Supplemental panels render below the primary chart** so the primary chart with its X-axis labels appears first.
396
+
358
397
Label detection is done dynamically by scanning chart data entry keys for the pattern `supp_{index}_{label}` (excluding keys ending in `_stddevPct`, `_error`, `_samples`).
359
398
399
+
### Breakout Sidebar (Value Legend)
400
+
401
+
When a bar is clicked (pinned), each chart panel shows a sidebar with metric values:
402
+
403
+
-**No breakouts**: Simple label + value display
404
+
-**With breakouts**: Table layout with rowSpan for repeated segment values (like the iteration table's run grouping)
405
+
- Column headers from breakout dimension names
406
+
- Labels parsed into `<segment>` patterns and grouped hierarchically
407
+
- Common text suffixes stripped and shown in header (e.g., `.local.net` removed from hostnames)
408
+
- Common text prefixes stripped if no suffix found (e.g., `host-` removed)
409
+
- Numeric-only columns skip deduplication
410
+
- Delimiter-boundary detection (`.`, `-`, `_`, `/`) prevents splitting words
411
+
412
+
### Bar Value Labels
413
+
414
+
Metric values are displayed inside bars when they fit:
-`iterations`: array of `{iterationId, runId}` for targeted queries (avoids discovering all iterations from runIds)
560
+
-`sampleIndex`: which sample to query (client computes best sample from primary metric values)
561
+
-`breakout`: array of breakout dimensions with optional filters
562
+
-`filter`: value filter (gt:N, ge:N, lt:N, le:N)
563
+
564
+
Processing:
565
+
1. Uses provided iteration IDs directly (or discovers from runIds as fallback)
498
566
2. Gets primary period IDs and ranges
499
567
3. Builds metric data sets with the specified source, type, and breakouts
500
568
4. Calls `cdm.getMetricDataSets()` to fetch from OpenSearch
@@ -590,14 +658,14 @@ Primary metric values are NOT loaded with iteration details (would add ~7 second
590
658
### Current Limitations
591
659
592
660
-**Phase 3 (Deep Dive):** Time-series line charts are not yet implemented
593
-
-**Breakout filters:** Breakout dimensions can be selected but not filtered to specific values (e.g., `package=0`). The data structures support this for future implementation.
594
-
-**Panel alignment with overlays:** Slight misalignment can occur when one chart has an overlay right Y-axis and another doesn't, despite hidden Y-axis placeholders
595
661
-**Large result sets:** Searching across many months with hundreds of runs can be slow due to sequential OpenSearch queries
596
662
-**Bundle size:** Recharts adds ~400KB to the bundle. Code splitting could help.
663
+
-**Breakout label parsing:** CDM may omit breakout dimensions with single values from labels, making label-to-dimension mapping imperfect. The sidebar uses segment-based grouping to work around this.
664
+
-**Supplemental metric in URL state:** Currently supplemental metrics, breakouts, and hidden fields are not encoded in the Share URL
597
665
598
666
### Planned Features
599
667
600
-
-**Breakout value filters:** Allow `breakout=["package=0"]` to filter to specific breakout values
601
668
-**Deep Dive view:** Time-series line charts with zoom/pan and interactive breakout exploration
602
669
-**Save/load workflows:** Server-side or localStorage persistence of named workflows
603
-
-**Supplemental metric in URL state:** Currently supplemental metrics and breakouts are not encoded in the Share URL
670
+
-**Supplemental metrics in URL state:** Encode added metrics, breakouts, and display modes in the Share URL
671
+
-**Drag-to-reorder:** Group-by chips currently use arrow buttons; drag-and-drop would be more intuitive
0 commit comments