Charts 结构是 Apple 在 2022 年新增加的结构。经过该结构,你能够用最少的代码来构建高效、自定制的图表。该结构提供符号、份额、轴和图例作为构建块,你能够将它们组合起来开发各种数据驱动的图表。
下图是官方文档的示例图片:
经过上图能够看到,咱们能够经过 Charts 创建各种图标:折线图、柱状图、散点图等。而且该结构会依据数据主动生成合适的外观。
废话不多说,开始编码时间。
简略运用
假定咱们有这样一个需求:需要用柱状图展现天津周一到周三的温度。
首要,导入 Charts
。然后,界说一个结构体用来表明数据,界说一个数组用来存储数据。
struct Temperature: Identifiable {
let weekday: String
let data: Double
var id: String { weekday }
}
let tj_temperatures: [Temperature] = [
.init(weekday: "周一", data: 33.8),
.init(weekday: "周二", data: 32.6),
.init(weekday: "周三", data: 30)
]
接着,就是在 Charts 里边填充数据就能够了:
struct ContentView: View {
var body: some View {
VStack {
Text("天津温度表")
Chart {
ForEach(tj_temperatures) { temperature in
BarMark(x: .value("day", temperature.weekday), y: .value("temperature", temperature.data))
}
}
}
}
}
上述 .value
函数,第一个参数为当前轴代表的意义,第二个参数是详细数据。
效果图:
Tips:因为 Charts 的初始化函数的效果跟 ForEach 相似,所以上述代码能够简化成这样:
Chart(tj_temperatures) {
BarMark(x: .value("day", $0.weekday), y: .value("temperature", $0.data))
}
如何将柱状图改成折线图呢?只需改动一句代码即可:将 BarMark
替换为 LineMark
。
下面是官方支撑的几种 Mark:
- AreaMark:区域图
- LineMark:折线图
- PointMark:散点图
- RectangleMark:矩形图
- RuleMark:运用单个水平或垂直规矩表明数据的图表内容
- BarMark:柱状图 详细款式可拜见官方文档。
动态切换
经过声明一个状态变量,能够依据状态变量的变化,来动态切换图标的数据。
首要界说一个枚举来区别区域,并界说区域的数据源:
let tj_temperatures: [Temperature] = [
.init(weekday: "周一", data: 33.8, city: "tj"),
.init(weekday: "周二", data: 32.6, city: "tj"),
.init(weekday: "周三", data: 30, city: "tj")
]
let bj_temperatures: [Temperature] = [
.init(weekday: "周一", data: 36, city: "bj"),
.init(weekday: "周二", data: 30, city: "bj"),
.init(weekday: "周三", data: 34, city: "bj"),]
enum City {
case tj
case bj
}
接着,界说一个状态变量 city,用来保存当前的区域。声明一个 data 变量,保存相应的区域数据源:
@State var city: City = .tj
var data: [Temperature] {
switch city {
case .tj:
return tj_temperatures
case .bj:
return bj_temperatures
}
}
最终,完成点击事件控件和 Charts:
var body: some View {
VStack {
Text("北京/天津温度表")
Picker("city", selection: $city.animation(.easeInOut)) {
Text("天津").tag(City.tj)
Text("北京").tag(City.bj)
}
.pickerStyle(.segmented)
Chart(data) {
BarMark(x: .value("name", $0.weekday),
y: .value("length", $0.data))
}
}
}
Tips:Charts 也是支撑 SwiftUI 的动画效果的。
两及多条线的折线图
假如咱们需要进行多个数据的比照,比如展现天津、北京和河北的温度比照。能够运用 foregroundStyle
来进行完成。
首要,咱们需要将三个区域的温度数据组成一个数组,并经过一个 city 的字段来区别区域:
let total: [Temperature] = [
.init(weekday: "周一", data: 36, city: "bj"),
.init(weekday: "周二", data: 30, city: "bj"),
.init(weekday: "周三", data: 34, city: "bj"),
.init(weekday: "周一", data: 33.8, city: "tj"),
.init(weekday: "周二", data: 32.6, city: "tj"),
.init(weekday: "周三", data: 31, city: "tj"),
.init(weekday: "周一", data: 34.8, city: "hb"),
.init(weekday: "周二", data: 36.6, city: "hb"),
.init(weekday: "周三", data: 28, city: "hb")
]
接着,调用 foregroundStyle(by: PlottableValue)
函数,将 city 字段值传进去即可:
struct ContentView: View {
var body: some View {
VStack {
Text("北京/天津/河北温度表")
Chart(total) {
LineMark(x: .value("name", $0.weekday), y: .value("length", $0.data))
.foregroundStyle(by: .value("city", $0.city))
}
}
}
}
体系会主动给不同的区域别配不同的色彩,用来区别。示例图如下:
假如不想运用体系主动分配的色彩,也能够运用 chartForegroundStyleScale<Range>(range: Range, type: ScaleType? = nil)
函数来进行自界说。示例代码如下:
let markColors: [Color] = [.black, .red, .cyan]
struct ContentView: View {
var body: some View {
VStack {
Text("北京/天津/河北温度表")
Chart(total) {
LineMark(x: .value("name", $0.weekday), y: .value("length", $0.data))
.foregroundStyle(by: .value("city", $0.city))
}
.chartForegroundStyleScale(range: markColors)
}
}
}
成果如下:
横向的柱状图
对 Charts 来说,横向的柱状图也是十分简略的,将 x 轴与 y 轴的数据互换一下,咱们就能够得到横向的柱状图了。
Chart(total) {
BarMark(x: .value("length", $0.data),
y: .value("name", $0.weekday))
.foregroundStyle(by: .value("city", $0.city))
}