当前位置: 首页 > 科技观察

在iOS16中使用SwiftUICharts创建折线图

时间:2023-03-14 22:20:46 科技观察

前言Apple在WWWDC2022上推出了SwiftUICharts,这使得在SwiftUI视图中创建图表变得异常容易。图表是一种以易于理解的丰富格式呈现视觉数据的好方法。本文展示了如何使用比以前从头开始创建相同折线图更少的代码轻松创建折线图。此外,自定义图表的外观和使图表中的信息易于访问也非常容易。如前几篇文章所示,可以在不使用SwiftUICharts的情况下创建折线图。但是,使用Charts[1]框架可以使它变得更容易,它提供了大量图表来探索应用程序中数据的最有效方法。系列文章如何在SwiftUI中创建条形图在SwiftUI中使用水平条形图在iOS16中使用SwiftUI图表自定义折线图在SwiftCharts中使用Foudation库中的测量类型简单折线图从包含一周的步骤的数据开始,类似于用于创建的数据SwiftUI中的折线图。定义一个结构来保存日期和当天的步数,并为本周创建一个数组。structStepCount:Identifiable{letid=UUID()letweekday:Dateletsteps:Intinit(day:String,steps:Int){letformatter=DateFormatter()formatter.dateFormat="yyyyMMdd"self.weekday=formatter.date(来自:天)??Date.distantPastself.steps=steps}}letcurrentWeek:[StepCount]=[StepCount(day:"20220717",steps:4200),StepCount(day:"20220718",steps:15000),StepCount(day:"20220719",步数:2800),StepCount(day:"20220720",步数:10800),StepCount(day:"20220721",步数:5300),StepCount(day:"20220722",步数:10400),StepCount(day:"20220723",steps:4000)]要创建折线图,请为步数数据中的每个元素创建一个带有LineMark的图表。在LineMark的X值中指定工作日,在Y值中指定步数。请注意,还需要导入图表框架。这会为步数数据创建一个折线图。由于只有一系列数据,可以省略ForEach,直接将数据传给Chart初始化器。这两个部分生成相同的折线图。importSwiftUIimportChartsstructLineChart1:View{varbody:someView{VStack{GroupBox("LineChart-StepCount"){Chart{ForEach(currentWeek){LineMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("StepCount",$0.steps))}}}GroupBox("LineChart-StepCount"){Chart(currentWeek){LineMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("StepCount",$0.steps))}}}}}使用SwiftUICharts创建的折线图显示每日步数其他图表SwiftUICharts有很多可用图表选项。通过将图表标记从LineMark更改为其他类型的标记(例如BarMark),可以将这些生成为条形图。structOtherCharts:View{varbody:someView{VStack{GroupBox("LineChart-Stepcount"){Chart(currentWeek){LineMark(x:.value("WeekDay",$0.weekday,unit:.day)},y:.value("StepCount",$0.steps))}}GroupBox("BarChart-Stepcount"){Chart(currentWeek){BarMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("StepCount",$0.steps))}}GroupBox("PointChart-Stepcount"){Chart(currentWeek){PointMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("步数",$0.steps))}}GroupBox("RectangleChart-Stepcount"){Chart(currentWeek){RectangleMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("StepCount",$0.steps))}}GroupBox("AreaChart-Stepcount"){Chart(currentWeek){AreaMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("StepCount",$0.steps))}}}}}使用SwiftUICharts创建的其他图表类型,显示每天的步数,让折线图更易于访问将图表植入SwiftUI的好处之一是可以轻松使用它们的可访问性修饰符[2]通过向StepCount添加一个计算属性来使图表可访问,该属性将数据作为可由accessibilityLabel使用的字符串返回。然后为图表中的每个标记添加辅助功能标签和值。structStepCount:Identifiable{letid=UUID()letweekday:Dateletsteps:Intinit(day:String,steps:Int){letformatter=DateFormatter()formatter.dateFormat="yyyyMMdd"self.weekday=formatter.date(来自:天)??Date.distantPastself.steps=steps}varweekdayString:String{letdateFormatter=DateFormatter()dateFormatter.dateFormat="yyyyMMdd"dateFormatter.dateStyle=.longdateFormatter.timeStyle=.nonedateFormatter.locale=Locale(标识符:"en_US")returndateFormatter.string(from:weekday)}}GroupBox("折线图-每日步数"){Chart(currentWeek){LineMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("步数",$0.steps)).accessibilityLabel($0.weekdayString).accessibilityValue("\($0.steps)步数")}使折线图在SwiftUI图表中可访问将多个数据系列添加到折线图中折线图是比较两个不同系列数据的好方法创建第二个系列,前一周的步数,并将两个系列合并添加到行中图表。让previousWeek:[StepCount]=[StepCount(day:"20220710",steps:15800),StepCount(day:"20220711",steps:7300),StepCount(day:"20220712",steps:8200),StepCount(day:“20220713”,步数:25600),StepCount(天:“20220714”,步数:16100),StepCount(天:“20220715”,步数:16500),StepCount(天:“20220716”,步数:3200)]让当前周:[StepCount]=[StepCount(天:“20220717”,步数:4200),StepCount(天:“20220718”,步数:15000),StepCount(天:“20220719”,步数:2800),StepCount(天:“20220720”,步数:10800),StepCount(天:“20220721”,步数:5300),StepCount(天:“20220722”,步数:10400),StepCount(天:“20220723”,步数:4000)]让stepData=[(period:"CurrentWeek",data:currentWeek),(period:"PreviousWeek",data:previousWeek)]第一次尝试添加这两个系列的数据没有按预期出现。structLineChart2:View{varbody:someView{GroupBox("LineChart-DailyStepCount"){Chart{ForEach(stepData,id:\.period){ForEach($0.data){LineMark(x:.value("WeekDay",$0.weekday,unit:.day),y:.value("步数",$0.steps)).accessibilityLabel($0.weekdayString).accessibilityValue("\($0.steps)步数")}}}}}}FirstattemptatcreatingalinechartinSwiftUIChartswithtwoseriesofstepcountdata在折线图中显示步数系列在折线图中显示多个基于工作日的步数系列在折线图中的初始尝试显示多组数据的问题是x轴使用日期。当前周数紧随前一周,因此绘制的每个点都沿x轴线性增加。必须仅使用工作日作为x轴的值,以便所有工作日都绘制在相同的x坐标上。将另一个计算属性添加到StepCount以字符串格式返回工作日的短天数。结构StepCount:可识别{...varshortDay:String{letdateFormatter=DateFormatter()dateFormatter.dateFormat="EEE"returndateFormatter.string(from:weekday)}}这个shortDay用于图表中LineMarks的x值。此外,前景的样式设置为基于stepCount数组的句点。折线图使用x轴上的工作日来显示两周的步骤,以便在周之间进行比较。structLineChart3:View{varbody:someView{VStack{GroupBox("LineChart-DailyStepCount"){Chart{ForEach(stepData,id:\.period){stepsinForEach(steps.data){LineMark(x:.value("WeekDay",$0.shortDay),y:.value("StepCount",$0.steps)).foregroundStyle(by:.value("Week",steps.period)).accessibilityLabel($0.weekdayString).accessibilityValue("\($0.steps)Steps")}}}.frame(height:400)}.padding()Spacer()}}}SwiftUIchartwithtwoseriesofstepsdataLineChartConclusions有在SwiftUI图表中还有很多需要探索的地方。使用这个框架显然比从头开始构建自己的图表要好。参考资料[1]图表:https://developer.apple.com/documentation/charts。[2]辅助功能修饰符:https://developer.apple.com/documentation/swiftui/view-accessibility。