Skip to content

Feat: Add scrollable feature to row/column charts - #180

Open
ehsannarmani wants to merge 16 commits into
masterfrom
feat/scrollable-rc-charts
Open

Feat: Add scrollable feature to row/column charts#180
ehsannarmani wants to merge 16 commits into
masterfrom
feat/scrollable-rc-charts

Conversation

@ehsannarmani

@ehsannarmani ehsannarmani commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added configurable scrolling for column and row charts via scrollMode with Disabled, Auto, and Always behaviors.
    • Scrolling keeps axis/indicators stationary while bars and labels scroll within the chart viewport.
  • Updates
    • Improved label layout for scrollable charts, including smarter rotation control with a new Never rotation option.
    • Enhanced chart examples to showcase scrolling with larger datasets and spacing settings.
  • Documentation
    • Added new documentation for scrollMode, plus updated chart pages with usage snippets.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Chart scrolling and layout

Layer / File(s) Summary
Scrolling contracts and label geometry
compose-charts/.../models/ScrollMode.kt, compose-charts/.../utils/ScrollUtils.kt, compose-charts/.../utils/Labels.kt, compose-charts/.../models/LabelProperties.kt
Adds configurable scroll modes, computes chart sizing values, positions labels within scrollable dimensions, and adds a Never rotation mode.
Column chart scrolling
compose-charts/.../ColumnChart.kt, app/.../ColumnSample.kt
Adds horizontal scroll state, layered rendering, drag handling, and scroll-mode configurations for column chart samples.
Row chart scrolling
compose-charts/.../RowChart.kt, app/.../RowSample.kt
Adds vertical scroll state, layered rendering, drag handling, and automatic scrolling configuration for a row chart sample.
Scroll mode documentation
document/docs/chart-properties/scroll-mode.md, document/docs/charts/*.md, document/mkdocs.yml
Documents scrolling modes, spacing, interactions, examples, and the new documentation navigation entry.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Chart
  participant ScrollUtils
  participant ScrollState
  participant Labels
  Chart->>ScrollUtils: compute effective content size
  ScrollUtils-->>Chart: return scroll configuration
  Chart->>ScrollState: apply drag delta
  Chart->>Labels: render aligned axis labels
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding scrollable behavior to row and column charts.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/scrollable-rc-charts

Comment @coderabbitai help to get the list of available commands.

@ehsannarmani ehsannarmani changed the title Feat/scrollable rc charts Feat: Add scrollable feature to row/column charts Jul 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt (1)

442-447: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the no-op pointerInteropFilter.

The if body is empty and the filter always returns false, so this modifier does nothing but keep an Android-only MotionEvent dependency in the chain. Detekt flags the empty block.

🧹 Proposed cleanup
-        .pointerInteropFilter { event ->
-            if (event.action == MotionEvent.ACTION_DOWN && popupProperties.enabled) {
-
-            }
-            false
-        }

As per static analysis hints: "This empty block of code can be removed."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt`
around lines 442 - 447, Remove the no-op pointerInteropFilter modifier from the
RowChart modifier chain, including its empty ACTION_DOWN condition and
MotionEvent reference. Preserve all surrounding modifiers and behavior
unchanged.

Source: Linters/SAST tools

compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/Labels.kt (1)

165-187: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Make textMeasurer non-optional instead of silently falling back to a 0 px label height.

VerticalLabels is public API; when a caller omits textMeasurer, the offset branch still runs and every label is mis-centered by half a line height. A default rememberTextMeasurer() keeps the signature source-compatible and removes the bogus fallback (also lets you hoist the measurement out of the per-label loop).

♻️ Proposed change
-    textMeasurer: TextMeasurer? = null
+    textMeasurer: TextMeasurer = rememberTextMeasurer()
 ) {
-                        val labelHeight = textMeasurer?.measure(
-                            label,
-                            style = labelProperties.textStyle,
-                            maxLines = 1
-                        )?.size?.height?.toFloat()
-                            ?: 0f
+                        val labelHeight = textMeasurer.measure(
+                            label,
+                            style = labelProperties.textStyle,
+                            maxLines = 1
+                        ).size.height.toFloat()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/Labels.kt`
around lines 165 - 187, Update the public VerticalLabels API so textMeasurer
defaults to rememberTextMeasurer() and is non-null. Remove the nullable
safe-call and 0f fallback when calculating labelHeight, and reuse the non-null
measurer while preserving the existing label positioning behavior.
app/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ui/ColumnSample.kt (1)

124-224: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Copy-pasted "Feb" groups with identical values. Five extra bar groups all share the label "Feb" and the same Linux/Windows values, so the scroll demo shows indistinguishable bars. Consider generating the padding groups in a loop with distinct month labels (as ColumnSample3 does) instead of duplicating the literal.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ui/ColumnSample.kt`
around lines 124 - 224, Update the sample data in ColumnSample so the repeated
Bars groups are no longer identical: replace the duplicated "Feb" literals with
generated padding groups using distinct month labels and the intended varying
data, following the loop-based approach used by ColumnSample3. Preserve the
existing Bars.Data structure and colors while removing the copy-pasted groups.
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt (1)

459-463: 🩺 Stability & Availability | 🔵 Trivial | 🏗️ Heavy lift

scrollEnabled is a MutableState written during composition in both charts. The shared root cause is that chartPointerModifier is built before BoxWithConstraints knows the viewport size, so the scroll flag is smuggled back through snapshot state that is written while composing and read earlier in the same pass.

  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt#L459-L463: drop the MutableState at line 190 and pass scrollConfig.scrollEnabled into a pointer-modifier factory invoked here.
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt#L475-L479: apply the same change for the state declared at line 184.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`
around lines 459 - 463, Remove the locally declared scrollEnabled MutableState
and refactor chartPointerModifier to a factory that accepts
scrollConfig.scrollEnabled after viewport constraints are known. Apply this in
ColumnChart.kt lines 459-463 and RowChart.kt lines 475-479, passing the
configuration value directly at each site; update the corresponding declarations
around ColumnChart.kt line 190 and RowChart.kt line 184.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`:
- Around line 336-338: The Above zero-line branch is incorrectly gated by
shouldDrawGrid, preventing it from rendering in scroll mode. In ColumnChart.kt
lines 336-338 and RowChart.kt lines 319-321, update the conditions around
drawZeroLine() to use shouldDrawBars while preserving the existing
zeroLineProperties.enabled and ZType.Above checks.
- Line 114: Change the default scrollMode parameter in ColumnChart to
ScrollMode.Disabled, matching RowChart and preserving existing ColumnChart
rendering for callers that omit the argument.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/Labels.kt`:
- Around line 61-74: Update the label layout logic around labelWidths,
maxLabelWidth, and minLabelWidth to handle a minimum measured width of zero
before calculating shouldCompact or any rotation transform values. Skip
width-ratio-based compaction and ensure transformOrigin remains finite for empty
or whitespace-only labels, while preserving existing behavior for positive label
widths.

---

Nitpick comments:
In `@app/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ui/ColumnSample.kt`:
- Around line 124-224: Update the sample data in ColumnSample so the repeated
Bars groups are no longer identical: replace the duplicated "Feb" literals with
generated padding groups using distinct month labels and the intended varying
data, following the loop-based approach used by ColumnSample3. Preserve the
existing Bars.Data structure and colors while removing the copy-pasted groups.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`:
- Around line 459-463: Remove the locally declared scrollEnabled MutableState
and refactor chartPointerModifier to a factory that accepts
scrollConfig.scrollEnabled after viewport constraints are known. Apply this in
ColumnChart.kt lines 459-463 and RowChart.kt lines 475-479, passing the
configuration value directly at each site; update the corresponding declarations
around ColumnChart.kt line 190 and RowChart.kt line 184.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt`:
- Around line 442-447: Remove the no-op pointerInteropFilter modifier from the
RowChart modifier chain, including its empty ACTION_DOWN condition and
MotionEvent reference. Preserve all surrounding modifiers and behavior
unchanged.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/Labels.kt`:
- Around line 165-187: Update the public VerticalLabels API so textMeasurer
defaults to rememberTextMeasurer() and is non-null. Remove the nullable
safe-call and 0f fallback when calculating labelHeight, and reuse the non-null
measurer while preserving the existing label positioning behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 95a21f9f-6544-486e-8196-256688388dd3

📥 Commits

Reviewing files that changed from the base of the PR and between fd706e7 and f477a42.

📒 Files selected for processing (8)
  • app/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ui/ColumnSample.kt
  • app/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ui/RowSample.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/models/LabelProperties.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/models/ScrollMode.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/Labels.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/ScrollUtils.kt

barAlphaDecreaseOnPopup: Float = .4f,
maxValue: Double = data.maxOfOrNull { it.values.maxOfOrNull { it.value } ?: 0.0 } ?: 0.0,
minValue: Double = if (data.any { it.values.any { it.value < 0 } }) -maxValue else 0.0,
scrollMode: ScrollMode = ScrollMode.Auto(4.dp),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Default scrollMode is inconsistent with RowChart and silently changes behavior for existing callers.

ColumnChart defaults to ScrollMode.Auto(4.dp) while RowChart defaults to ScrollMode.Disabled (RowChart.kt line 116). With Auto, every existing ColumnChart usage switches to the new layered/scroll layout (separate indicator canvases, different label path) without opting in. Pick one default for both charts — Disabled preserves legacy rendering.

🔧 Proposed change
-    scrollMode: ScrollMode = ScrollMode.Auto(4.dp),
+    scrollMode: ScrollMode = ScrollMode.Disabled,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
scrollMode: ScrollMode = ScrollMode.Auto(4.dp),
scrollMode: ScrollMode = ScrollMode.Disabled,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`
at line 114, Change the default scrollMode parameter in ColumnChart to
ScrollMode.Disabled, matching RowChart and preserving existing ColumnChart
rendering for callers that omit the argument.

Comment on lines +336 to +338
if (shouldDrawGrid && zeroLineProperties.enabled && zeroLineProperties.zType == ZeroLineProperties.ZType.Above) {
drawZeroLine()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

ZeroLineProperties.ZType.Above is ignored in scroll mode in both charts. In both files the Above zero-line call is gated on shouldDrawGrid, which is false for the scrollable bars canvas, so the line is only ever painted by the grid layer underneath the bars.

  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt#L336-L338: gate the Above branch on shouldDrawBars rather than shouldDrawGrid.
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt#L319-L321: apply the same gating change.
📍 Affects 2 files
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt#L336-L338 (this comment)
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt#L319-L321
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`
around lines 336 - 338, The Above zero-line branch is incorrectly gated by
shouldDrawGrid, preventing it from rendering in scroll mode. In ColumnChart.kt
lines 336-338 and RowChart.kt lines 319-321, update the conditions around
drawZeroLine() to use shouldDrawBars while preserving the existing
zeroLineProperties.enabled and ZType.Above checks.

Comment on lines +61 to +74
val labelWidths = labelMeasures.map { it.size.width }
val maxLabelWidth = labelWidths.max()
val minLabelWidth = labelWidths.min()

var textModifier: Modifier = Modifier

val shouldCompact = (maxLabelWidth / minLabelWidth.toDouble()) >= 1.5 && labelProperties.rotation.degree != 0f
val shouldRotate = when(labelProperties.rotation.mode){
LabelProperties.Rotation.Mode.Force -> true
LabelProperties.Rotation.Mode.Never -> false
LabelProperties.Rotation.Mode.IfNecessary -> shouldCompact
}
if (shouldCompact) {
textModifier = textModifier.width((minLabelWidth / density.density).dp)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard against minLabelWidth == 0.

An empty (or whitespace-only) label measures 0 px, making line 67 produce Infinity/NaN and line 96's transformOrigin non-finite, which can blank out or crash the rotated label layer.

🛡️ Proposed guard
-            val minLabelWidth = labelWidths.min()
+            val minLabelWidth = labelWidths.min().coerceAtLeast(1)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
val labelWidths = labelMeasures.map { it.size.width }
val maxLabelWidth = labelWidths.max()
val minLabelWidth = labelWidths.min()
var textModifier: Modifier = Modifier
val shouldCompact = (maxLabelWidth / minLabelWidth.toDouble()) >= 1.5 && labelProperties.rotation.degree != 0f
val shouldRotate = when(labelProperties.rotation.mode){
LabelProperties.Rotation.Mode.Force -> true
LabelProperties.Rotation.Mode.Never -> false
LabelProperties.Rotation.Mode.IfNecessary -> shouldCompact
}
if (shouldCompact) {
textModifier = textModifier.width((minLabelWidth / density.density).dp)
val labelWidths = labelMeasures.map { it.size.width }
val maxLabelWidth = labelWidths.max()
val minLabelWidth = labelWidths.min().coerceAtLeast(1)
var textModifier: Modifier = Modifier
val shouldCompact = (maxLabelWidth / minLabelWidth.toDouble()) >= 1.5 && labelProperties.rotation.degree != 0f
val shouldRotate = when(labelProperties.rotation.mode){
LabelProperties.Rotation.Mode.Force -> true
LabelProperties.Rotation.Mode.Never -> false
LabelProperties.Rotation.Mode.IfNecessary -> shouldCompact
}
if (shouldCompact) {
textModifier = textModifier.width((minLabelWidth / density.density).dp)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/Labels.kt`
around lines 61 - 74, Update the label layout logic around labelWidths,
maxLabelWidth, and minLabelWidth to handle a minimum measured width of zero
before calculating shouldCompact or any rotation transform values. Skip
width-ratio-based compaction and ensure transformOrigin remains finite for empty
or whitespace-only labels, while preserving existing behavior for positive label
widths.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt (1)

304-305: 🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

Update hit rectangles by stable bar identity instead of Rect equality. During animation, each frame changes the rectangle, so barWithRect.none { it.rect == rect } appends another entry for the same bar. This makes hit-testing increasingly expensive and retains stale rectangles. Replace/update entries by (dataIndex, valueIndex) and remove entries for bars no longer present.

  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt#L304-L305: replace the geometry-based append logic with keyed updates.
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt#L282-L283: apply the same keyed update logic.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`
around lines 304 - 305, Update bar hit-rectangle tracking in ColumnChart.kt
lines 304-305 and RowChart.kt lines 282-283 to key entries by (dataIndex,
valueIndex) rather than Rect equality: replace each existing bar’s rectangle in
place, add only new bar identities, and remove entries for bars absent from the
current frame so stale rectangles cannot accumulate.
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/ScrollUtils.kt (1)

47-68: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Make barSpacing represent the actual empty gap.

calculateEveryDataSize already includes each bar’s configured spacing, while both charts also offset bars by averageSpacingBetweenBars / 2. Therefore targetStep = everyDataSize + targetGapPx makes the visible inter-group gap larger than targetGapPx (for one 20.dp bar with 3.dp spacing and Always(16.dp), it is approximately 19.dp). This also makes Auto’s compression threshold inaccurate. Align the effective-size formula with the visible group width, or document that barSpacing is additive.

Also applies to: 73-88

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/ScrollUtils.kt`
around lines 47 - 68, Update the ScrollMode.Always and ScrollMode.Auto
calculations so barSpacing represents the actual visible empty gap between
groups, accounting for spacing already included by calculateEveryDataSize and
the averageSpacingBetweenBars / 2 offsets. Adjust targetStep, effectiveSize, and
Auto’s naturalGap compression threshold consistently, preserving the existing
scroll behavior while preventing the configured gap from being inflated.
🧹 Nitpick comments (1)
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt (1)

184-185: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Avoid mutating scrollEnabled during composition. Derive the value from scrollConfig and pass it directly into the pointer modifier, or update it outside composition. The current write causes an extra recomposition and can leave gesture handling one frame behind after layout changes.

  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt#L184-L185: avoid storing this derived value in mutable state.
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt#L454-L455: remove the composition-time assignment.
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt#L180-L181: apply the same derivation strategy.
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt#L464-L465: remove the composition-time assignment.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`
around lines 184 - 185, Derive scroll-enabled behavior directly from
scrollConfig instead of storing it in mutable state during composition. In
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt
lines 184-185, replace the scrollEnabled state with the derived value and pass
it directly to the pointer modifier; remove the composition-time assignment at
lines 454-455. Apply the same changes in
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt
lines 180-181 and remove its assignment at lines 464-465.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@document/docs/chart-properties/scroll-mode.md`:
- Around line 18-20: Update the fenced code block containing
distanceBetweenBarOrigins in the scroll-mode documentation to specify a language
identifier such as text or kotlin after the opening backticks, without changing
the formula.

---

Outside diff comments:
In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`:
- Around line 304-305: Update bar hit-rectangle tracking in ColumnChart.kt lines
304-305 and RowChart.kt lines 282-283 to key entries by (dataIndex, valueIndex)
rather than Rect equality: replace each existing bar’s rectangle in place, add
only new bar identities, and remove entries for bars absent from the current
frame so stale rectangles cannot accumulate.

In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/ScrollUtils.kt`:
- Around line 47-68: Update the ScrollMode.Always and ScrollMode.Auto
calculations so barSpacing represents the actual visible empty gap between
groups, accounting for spacing already included by calculateEveryDataSize and
the averageSpacingBetweenBars / 2 offsets. Adjust targetStep, effectiveSize, and
Auto’s naturalGap compression threshold consistently, preserving the existing
scroll behavior while preventing the configured gap from being inflated.

---

Nitpick comments:
In
`@compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt`:
- Around line 184-185: Derive scroll-enabled behavior directly from scrollConfig
instead of storing it in mutable state during composition. In
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt
lines 184-185, replace the scrollEnabled state with the derived value and pass
it directly to the pointer modifier; remove the composition-time assignment at
lines 454-455. Apply the same changes in
compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt
lines 180-181 and remove its assignment at lines 464-465.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: daa042fc-1ad9-4964-9a58-4bcfb2e37da0

📥 Commits

Reviewing files that changed from the base of the PR and between f477a42 and 7d34478.

📒 Files selected for processing (7)
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/ColumnChart.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/RowChart.kt
  • compose-charts/src/commonMain/kotlin/ir/ehsannarmani/compose_charts/utils/ScrollUtils.kt
  • document/docs/chart-properties/scroll-mode.md
  • document/docs/charts/column-chart.md
  • document/docs/charts/row-chart.md
  • document/mkdocs.yml

Comment on lines +18 to +20
```
distanceBetweenBarOrigins = barWidth + barSpacing
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Specify the formula fence language.

The fenced block on Lines 18-20 violates markdownlint MD040. Use text or kotlin after the opening backticks.

🧰 Tools
🪛 markdownlint-cli2 (0.23.1)

[warning] 18-18: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@document/docs/chart-properties/scroll-mode.md` around lines 18 - 20, Update
the fenced code block containing distanceBetweenBarOrigins in the scroll-mode
documentation to specify a language identifier such as text or kotlin after the
opening backticks, without changing the formula.

Source: Linters/SAST tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant