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

如何在SwiftUI中按年份分组显示折线图线条?

SwiftUI Charts 按年份分组折线图解决方案

问题原因

你当前的代码仅为单个数据点按年份设置了颜色,但LineMark默认会将所有数据点按X轴顺序连接成一条折线,因此即使颜色不同,依然是同一条线,无法实现按年份分组的多条折线效果。

解决方案

要实现每年一条独立折线,需先将数据按年份分组,再为每个年份的数据集单独绘制LineMark。具体步骤如下:

  1. 为Sales结构体添加年份计算属性,简化分组操作;
  2. 将样本数据按年份分组为字典;
  3. 在Chart中遍历每个年份的分组数据,分别绘制折线。

修改后的完整代码

import SwiftUI
import Charts

struct Sales {
    let id = UUID()
    let period: Date
    let value: Double
    
    init(value: Double, year: Int, month: Int) {
        self.value = value
        
        var dateComponents = DateComponents()
        dateComponents.year = year
        dateComponents.month = month
        
        let calendar = Calendar.current
        self.period = calendar.date(from: dateComponents)!
    }
}

extension Sales {
    static var sampleData = [
        Sales(value: 300, year: 2020, month: 1),
        Sales(value: 230, year: 2020, month: 2),
        Sales(value: 190, year: 2020, month: 3),
        Sales(value: 250, year: 2020, month: 4),
        Sales(value: 270, year: 2020, month: 5),
        Sales(value: 280, year: 2020, month: 6),
        Sales(value: 290, year: 2020, month: 7),
        Sales(value: 400, year: 2020, month: 8),
        Sales(value: 300, year: 2020, month: 9),
        Sales(value: 360, year: 2020, month: 10),
        Sales(value: 400, year: 2020, month: 11),
        Sales(value: 450, year: 2020, month: 12),
        
        Sales(value: 320, year: 2021, month: 1),
        Sales(value: 280, year: 2021, month: 2),
        Sales(value: 300, year: 2021, month: 3),
        Sales(value: 390, year: 2021, month: 4),
        Sales(value: 400, year: 2021, month: 5),
        Sales(value: 450, year: 2021, month: 6),
        Sales(value: 420, year: 2021, month: 7),
        Sales(value: 500, year: 2021, month: 8),
        Sales(value: 550, year: 2021, month: 9),
        Sales(value: 490, year: 2021, month: 10),
        Sales(value: 600, year: 2021, month: 11),
        Sales(value: 650, year: 2021, month: 12),
        
        Sales(value: 400, year: 2022, month: 1),
        Sales(value: 330, year: 2022, month: 2),
        Sales(value: 430, year: 2022, month: 3),
        Sales(value: 450, year: 2022, month: 4),
        Sales(value: 600, year: 2022, month: 5),
        Sales(value: 650, year: 2022, month: 6),
        Sales(value: 550, year: 2022, month: 7),
        Sales(value: 580, year: 2022, month: 8),
        Sales(value: 600, year: 2022, month: 9),
        Sales(value: 650, year: 2022, month: 10),
        Sales(value: 600, year: 2022, month: 11),
        Sales(value: 800, year: 2022, month: 12)
    ]
    
    // 添加年份计算属性,方便分组
    var year: Int {
        Calendar.current.component(.year, from: period)
    }
}

struct TesteYearView: View {
    // 按年份分组数据
    private let groupedData: [Int: [Sales]] = {
        Dictionary(grouping: Sales.sampleData, by: { $0.year })
    }()
    
    var body: some View {
        VStack {
            Chart {
                // 遍历排序后的年份,绘制对应折线
                ForEach(Array(groupedData.keys).sorted(), id: \.self) { year in
                    ForEach(groupedData[year]!) { datum in
                        LineMark(
                            x: .value("Month", datum.period, unit: .month),
                            y: .value("Value", datum.value)
                        )
                    }
                    .foregroundStyle(by: .value("Year", year))
                    .symbol {
                        Circle()
                            .frame(width: 5)
                    }
                    .interpolationMethod(.catmullRom) // 可选:让折线过渡更平滑
                }
            }
            .chartLegend(position: .bottom) // 显示年份图例
        }
        .frame(height: 400)
        .padding()
        .chartYAxis(.hidden)
        Spacer()
    }
}

额外说明

  • 通过Dictionary(grouping:)将数据按年份分组,确保每个年份的数据集独立;
  • 外层ForEach遍历排序后的年份,内层ForEach绘制对应年份的每个数据点;
  • .foregroundStyle(by:)会自动为不同年份分配不同颜色,并生成图例;
  • 可选的.interpolationMethod(.catmullRom)可以让折线过渡更平滑,提升视觉效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 05:10:06