From fae2829c68478dc1025f6c7be63dd486d2a5eceb Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Tue, 27 Oct 2026 16:33:24 +0800 Subject: [PATCH] Fix bar charts with filtered x ranges --- .../Charts/BarChart/BarChartRow.swift | 30 +++++++++++-------- .../ComposableUsageSmokeTests.swift | 10 +++++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift b/Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift index a68d9118..d70e3167 100644 --- a/Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift +++ b/Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift @@ -14,22 +14,27 @@ public struct BarChartRow: View { let localFrame = geometry.frame(in: .local).sanitized let safeWidth = localFrame.width let safeHeight = localFrame.height - let barCount = max(1, chartData.data.count) + let visiblePoints = chartData.points + let normalisedPoints = chartData.normalisedPoints + let barCount = max(1, visiblePoints.count) let slotWidth = safeWidth / CGFloat(barCount) let barWidthRatio: CGFloat = 0.72 HStack(alignment: .bottom, spacing: 0) { - ForEach(0.. CGSize { - if touchLocation > CGFloat(index) / CGFloat(max(1, chartData.data.count)) && - touchLocation < CGFloat(index + 1) / CGFloat(max(1, chartData.data.count)) { + func getScaleSize(touchLocation: CGFloat, index: Int, barCount: Int) -> CGSize { + if touchLocation > CGFloat(index) / CGFloat(max(1, barCount)) && + touchLocation < CGFloat(index + 1) / CGFloat(max(1, barCount)) { return CGSize(width: 1.4, height: 1.1) } return CGSize(width: 1, height: 1) } func getCurrentSelection(width: CGFloat) -> (index: Int, value: Double)? { - guard !chartData.data.isEmpty else { return nil } + let points = chartData.points + guard !points.isEmpty else { return nil } guard width.isFinite, width > 0 else { return nil } - let denominator = width / CGFloat(chartData.data.count) + let denominator = width / CGFloat(points.count) guard denominator > 0, denominator.isFinite else { return nil } - let index = max(0, min(chartData.data.count - 1, Int(floor((touchLocation * width) / denominator)))) - return (index, chartData.points[index]) + let index = max(0, min(points.count - 1, Int(floor((touchLocation * width) / denominator)))) + return (index, points[index]) } private func formatted(_ value: Double) -> String { diff --git a/Tests/SwiftUIChartsTests/ComposableUsageSmokeTests.swift b/Tests/SwiftUIChartsTests/ComposableUsageSmokeTests.swift index 482d69fa..3281e042 100644 --- a/Tests/SwiftUIChartsTests/ComposableUsageSmokeTests.swift +++ b/Tests/SwiftUIChartsTests/ComposableUsageSmokeTests.swift @@ -17,6 +17,16 @@ final class ComposableUsageSmokeTests: XCTestCase { assertCanRender(view) } + func testBarChartRendersWithCategoricalXRange() { + let view = BarChart() + .chartData([10, 20, 30]) + .chartXRange(1...2) + .chartStyle(sampleStyle) + .frame(width: 240, height: 140) + + assertCanRender(view) + } + func testPieChartRendersWithOptionalInteractionValue() { let view = PieChart() .chartData([34, 23, 12])