Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 案例:多数据集的组合图表

案例:多数据集的组合图表

概述

本章案例将演示如何使用 SwiftUI Charts 框架创建包含多个数据集的组合图表。我们将构建一个同时展示销售额和利润趋势的混合图表,结合折线图和柱状图来呈现不同维度的数据。

实现步骤

1. 准备数据模型

struct SalesData: Identifiable {
    let id = UUID()
    let month: String
    let revenue: Double
    let profit: Double
}

let sampleData: [SalesData] = [
    SalesData(month: "Jan", revenue: 15000, profit: 5000),
    SalesData(month: "Feb", revenue: 22000, profit: 7500),
    // ...其他月份数据
]

2. 创建基础图表框架

Chart {
    // 柱状图表示销售额
    ForEach(sampleData) { data in
        BarMark(
            x: .value("Month", data.month),
            y: .value("Revenue", data.revenue)
        )
        .foregroundStyle(.blue)
    }
    
    // 折线图表示利润
    ForEach(sampleData) { data in
        LineMark(
            x: .value("Month", data.month),
            y: .value("Profit", data.profit)
        )
        .foregroundStyle(.green)
        .lineStyle(StrokeStyle(lineWidth: 3))
    }
}
.chartYAxis {
    // 主Y轴(左侧)
    AxisMarks(position: .leading)
    
    // 次Y轴(右侧)
    AxisMarks(position: .trailing)
}

3. 添加图表修饰符

.chartForegroundStyleScale([
    "Revenue": .blue,
    "Profit": .green
])
.chartLegend(position: .top)
.chartXAxis {
    AxisMarks(values: .stride(by: .month)) { value in
        AxisGridLine()
        AxisTick()
        AxisValueLabel(format: .dateTime.month(.abbreviated))
    }
}

4. 实现交互功能

@State private var selectedMonth: String?

Chart {
    // ...之前的图表内容
    
    // 添加交互标记
    if let selectedMonth {
        RuleMark(
            x: .value("Selected", selectedMonth)
        )
        .foregroundStyle(.gray.opacity(0.3))
        .annotation(position: .top) {
            // 显示详细数据的注解
        }
    }
}
.chartOverlay { proxy in
    GeometryReader { geometry in
        Rectangle().fill(.clear).contentShape(Rectangle())
            .gesture(
                DragGesture()
                    .onChanged { value in
                        let xPosition = value.location.x
                        guard let month: String = proxy.value(atX: xPosition) else { return }
                        selectedMonth = month
                    }
            )
    }
}

关键技术与注意事项

  1. 双Y轴处理:

    • 使用不同度量单位时,需要合理设置轴的位置和比例
    • 可以通过.chartYScale(domain: 0...maxValue)调整范围
  2. 数据对齐:

    • 确保不同图表类型使用相同的x轴值
    • 对时间序列数据使用Date类型而非字符串
  3. 视觉区分:

    • 为不同数据集使用对比明显的颜色
    • 添加图例说明各数据系列含义
  4. 性能优化:

    • 大数据集时考虑使用.chartXScale和.chartYScale限制显示范围
    • 对静态数据使用let声明而非@State

完整示例扩展

添加平均值参考线

let avgRevenue = sampleData.map { $0.revenue }.reduce(0, +) / Double(sampleData.count)

Chart {
    // ...现有图表内容
    
    RuleMark(
        y: .value("Average", avgRevenue)
    )
    .foregroundStyle(.blue)
    .lineStyle(StrokeStyle(lineWidth: 1, dash: [5]))
}

响应式设计处理

@Environment(\.horizontalSizeClass) var sizeClass

var body: some View {
    chart
        .frame(height: sizeClass == .compact ? 300 : 400)
        .padding(sizeClass == .compact ? 10 : 20)
}

总结

通过本案例,我们实现了:

  • 在同一图表中展示多个数据维度
  • 组合使用不同的图表类型(柱状图+折线图)
  • 添加交互式元素和注解
  • 处理双Y轴和响应式布局

这种组合图表特别适合需要对比分析相关指标的商业应用场景。

Last Updated:: 5/18/25, 10:44 AM