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
Today, 2D grouped charts render Y-series as side-by-side bars or lines within each X category. There is no way to show part-to-whole composition (stacked totals per X) in 2D mode.
Meanwhile, 3D charts already stack Z values on each (X, Y) cell via ECharts stack: 'z' in useBar3DChartOptions.ts. The 2D path has no equivalent — users who want stacked composition must leave vizb, misuse 3D, or use a heatmap (which answers a different question).
Common use case: sales.csv with -g region,category -p x,y — compare total revenue per region broken down by category, not just side-by-side category bars.
# Today: grouped side-by-side only
vizb bar sales.csv -g region,category -p x,y -o out.html
# Desired: one bar per region, categories stacked inside
vizb bar sales.csv -g region,category -p x,y --stack -o stacked.html
Proposed solution
Add an opt-in --stack boolean flag for 2D grouped bar and line charts (categorical x + y, no z). Default stays grouped (backward compatible).
Problem / use case
Today, 2D grouped charts render Y-series as side-by-side bars or lines within each X category. There is no way to show part-to-whole composition (stacked totals per X) in 2D mode.
Meanwhile, 3D charts already stack Z values on each
(X, Y)cell via EChartsstack: 'z'inuseBar3DChartOptions.ts. The 2D path has no equivalent — users who want stacked composition must leave vizb, misuse 3D, or use a heatmap (which answers a different question).Common use case:
sales.csvwith-g region,category -p x,y— compare total revenue per region broken down by category, not just side-by-side category bars.Proposed solution
Add an opt-in
--stackboolean flag for 2D grouped bar and line charts (categorical x + y, no z). Default stays grouped (backward compatible).Scope (v1)
--stack,--chart bar:stack,--chart line:stackFlag semantics
--stack(bool, default off)stackonBarConfigandLineConfigRequiresAxes("x", "y")ExcludesAxes("z")— skip flag with warning when z is present (3D owns stacking)scale=logandstack=true: skip stack with CLI warning (ECharts stacked bars/lines do not work on log axes)Rendering (core change ~6 lines in two composables)
No transform/builder changes — data shape is identical; only ECharts series config changes.
Bar —
ui/src/composables/charts/useBarChartOptions.ts, whenstackis true andhasYAxis:Line —
ui/src/composables/charts/useCategorySeriesChartOptions.ts(line grouped path):Labels, tooltip, sort
createTooltipConfigalready shows per-series values andΣ <xName>— works for stacks as-is.--show-labels): v1 = per-segment labels (ECharts default). Follow-up: total label on top segment only (mirrorcreate3DCellLabelfor 3D).Implementation checklist
Go
StackFlagininternal/charts/flag.goExcludesAxes("z")rule ininternal/charts/rules.goStack *booltointernal/charts/bar/bar.goandinternal/charts/line/line.gocmd/charts/bar/bar.goandcmd/charts/line/line.goUI
stack?: booleanonBarConfig/LineConfiginui/src/types/index.tsstack?: Ref<boolean>onBaseChartConfig; thread throughuseActiveChartShape,useChartOptions,ChartCard.vuestack: 'total'inuseBarChartOptions.tsstack: 'total'+areaStyle: {}inuseCategorySeriesChartOptions.ts(line only)StackControl.vue; entry infieldRegistry.ts(appliesTo: ['bar', 'line'],appliesOn: ['2D'], hidden whenrendering3D)setStackinuseSettingsStore.ts+ handler inSettingsPanel.vueTests
ApplyRules— stack kept for x+y, skipped for x+y+z and log+stackuseBarChartOptions/useCategorySeriesChartOptionsemitstack: 'total'when enabled--chart bar:stackround-trips through materialise (cmd/cli/pipeline_test.go)Docs
docs/src/content/docs/charts/bar.mdx— 2D stacked example + settings table rowdocs/src/content/docs/charts/line.mdx— same for stacked areaExample commands for docs:
Architecture (today vs proposed)
flowchart LR subgraph today [Today 2D] X1["X category"] --> G1["Bar A"] X1 --> G2["Bar B"] X1 --> G3["Bar C"] end subgraph stacked [With --stack] X2["X category"] --> S1["Segment A"] S1 --> S2["Segment B"] S2 --> S3["Segment C"] endKey files
internal/charts/bar/bar.gointernal/charts/line/line.gointernal/charts/flag.gointernal/charts/rules.goui/src/composables/charts/useBarChartOptions.tsui/src/composables/charts/useCategorySeriesChartOptions.tsui/src/composables/charts/useBar3DChartOptions.tsui/src/composables/settings/fieldRegistry.tsEdge cases (document, don't over-engineer)
Estimated diff
~15 files, ~200 lines — mostly plumbing; core render change is ~6 lines in two composables.
Alternatives considered
--stack-percentor similar); defer to v2.