SwiftUI Chart 水平一维分段图表圆角设置异常问题
水平分段柱状图圆角设置问题
尝试给SwiftUI Charts的水平一维分段柱状图设置圆角,但目前仅右侧上下两个角能显示圆角,使用clipShape方法也得到相同结果。
原代码
import SwiftUI import Charts let testData: [Profit] = [ Profit(department: "Production", profit: 15000), Profit(department: "Marketing", profit: 8000), Profit(department: "Finance", profit: 10000) ] struct ContentView: View { var body: some View { VStack { Chart(testData) { BarMark( x: .value("Profit", $0.profit) ) .foregroundStyle(Color.random(randomOpacity: false)) .cornerRadius(15) } .chartLegend(.hidden) .chartXAxis(.hidden) .frame(height: 50) .padding(.horizontal) } .padding(100) } } struct Profit: Identifiable { let id = UUID() let department: String let profit: Double } public extension Color { static func random(randomOpacity: Bool = false) -> Color { Color( red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1), opacity: randomOpacity ? .random(in: 0...1) : 1 ) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
当前效果

解决方案
原问题是因为每个BarMark单独设置了全角圆角,且未将分段bar堆叠到同一行,导致只有每个bar的右端显示圆角。要实现整体左右两端的圆角,需做以下调整:
- 将所有bar堆叠到同一y轴分类下,形成连续的水平长条;
- 为第一个bar设置左侧圆角,最后一个bar设置右侧圆角,中间bar不设置圆角;
- 取消bar之间的间距,让分段无缝连接。
修改后的代码
import SwiftUI import Charts let testData: [Profit] = [ Profit(department: "Production", profit: 15000), Profit(department: "Marketing", profit: 8000), Profit(department: "Finance", profit: 10000) ] struct ContentView: View { var body: some View { VStack { Chart(testData.enumerated()) { index, item in BarMark( x: .value("Profit", item.profit), y: .value("Category", "Total") // 将所有bar归到同一分类 ) .foregroundStyle(Color.random(randomOpacity: false)) // 针对不同位置的bar设置对应圆角 .cornerRadius(15, corners: index == 0 ? [.topLeft, .bottomLeft] : (index == testData.count - 1 ? [.topRight, .bottomRight] : [])) } .chartLegend(.hidden) .chartXAxis(.hidden) .chartYAxis(.hidden) // 隐藏不需要的y轴 .chartBarSpacing(0) // 取消bar之间的间距 .frame(height: 50) .padding(.horizontal) } .padding(100) } } struct Profit: Identifiable { let id = UUID() let department: String let profit: Double } public extension Color { static func random(randomOpacity: Bool = false) -> Color { Color( red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1), opacity: randomOpacity ? .random(in: 0...1) : 1 ) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
说明
- 通过
y: .value("Category", "Total")将所有分段bar绑定到同一y轴项,实现水平堆叠; - 利用
enumerated()遍历数据,判断每个bar的位置,分别设置左右圆角; chartBarSpacing(0)确保分段之间无间隙,形成完整的长条效果。
内容的提问来源于stack exchange,提问作者jat
相关产品推荐
相关产品推荐

