首页 > 其他分享 >在 iOS 16 中用 SwiftUI Charts 创建一个折线图

在 iOS 16 中用 SwiftUI Charts 创建一个折线图

时间:2022-11-14 11:38:58浏览次数:49  
标签:16 StepCount iOS Charts value Chart steps 折线图 day

前言

苹果在 WWDC 2022 上推出了 SwiftUI 图表,这使得在 SwiftUI 视图中创建图表变得异常简单。图表是以丰富的格式呈现可视化数据的一种很好的方式,而且易于理解。本文展示了如何用比以前从头开始创建同样的折线图少得多的代码轻松创建折线图。此外,自定义图表的外观和感觉以及使图表中的信息易于访问也是非常容易的。

如以前的文章所示,不使用 SwiftUI Charts 也可以创建一个折线图。然而,使用 Charts 框架可以提供大量的图表来探索对应用程序中的数据最有效的方法,从而使它变得更加容易。

系列文章

  1. 如何在 SwiftUI 中创建条形图
  2. SwiftUI 中的水平条形图
  3. 在 iOS 16 中用 SwiftUI Charts 创建一个折线图
  4. 在 iOS16 中用 SwiftUI 图表定制一个线图
  5. 在 Swift 图表中使用 Foudation 库中的测量类型

简单折线图

从包含一周的步数的数据开始,类似于 在SwiftUI中创建折线图 中使用的数据。定义一个结构来保存日期和该日的步数,并为当前周创建一个数组。

struct StepCount: Identifiable {
let id = UUID()
let weekday: Date
let steps: Int

init(day: String, steps: Int) {
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMdd"

self.weekday = formatter.date(from: day) ?? Date.distantPast
self.steps = steps
}
}


let currentWeek: [StepCount] = [
StepCount(day: "20220717", steps: 4200),
StepCount(day: "20220718", steps: 15000),
StepCount(day: "20220719", steps: 2800),
StepCount(day: "20220720", steps: 10800),
StepCount(day: "20220721", steps: 5300),
StepCount(day: "20220722", steps: 10400),
StepCount(day: "20220723", steps: 4000)
]

要创建一个折线图,为步数数据中的每个元素创建一个带有​​LineMark​​的图表。在​​LineMark​​​的 X 值中指定工作日,在 Y 值中指定步数。注意,还需要导入​​Charts​​框架。

这就为步数数据创建了一个线形图。由于只有一个系列的数据,​​ForEach​​​ 可以省略,数据可以直接传递给 ​​Chart​​ 初始化器。两个部分都产生相同的折线图。

import SwiftUI
import Charts

struct LineChart1: View {
var body: some View {
VStack {
GroupBox ( "Line Chart - Step Count") {
Chart {
ForEach(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
}

GroupBox ( "Line Chart - Step Count") {
Chart(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)

}
}
}
}
}

在 iOS 16 中用 SwiftUI Charts 创建一个折线图_折线图

使用 SwiftUI Charts 创建的折线图显示每日步数

其他图表

SwiftUI Charts 有许多可用的图表选项。这些可以通过将图表标记从​​LineMark​​​改为其他类型的标记(如​​BarMark​​)来生成条形图。

struct OtherCharts: View {
var body: some View {
VStack {
GroupBox ( "Line Chart - Step count") {
Chart(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}

GroupBox ( "Bar Chart - Step count") {
Chart(currentWeek) {
BarMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}

GroupBox ( "Point Chart - Step count") {
Chart(currentWeek) {
PointMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}

GroupBox ( "Rectangle Chart - Step count") {
Chart(currentWeek) {
RectangleMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}

GroupBox ( "Area Chart - Step count") {
Chart(currentWeek) {
AreaMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
}
}
}

在 iOS 16 中用 SwiftUI Charts 创建一个折线图_SwiftUI_02

使用 SwiftUI 图表创建的其他图表类型,显示每日步数

让折线图增加可访问性

将图表植入 SwiftUI 的一个好处是,可以很容易地使用 可访问性修饰符 使图表变得可访问。为 StepCount 添加一个计算属性,将数据返回为一个字符串,可由 ​​accessibilityLabel​​ 使用。然后为图表中的每个标记添加可访问性标签和值。

struct StepCount: Identifiable {
let id = UUID()
let weekday: Date
let steps: Int

init(day: String, steps: Int) {
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMdd"

self.weekday = formatter.date(from: day) ?? Date.distantPast
self.steps = steps
}

var weekdayString: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd"
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
dateFormatter.locale = Locale(identifier: "en_US")
return dateFormatter.string(from: weekday)
}
}
GroupBox ( "Line Chart - Daily Step Count") {
Chart(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
.accessibilityLabel($0.weekdayString)
.accessibilityValue("\($0.steps) Steps")
}
}

在 iOS 16 中用 SwiftUI Charts 创建一个折线图_ECharts_03

在 SwiftUI 图表中使折线图可访问性

为折线图添加多个数据序列

折线图是比较两个不同系列数据的好方法。创建第二个系列,即前一周的步数,并将这两个系列添加到折线图中。

let previousWeek: [StepCount] = [
StepCount(day: "20220710", steps: 15800),
StepCount(day: "20220711", steps: 7300),
StepCount(day: "20220712", steps: 8200),
StepCount(day: "20220713", steps: 25600),
StepCount(day: "20220714", steps: 16100),
StepCount(day: "20220715", steps: 16500),
StepCount(day: "20220716", steps: 3200)
]

let currentWeek: [StepCount] = [
StepCount(day: "20220717", steps: 4200),
StepCount(day: "20220718", steps: 15000),
StepCount(day: "20220719", steps: 2800),
StepCount(day: "20220720", steps: 10800),
StepCount(day: "20220721", steps: 5300),
StepCount(day: "20220722", steps: 10400),
StepCount(day: "20220723", steps: 4000)
]

let stepData = [
(period: "Current Week", data: currentWeek),
(period: "Previous Week", data: previousWeek)
]

第一次尝试添加这两个系列的数据没有按预期显示。

struct LineChart2: View {
var body: some View {
GroupBox ( "Line Chart - Daily Step Count") {
Chart {
ForEach(stepData, id: \.period) {
ForEach($0.data) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
.accessibilityLabel($0.weekdayString)
.accessibilityValue("\($0.steps) Steps")
}
}
}
}
}
}

在 iOS 16 中用 SwiftUI Charts 创建一个折线图_ECharts_04

第一次尝试在 SwiftUI Charts 中创建一个包含两个系列步数数据的折线图

显示步数系列

在折线图中显示多个基于工作日的步数系列

最初尝试在折线图中显示多组数据的问题是X轴使用了日期。当前的周数紧接着上一周,所以每一个点都是沿着X轴线性递增绘制的。

有必要只用工作日作为X轴的数值,这样所有的周日都在同一个X坐标上绘制。

在​​StepCount​​中添加另一个计算属性,以便以字符串格式返回工作日的短日。

struct StepCount: Identifiable {

. . .


var shortDay: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE"
return dateFormatter.string(from: weekday)
}
}

此 ​​shortDay​​​ 用于图表中 ​​LineMarks​​​ 的 x 值。另外,前景的样式设置为基于​​stepCount​​数组的周期。折线图使用 x 轴的工作日来显示两周的步数,以便在周之间进行比较。

struct LineChart3: View {
var body: some View {
VStack {
GroupBox ( "Line Chart - Daily Step Count") {
Chart {
ForEach(stepData, id: \.period) { steps in
ForEach(steps.data) {
LineMark(
x: .value("Week Day", $0.shortDay),
y: .value("Step Count", $0.steps)
)
.foregroundStyle(by: .value("Week", steps.period))
.accessibilityLabel($0.weekdayString)
.accessibilityValue("\($0.steps) Steps")
}
}
}
.frame(height:400)
}
.padding()

Spacer()
}
}
}

在 iOS 16 中用 SwiftUI Charts 创建一个折线图_SwiftUI_05

SwiftUI 图表中带有两个系列的步数数据的折线图

结论

在 SwiftUI Charts 中还有很多东西可以探索。使用这个框架显然比从头开始建立你自己的图表要好。


标签:16,StepCount,iOS,Charts,value,Chart,steps,折线图,day
From: https://blog.51cto.com/u_15551344/5848568

相关文章

  • Oracle常用优化16个技巧
    1.选择最有效率的表名顺序ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表drivingtable)将被最先处理。当ORACLE处理多个表时,会......
  • CF1650G 『Counting Shortcuts』 题解
    从洛谷博客那里搬过来的(图论专题本来打算先挑最简单的做,结果做了两个多小时(题意就是让你找从起点\(s\)到终点\(t\)的最短路以及次短路个数,本题次短路长度指的是最短......
  • 最全iOS 应用上架流程(提交到AppStore)
    一、上架基本需求资料1、苹果开发者账号(公司已有可以不用申请,需要开通开发者功能,每年99美元)2、开发好的APP借助辅助工具appuploader创建证书跟描述文件二、证书,描述文件(借......
  • 【算法训练营day16】LeetCode104. 二叉树的最大深度 LeetCode559. n叉树的最大深度 Le
    LeetCode104.二叉树的最大深度题目链接:104.二叉树的最大深度初次尝试直接看题解学习思路。看完代码随想录后的想法本题使用的是二叉树的后序遍历,实际上是在求根节点......
  • 第2节 2020.05.16 智能互联网之关键系统实践篇【二】
                                    给key加锁,并且key数+1统计到100做限制         ......
  • 16.Linux-默认权限控制命令umask
    1.umaskLinux中umask的工作方式与chmod命令类似,它也用于定义文件或目录的权限。它们之间的区别在于chmod用于改变已有文件或目录的权限,而umask用于定义新建文件或目录的......
  • P2827 NOIP2016 提高组 蚯蚓
    P2827NOIP2016提高组蚯蚓-洛谷|计算机科学教育新生态(luogu.com.cn)事实上,本题疑似所有题解和lyd蓝书上的证明均有误,本篇题解将给出一个严谨的单调性正确性证明......
  • LeetCode 167.TowSum
    双指针classSolution{public:vector<int>twoSum(vector<int>&numbers,inttarget){intl=0,r=numbers.size()-1,sum=0;while(l<r){......
  • expdp导出sys用户下test表空间报错ora-31655
    数据库:oracle11.2.0.4系统:centos7.9问题描述:expdp导出sys用户下test表空间报错ora-31655,如下所示:[oracle@leo~]$expdp\'/assysdba\'directory=ts_expdpdumpfile=ts......
  • 16.xpath解析
    xpath语法XPath使用路径表达式来选取HTML/XML文档中的节点或节点集。节点是通过沿着路径(path)或者步(steps)来选取的。选取节点表达式描述nodename......