Skip to content

Refactor chart style factories: replace long style(...) signatures with grouped style blocks #415

@hdcodedev

Description

@hdcodedev

Problem

Most chart defaults expose very large style(...) factories (many positional/named args). This is getting hard to evolve and review, and increases API churn risk when adding new style options.

Goal

Introduce a project-wide style-factory shape that groups related options (for example: bars/lines, axes, labels, selection, interaction, view) instead of adding more flat parameters to each chart's style(...) function.

Current vs After (Example)

Current (flat factory with many parameters):

val style = BarChartDefaults.style(
    barColor = MaterialTheme.colorScheme.primary,
    barColors = colors,
    barAlpha = 0.8f,
    space = 10.dp,
    minValue = 0f,
    maxValue = 120f,
    minBarWidth = 10.dp,
    zoomControlsVisible = true,
    gridVisible = true,
    gridSteps = 4,
    gridColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.15f),
    gridLineWidth = 1f,
    axisVisible = true,
    axisColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.3f),
    axisLineWidth = 1f,
    xAxisLabelsVisible = true,
    xAxisLabelColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.75f),
    xAxisLabelSize = 11.sp,
    xAxisLabelMaxCount = 6,
    selectionLineVisible = true,
    selectionLineColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.6f),
    selectionLineWidth = 1f,
    yAxisLabelsVisible = true,
    yAxisLabelColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.75f),
    yAxisLabelSize = 11.sp,
    yAxisLabelCount = 5,
    chartViewStyle = ChartViewDefaults.style(),
)

After (grouped style blocks):

val style = BarChartDefaults.style(
    bars = BarVisualStyle(
        color = MaterialTheme.colorScheme.primary,
        colors = colors,
        alpha = 0.8f,
        space = 10.dp,
        minBarWidth = 10.dp,
    ),
    range = ValueRangeStyle(min = 0f, max = 120f),
    grid = GridStyle(
        visible = true,
        steps = 4,
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.15f),
        lineWidth = 1f,
    ),
    axis = AxisStyle(
        visible = true,
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.3f),
        lineWidth = 1f,
    ),
    xLabels = AxisLabelStyle(
        visible = true,
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.75f),
        size = 11.sp,
        maxCount = 6,
    ),
    yLabels = YAxisLabelStyle(
        visible = true,
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.75f),
        size = 11.sp,
        count = 5,
    ),
    selection = SelectionLineStyle(
        visible = true,
        color = MaterialTheme.colorScheme.primary.copy(alpha = 0.6f),
        lineWidth = 1f,
    ),
    interaction = InteractionStyle(zoomControlsVisible = true),
    chartViewStyle = ChartViewDefaults.style(),
)

Proposed Direction

  • Add grouped style blocks (small immutable config types) per chart family.
  • Keep chart-specific defaults (Histogram: contiguous bins + zero baseline) via defaults in those blocks.
  • Reuse shared Cartesian blocks across bar/line/histogram/stacked charts where possible.
  • Keep current APIs temporarily as forwarding overloads for compatibility.

Migration Plan

  1. Introduce new grouped API alongside current flat API.
  2. Forward old style(...) to new grouped API internally.
  3. Mark old flat signatures as deprecated with ReplaceWith.
  4. Remove old signatures in next major release window.

Notes

  • This issue intentionally targets a project-level style API direction, not only histogram.
  • Follow-up issues/PRs can split by chart family after design is agreed.

Alternatives Considered

  1. Grouped style blocks (recommended)
  • Pros: Better readability, easier extension, and reusable shared Cartesian config blocks.
  • Cons: Adds a few new config types.
  1. Keep flat style(...) and add a DSL builder
  • Pros: Nice call-site ergonomics.
  • Cons: Extra API surface and maintenance overhead (factory + DSL + docs/tests).
  1. Introduce one per-chart StyleSpec object
  • Pros: Fewer function parameters and straightforward migration.
  • Cons: Can become a large "god object" if not carefully split.
  1. Deep style inheritance/composition hierarchy
  • Pros: Maximum theoretical reuse.
  • Cons: Higher complexity and harder long-term API stability.

Recommendation

Proceed with grouped style blocks + forwarding deprecated overloads for existing flat style(...) APIs. This gives the best balance of ergonomics, compatibility, and migration safety.

Follow-up Scope (Optional)

  • Define shared Cartesian blocks for reuse across bar/line/histogram/stacked charts (GridStyle, AxisStyle, XLabelStyle, YLabelStyle, SelectionStyle).

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions