WWDC22- Un premier regard sur Swift Charts

Olaf⛄️ 2022-8-12 Ébauche finale

avant-propos

En tant que développeur iOS, nous rencontrons plus ou moins le besoin d'affichage d'icônes dans notre développement quotidien. Je pense que lorsque vous résolvez les besoins en icônes, vous utiliserez ou vous référerez directement au framework de dessin de graphiques open source github : Charts , qui dessine des graphiques basé sur CoreGraphics Le framework prend en charge une partie considérable des besoins de développement de graphiques.

En 2022, le propre cadre graphique d'Apple est là !

Le tout nouveau framework Swift Charts a rencontré les développeurs à la WWDC22. Il s'agit d'un cadre SwiftUI puissant et concis qui transforme les données en visualisations informatives et personnalisables. Voici les 4 sessions pertinentes :

Je recommande vivement de regarder Session ! ! !

Fonctionnalités du cadre

L'image ci-dessus est la présentation de l'effet dans Seesion, montrant les puissantes capacités de dessin de Swift Charts, des graphiques à barres simples aux graphiques vectoriels complexes, aux cartes thermiques et aux graphiques Swift peuvent être implémentés avec un code concis. Swift Charts prend en charge les fonctionnalités de localisation et d'accessibilité. Vous pouvez également utiliser des modificateurs de graphique pour remplacer le comportement par défaut afin de personnaliser le graphique. Par exemple, une expérience dynamique peut être créée en ajoutant une animation à un graphique.

compatibilité

iOS 16+, iPadOS 16.0+, macOS 13.0+, watchOS 9.0+

Des marques

  • BarMark

    Différents types de graphiques à barres peuvent être créés avec BarMark, tels que des graphiques à colonnes, des graphiques à barres de progression, etc.

  • Marque de ligne

    Les graphiques linéaires peuvent être créés en traçant les attributs de catégorie ou de date (généralement en utilisant la position x) et en traçant les catégories numériques (généralement en utilisant la position y).

  • Marque de point

    Différents types de graphiques à points peuvent être créés à l'aide du contenu du graphique PointMark. Un graphique commun qui peut être construit à l'aide de marqueurs de points est un nuage de points, qui montre la relation entre deux attributs de données numériques.

  • Marque de zone

    可以使用 AreaMark 将数据可视化为单个区域形状。 可以使用 AreaMark 图表内容创建不同类型的面积图。 要创建简单的区域标记图表,我们通常会将日期或有序字符串属性绘制到 x 位置,将数字绘制到 y 位置。

  • RuleMark

    可以使用 RuleMark 在图表中绘制水平或垂直规则,如平均线,阈值线等。

  • RectangleMark

    可以使用RectangleMark将数据字段映射成矩形图。 可以使用RectangleMark创建热图图表或注释图表中的矩形区域。

以上就是Swift Charts所有的Mark,它们可以单独使用,也可以组合使用,从而支撑开发者按需求开发出所需要的图表。用Session中的图来总结这些Mark吧

框架实践

实现Swift Charts框架,首先需要对SwiftUI的语法有一定的了解,下面将挑选典型图表进行coding实践。

BarkMark

如果我们需要用一张图表来直观的呈现多个国家的某一项开支费用,那我们就可以直接用BarMark来构建一个简单的柱状图来实现。

struct BarMarkData: Identifiable {
    let name: String
    let count: Double
    var id: String{name}
}

let defData: [BarMarkData] = [
    BarMarkData(name: "China", count: 15000),
    BarMarkData(name: "US", count: 30000),
    BarMarkData(name: "UK", count: 2000),
    BarMarkData(name: "Japan", count: 800),
    BarMarkData(name: "France", count: 3000)
]

struct BarMarkChartView: View {
    var body: some View {
        Chart(data) {
            BarMark(
                x: .value("name", $0.name),
                y: .value("count", $0.count)
            )
        }.frame(width: 360, height: 300)
    }
}

struct BarMarkChartView_Previews: PreviewProvider {
    static var previews: some View {
        AreaMarkChartView()
    }
}
复制代码

我们看呈现效果:

如果这项开支还需要跟另一项开支进行对比呈现,这该怎么实现呢?我们只需要将上面的代码略微改动,即可实现,一下只粘贴新增部分的代码:

let eduData: [BarMarkData] = [
    BarMarkData(name: "China", count: 28000),
    BarMarkData(name: "US", count: 35000),
    BarMarkData(name: "UK", count: 6000),
    BarMarkData(name: "Japan", count: 2000),
    BarMarkData(name: "France", count: 5000)
]

let mergeData = [
    (outlay: "def", data: defData),
    (outlay: "edu", data: eduData)
]

struct AreaMarkChartView: View {
    var body: some View {
        Chart(mergeData, id: .outlay) { mergeData in
            ForEach(defData) { datum in
                ForEach(mergeData.data, id: .id) { element in
                    BarMark(
                        x: .value("name", element.name),
                        y: .value("count", element.count)
                    ).position(by: .value("outlay", mergeData.outlay))
                    .foregroundStyle(by: .value("outlay", mergeData.outlay))
                }
            }
        }.frame(width: 360, height: 300)
    }
}
复制代码

我们再来看看呈现效果:

现在已经实现了几个国家两个费用支出的对比图。对比上面,在代码上除了新增数据源,在Charts实现环节,也新增了position和foregroundStyle两个扩展方法

  • .position

    position可以创建分组,让图表沿水平轴按其“类型”标记具有相同“产品”的mark。

  • .foregroundStyle

    foregroundStyle按照传参不同,可进行不同类型的展示设置,如下:

extension ChartContent {

    /// Sets the foreground style for marks in this chart content.
    ///
    /// - Parameter color: The color.
    public func foregroundStyle<S>( _ style: S) -> some ChartContent where S : ShapeStyle


    /// Encodes data as the foreground style for marks in this chart content.
    ///
    /// - Parameter data: The data property or value.
    public func foregroundStyle<D>(by value: PlottableValue<D>) -> some ChartContent where D : Plottable

}
复制代码

LineMark

如果我们需要展示公司统计的一年内营收数据的变化,并且对比往年的数据,那此时我们可以用到的最简单的图就是线性图了,当然我们也可以使用其他的类型的图表来表示。下面我们先用LineMark来进行实践

struct SalesSummary: Identifiable {
    let month: String
    let total: Int
    var id: String {month}
}

let pastData: [SalesSummary] = [
    .init(month: "Jan", total: 3388),
    .init(month: "Feb", total: 4420),
    .init(month: "Mar", total: 6120),
    ...
    .init(month: "Dec", total: 11076)
]

let lineData: [SalesSummary] = [
    .init(month: "Jan", total: 5566),
    .init(month: "Feb", total: 4610),
    .init(month: "Mar", total: 5533),
    ...
    .init(month: "Dec", total: 12998)
]

let salesData = [
    (quarter: "2022", data: currentData),
    (quarter: "2021", data: pastData)
]

struct LineMarkChartView: View {
    var body: some View {
        Chart{
            ForEach(salesData, id: .years) { salesData in    
                ForEach(salesData.data, id: .id) { element in
                    LineMark(x: .value("month", element.month),
                             y: .value("total", element.total))
                }.foregroundStyle(by: .value("sales", salesData.years))
            }
        }.frame(width: 360, height: 300)
    }
}

struct LineMarkChartView_Previews: PreviewProvider {
    static var previews: some View {
        LineMarkChartView()
    }
}
复制代码

我们来看效果:

如果想给折线图增加一个数据点的标记符号,同时让折线变的圆润,那我们就需要实现以下两个属性

struct LineMarkChartView: View {
    var body: some View {
        Chart{
            ForEach(salesData, id: .years) { salesData in
                ForEach(salesData.data, id: .id) { element in 
                    LineMark(x: .value("month", element.month),
                             y: .value("total", element.total))
                             .interpolationMethod(.catmullRom)
                             .symbol(by: .value("sales", salesData.years))
                }.foregroundStyle(by: .value("sales", salesData.years))
            }
        }.frame(width: 360, height: 300)
    }
}
复制代码

再看下效果:

此时我们可以看到数据节点都用原点标记出来,并且折线也变成了更加柔和的曲线,这就是 interpolationMethod 和 symbol 这两个属性发挥的作用。

  • interpolationMethod

    返回使用给定插值绘制数据的图表内容,包含多个,这里不一一列举了,可以查看api,这个方法仅提供给Line 和 Area 两种Mark

  • symbol

    symbol根据传参不同有三个不同的方法实现,来支持不同的特性功能

extension ChartContent {
    /// 设置此图表内容中标记的绘图符号类型
    /// - Parameter symbol: The symbol.
    public func symbol<S>( _ symbol: S) -> some ChartContent where S : ChartSymbolShape

    /// 将数据编码为此图表内容中标记的符号。如上面的例子
    /// - Parameter data: The data property or value.
    public func symbol<D>(by value: PlottableValue<D>) -> some ChartContent where D : Plottable

    /// 返回以给定视图作为绘图符号的图表内容。
    /// - Parameter symbol: The view to use as the plotting symbol.
    public func symbol<V>(@ViewBuilder symbol: () -> V) -> some ChartContent where V : View
}
复制代码

AreaMark

上面的公司年度营收的折线图数据同样也可以用来实践AreaMark区域图,我们来看看具体的代码实现,会不会更复杂呢,还是同样简单

let areaData: [BarMarkData] = [
    .init(month: "Jan", total: 5566),
    .init(month: "Feb", total: 4610),
    .init(month: "Mar", total: 5533),
    ...
    .init(month: "Dec", total: 12998)
]

struct AreaMarkChartView: View {
    var body: some View {
        Chart(areaData) { element in             
            AreaMark(
                x: .value("month", element.month),
                y: .value("total", element.total)
            ).interpolationMethod(.catmullRom)
                .foregroundStyle(.pink)
        }.frame(width: 360, height: 300)
    }
}
复制代码

同样我们先来看看效果:

同样,AreaMark也使用了interpolationMethod来增加了边缘的曲线,同时还使用foregroundStyle来设置区域的颜色。

更多支持

Swift Charts可以三种数据类型作为他的数据值

  • Quantitative(数据型,如果Int、Double等)

  • Nominal(名义型,如各类名称标签)

  • Temporal(时间型,如年月周日时分等)

所以,6种Mark实际只有三种数据类别,每种Mark通常使用的属性通产个包括以下这些,这些属性,我们再上面的实践Demo中也都有使用到:

那么这些属性是不是足够了呢?

当然,是不够的。我们在实际开发中呈现的UI需求往往是定制化元素比较多的,现在我们来看看Swift Charts 框架都能够支持哪些内容的自定义,Seesion中给我们罗列了Chart的自定义内容维度:

接下来,我从途中所列的自定义属性入手,结合上面的的Demo例子,进一步实践Swift Charts的自定义能力。

增加Plot属性后,我们看看实际的效果

            .chartPlotStyle { plot in  
                 plot.background(.purple.opacity(0.8))
                     .border(.purple, width: 2)
                     .frame(width: 150, height: 100)
            }
            // 此时的效果,下图一。
            // 如果将这个图标展示在Apple Watch,或者Widget上,
            // 坐标线的效果此时会成为一种干扰,当然我们可以隐藏坐标线
            .chartXAxis(.hidden)
            .chartYAxis(.hidden)
            // 此时的效果,下图二
            
复制代码

当然,关于这三个属性的应用,不止于此。它们都有很强大的自定义支撑能力来应对图标的展示需求,再结合Descriptions、Interaction、Color来实现更加酷炫的图表呈现。

关于使用

Charts的图表呈现能力虽然强大,但是我们都知道图表有它特殊的呈现场景,那么何时应该较交互呈现为图表,苹果的Session中已经给我们进行的设计指引。

当我们需要将数据进行变化、对比、进度(比例)呈现时,我们就可以使用Chart来帮我们进行可视化的实现 了。

如上三张图所示:

  • 当我们需要可视化某项持续性数据变化趋势时,我们就可以使用Change部分的可视化方式来呈现。例如:用户单日步数、用户消费、浏览时长等数据变化趋势。

  • 当我们需要可视化某项任务的进度,完成度、参与度、占比等等数据时,我们就可以使用Proportion部分的可视化形式来呈现。例如:用户年度App各类业务消费占比。

  • 当我们需要可视化更全面数据的对比及跟维度的数据时,我们可以使用Comparison部分的可视化形式来呈现。如各公司的数据平台等系统的数据。

综上,Charts的使用场景,可能依然是众多App中的小部分,但是在特定行业App的业务中则是核心能力的展示,如你需要做一个股票或者财经类的App,又或者关于健康数据的App。Apple Watch的应用中则对Swift Charts有更多的需求。下面我们可以看看Session中的一些案例。

写在最后

Swift Charts是在WWDC22上和大家见面的,其强大的图表呈现能力,随着你对框架的挖掘和熟悉,会逐渐感知到。那么当你看了这篇文章后,你对Swift Charts有什么想法?

  • 好家伙,兼容性最低iOS16,哪年那月才能用上...

  • Basé sur SwiftUI, je pourrais aussi bien utiliser danielgindi / Charts , après tout, SwiftUI a également besoin d'au moins le support iOS13, attendez jusque-là pour voir SwiftUI...

Ces problèmes existent, et lorsque vous serez familiarisé avec Swift Charts, vous constaterez sûrement qu'il existe des scénarios d'exigences qu'il ne peut pas prendre en charge. Swift Charts vous rencontrera à WWDC22. Je crois que dans WWDC23/24 et au-delà, le cadre Swift Charts continuera d'être mis à jour et amélioré. Pour ceux qui ont des besoins de développement Widget Kit, ou des besoins de développement Apple Watch, il est recommandé de garder en faisant attention.

références

Guess you like

Origin juejin.im/post/7130969087621988389