Skip to content

Fix bar chart rendering for single-value data series - #749

Open
LeSingh1 wants to merge 1 commit into
carekit-apple:mainfrom
LeSingh1:fix-single-value-bar-chart
Open

Fix bar chart rendering for single-value data series#749
LeSingh1 wants to merge 1 commit into
carekit-apple:mainfrom
LeSingh1:fix-single-value-bar-chart

Conversation

@LeSingh1

Copy link
Copy Markdown

Summary

Fixes #575: a bar chart with a single data point (e.g. OCKDataSeries(values: [132], title: "Steps")) renders nothing.

Root cause

OCKMultiPlotable.graphBounds() in CareKitUI/CareKitUI/iOS/Charts/Protocols/OCKGraphable.swift computes the chart's coordinate-space rect from the min/max of the data points. With one point, xMin == xMax and yMin == yMax, so the returned CGRect has zero width and zero height. OCKBarLayer.makePath then receives degenerate input from the cartesian conversion and draws nothing.

Fix

In graphBounds(), when an axis collapses to a single value, pad the inferred range so the rect has positive extent:

  • x axis: pad by 0.5 on each side of the value, centering the bar.
  • y axis: for positive values, snap the lower bound to 0 so a single value renders as a full-height bar from the natural baseline — this matches the workaround @erik-apple documented in the issue (graphView.yMinimum = 0). For negative values, snap the upper bound to 0. For exactly 0, expand symmetrically.

Multi-point series fall through unchanged (xMin < xMax and yMin < yMax continue to use the existing computation).

Test plan

  • Source file parses cleanly: swiftc -parse CareKitUI/CareKitUI/iOS/Charts/Protocols/OCKGraphable.swift (exit 0)
  • Traced the math by hand against the issue's repro (OCKDataSeries(values: [132], title: "Steps")):
    • Before: graphBounds()CGRect(x: 0, y: 132, w: 132, h: 0) (auto-scaling sets yMaximum = 132, then yMin == yMax); height is 0, bar layer produces no visible path.
    • After: graphBounds()CGRect(x: -0.5, y: 0, w: 1, h: 132). Bar centered at x=0, full height from y=0 to y=132.
  • Multi-value case ([10, 20, 30]): unchanged behavior (xMin=0, xMax=2, height>0, etc.). Both branches of the if xMin == xMax and if yMin == yMax guards are skipped.

⚠️ I could not run the CareKitUI XCTest suite from this environment (no Xcode/test runner available here). A regression test that asserts view.graphBounds().width > 0 && height > 0 after view.dataSeries = [OCKDataSeries(values: [132], title: "Steps")] would be a natural follow-up — I intentionally did not add an unbuilt test file to avoid manual .pbxproj edits I couldn't verify.

Scope

Single-file change to OCKGraphable.swift. No public API changes, no behavior change for existing multi-point charts.

When a data series contains exactly one value, graphBounds() inferred
xMin == xMax and yMin == yMax, producing a zero-area CGRect that
collapses bar/line/scatter rendering (issue carekit-apple#575). Expand the inferred
range so a single point has room to render:

- x: pad by 0.5 on either side of the value
- y: snap to 0 as the natural baseline when the value is positive
  (matching the documented workaround), to 0 as the top when negative,
  and pad symmetrically when the value is exactly 0

Multi-point series are unaffected (xMin < xMax and yMin < yMax remain
the existing computation).

Fixes carekit-apple#575
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.

bar chart fails to display when only one entry is there in dataSeries

1 participant