You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的右端显示圆角。要实现整体左右两端的圆角,需做以下调整:

  1. 将所有bar堆叠到同一y轴分类下,形成连续的水平长条;
  2. 为第一个bar设置左侧圆角,最后一个bar设置右侧圆角,中间bar不设置圆角;
  3. 取消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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 14:35:33