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

SwiftUI图表中点击BarMark时如何修改其颜色

SwiftUI Charts 实现点击BarMark修改样式

因为BarMark本身没有直接的.onTap修饰符,我们可以通过Chart的手势结合状态变量来实现点击修改样式的需求,核心思路是用状态记录选中的条形项,再根据状态动态调整BarMark的样式。

完整实现步骤

  1. 先定义数据模型(可根据实际业务调整):
import SwiftUI
import Charts

struct DataItem: Identifiable {
    let id = UUID()
    let day: Date
    let duration: Double
}

// 模拟近1小时的数据
extension [DataItem] {
    static let lastOneHour: [DataItem] = {
        let now = Date()
        return (0..<6).map { hourOffset in
            DataItem(day: now.addingTimeInterval(-TimeInterval(hourOffset)*3600), duration: Double.random(in: 10...50))
        }
    }()
}
  1. 实现可点击的条形图:
struct TapableBarChart: View {
    // 记录选中的条形项
    @State private var selectedItem: DataItem?
    
    var body: some View {
        Chart {
            ForEach(DataItem.lastOneHour) { item in
                BarMark(
                    x: .value("Hour", item.day, unit: .hour),
                    y: .value("Duration", item.duration)
                )
                // 根据选中状态切换样式
                .foregroundStyle(selectedItem?.id == item.id ? .orange : .blue)
                .opacity(selectedItem?.id == item.id ? 0.8 : 1.0)
                .cornerRadius(selectedItem?.id == item.id ? 8 : 4)
                .border(selectedItem?.id == item.id ? .red : .clear, width: 2)
            }
        }
        .onTapGesture { location in
            let chartProxy = ChartProxy(self)
            guard let plotArea = chartProxy.plotAreaFrame else { return }
            
            // 计算点击位置在图表绘图区域的相对坐标
            let relativeX = (location.x - plotArea.minX) / plotArea.width
            let relativeY = (location.y - plotArea.minY) / plotArea.height
            
            // 将相对坐标转换为图表的X轴值(这里是Date类型)
            if let tappedHour = chartProxy.value(atX: relativeX, as: Date.self),
               // 匹配对应的DataItem(按小时粒度匹配)
               let matchedItem = DataItem.lastOneHour.first(where: {
                   Calendar.current.isDate($0.day, equalTo: tappedHour, toGranularity: .hour)
               }) {
                // 点击已选中的项则取消选中,否则切换选中项
                selectedItem = matchedItem == selectedItem ? nil : matchedItem
            }
        }
    }
}

关键说明

  • 状态变量:用@State private var selectedItem跟踪当前选中的条形,驱动样式变化
  • 样式动态调整:通过foregroundStyle、opacity、cornerRadius、border等修饰符,根据选中状态修改BarMark的外观
  • 点击识别:借助ChartProxy获取点击位置对应的图表数据,通过坐标转换匹配到对应的DataItem,更新选中状态

你可以根据需求自定义更多样式变化,比如修改填充图案、阴影效果等。

内容的提问来源于stack exchange,提问作者Leela

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:30:53