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 视图组合和布局知识,创建一个可展示基础数据结构的静态图表框架。最终成果将包含坐标轴、数据标记和基本样式。

步骤说明

1. 创建基础视图结构

import SwiftUI

struct StaticChartView: View {
    // 示例数据(硬编码)
    let dataPoints: [Double] = [20, 45, 28, 80, 50]
    
    var body: some View {
        VStack(alignment: .leading) {
            Text("月度销售额")
                .font(.headline)
            
            // 图表主体容器
            ChartContainer(dataPoints: dataPoints)
                .frame(height: 200)
        }
        .padding()
    }
}

2. 实现图表容器

struct ChartContainer: View {
    let dataPoints: [Double]
    private let axisWidth: CGFloat = 30
    
    var body: some View {
        HStack(alignment: .bottom, spacing: 0) {
            // Y轴标签
            YAxisView(maxValue: dataPoints.max() ?? 100)
                .frame(width: axisWidth)
            
            // 主图表区域
            ZStack(alignment: .bottom) {
                // 背景网格线
                ChartGridLines()
                
                // 数据可视化部分
                HStack(spacing: 12) {
                    ForEach(Array(dataPoints.enumerated()), id: \.offset) { index, value in
                        BarColumn(value: value, maxValue: dataPoints.max() ?? 100)
                    }
                }
                .padding(.leading, 8)
            }
        }
    }
}

3. 构建核心组件

柱状图元素

struct BarColumn: View {
    let value: Double
    let maxValue: Double
    
    var body: some View {
        VStack(spacing: 4) {
            // 柱状主体
            Rectangle()
                .fill(Color.blue.gradient)
                .frame(height: CGFloat(value / maxValue) * 150)
            
            // X轴标签
            Text("\(Int(value))")
                .font(.caption2)
        }
    }
}

坐标轴组件

struct YAxisView: View {
    let maxValue: Double
    let steps = 5
    
    var body: some View {
        VStack {
            ForEach(0..<steps, id: \.self) { step in
                let value = Int(maxValue) - (Int(maxValue) / steps * step)
                Text("\(value)")
                    .font(.system(size: 10))
                    .frame(height: 30)
                Spacer()
            }
        }
    }
}

struct ChartGridLines: View {
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                let step = geometry.size.height / 5
                for i in 0...5 {
                    let y = step * CGFloat(i)
                    path.move(to: CGPoint(x: 0, y: y))
                    path.addLine(to: CGPoint(x: geometry.size.width, y: y))
                }
            }
            .stroke(Color.gray.opacity(0.2), style: StrokeStyle(lineWidth: 1, dash: [2]))
        }
    }
}

进阶挑战

  1. 添加动态颜色支持:根据数值大小显示不同渐变色
  2. 实现横向柱状图版本
  3. 添加点击交互高亮效果(使用 .onTapGesture)

最终效果预览

包含坐标轴、网格线和5个数据柱的基础图表

关键知识点回顾

  • 使用 VStack/HStack 构建复合布局
  • 通过 GeometryReader 实现相对尺寸计算
  • 用 Path 绘制自定义形状
  • 数据到视图的映射模式(ForEach 遍历)

> 提示:此框架已预留扩展接口,后续学习动态数据绑定时可直接复用容器结构
Last Updated:: 5/18/25, 10:09 AM