Skip to content

Commit 47e7350

Browse files
committed
fixes
1 parent 1207980 commit 47e7350

11 files changed

Lines changed: 6270 additions & 122 deletions

File tree

py-src/data_formulator/agents/agent_data_rec.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
| Regression | x, y, color, size, facet | regressionMethod ("linear","log","exp","pow","quad","poly"), polyOrder (2–10) |
7474
| Bar Chart | x, y, color, facet | cornerRadius (0–15) |
7575
| Grouped Bar Chart | x, y, group, facet | cornerRadius (0–15) |
76-
| Histogram | x, color, facet | binCount (5–50) |
7776
| Line Chart | x, y, color, strokeDash, facet | interpolate ("linear","monotone","step") |
7877
| Area Chart | x, y, color, facet | — |
7978
| Heatmap | x, y, color, facet | colorScheme ("viridis","blues","reds","oranges","greens","blueorange","redblue") |
@@ -87,9 +86,9 @@
8786
8887
**Critical chart rules:**
8988
- **Scatter Plot**: good default for relationships/correlations. Use config opacity (0.1–1.0) for dense data instead of encoding opacity.
90-
- **Regression**: automatically overlays a trend line — do NOT compute regression in Python.
91-
- **Histogram**: only needs x encoding; values are auto-binned.
92-
- **Bar Chart**: same-x rows are automatically stacked. Use Grouped Bar Chart for side-by-side (group channel, not color).
89+
- **Regression**: automatically overlays a trend line — do NOT compute regression in Python. Use color to get separate trend lines per group.
90+
- **Bar Chart**: x=categorical, y=quantitative (vertical bars). Swap x↔y for horizontal bars. For histograms/distributions, bin the data in the Python step. Same-x rows are auto-stacked.
91+
- **Grouped Bar Chart**: use the group channel (not color) for side-by-side bars.
9392
- **Line Chart**: use strokeDash to differentiate line styles (e.g. actual vs forecast).
9493
- **Pie Chart**: use "size" channel (not "theta") for the wedge values. Avoid when >7–8 categories.
9594
- **Lollipop Chart**: like bar but with dot+line — cleaner for ranked comparisons.

src/lib/agents-chart/core/compute-layout.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,48 @@ export function computeChannelBudgets(
687687
: minStepVal;
688688

689689
// --- 4. Per-channel budgets ---
690-
const maxXToKeep = Math.floor(maxSubplotW / xMinGroupStep);
691-
const maxYToKeep = Math.floor(maxSubplotH / yMinGroupStep);
690+
let maxXToKeep = Math.floor(maxSubplotW / xMinGroupStep);
691+
let maxYToKeep = Math.floor(maxSubplotH / yMinGroupStep);
692+
693+
// --- 5. Faceted-chart canvas cap ---
694+
// Each subplot's step-based width/height must fit in the (un-stretched)
695+
// canvas dimensions. Without this, a busy discrete axis produces
696+
// subplots wider than the canvas, causing clipping. Filtering values
697+
// yields narrower subplots; we then re-derive the facet grid so more
698+
// columns fit, reducing overall chart height.
699+
if (facetGrid) {
700+
const canvasXCap = Math.max(1, Math.floor(canvasSize.width / xMinGroupStep));
701+
const canvasYCap = Math.max(1, Math.floor(canvasSize.height / yMinGroupStep));
702+
703+
if (maxXToKeep > canvasXCap || maxYToKeep > canvasYCap) {
704+
maxXToKeep = Math.min(maxXToKeep, canvasXCap);
705+
maxYToKeep = Math.min(maxYToKeep, canvasYCap);
706+
707+
// Re-derive facet grid with the tighter subplot size.
708+
const colField = channelSemantics.column?.field;
709+
const rowField = channelSemantics.row?.field;
710+
const colCount = colField
711+
? new Set(data.map(r => r[colField])).size : 0;
712+
713+
if (colCount > 1 && !rowField) {
714+
const tighterW = canvasXCap * xMinGroupStep;
715+
const totalW = canvasSize.width * maxStretchVal - fixW;
716+
const totalH = canvasSize.height * maxStretchVal - fixH;
717+
const revisedMaxCols = Math.max(1, Math.floor(totalW / (tighterW + gap)));
718+
const revisedMaxRows = Math.max(1, Math.floor(
719+
totalH / ((options.minSubplotSize ?? 60) + gap),
720+
));
721+
const maxTotal = revisedMaxCols * revisedMaxRows;
722+
const effectiveCount = Math.min(colCount, maxTotal);
723+
const visRows = Math.ceil(effectiveCount / revisedMaxCols);
724+
const visCols = Math.ceil(effectiveCount / visRows);
725+
726+
facetGrid.columns = visCols;
727+
facetGrid.rows = visRows;
728+
facetGrid.maxColumnValues = maxTotal;
729+
}
730+
}
731+
}
692732

693733
const hasRow = !!channelSemantics.row?.field;
694734
const maxFacetColumns = facetGrid?.maxColumnValues ?? Infinity;

0 commit comments

Comments
 (0)