Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >在 Swift图表中使用Foundation库中的测量类型

在 Swift图表中使用Foundation库中的测量类型

作者头像
韦弦zhy
发布于 2022-11-07 08:27:49
发布于 2022-11-07 08:27:49
2.7K00
代码可运行
举报
运行总次数:0
代码可运行

在 Swift 图表中使用Foundation 库中的测量类型

在这篇文章中,我们将建立一个条形图,比较基督城地区自然散步的持续时间。我们将使用今年推出的新的Swift Charts框架,并将看到如何绘制默认不符合Plottable协议的类型的数据,如Measurement<UnitDuration>

定义图表的数据

让我们先定义一下要在图表中展现的数据。

我们声明了一个包含标题和步行时间(小时)的Walk结构体。我们使用 Foundation 框架中的测量类型Measurement和单位类型UnitDuration来表示每次步行的时间。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct Walk {
    let title: String
    let duration: Measurement<UnitDuration>
}

我们在数组works中存储要在图表中显示的数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let walks = [
    Walk(
        title: "Taylors Mistake to Sumner Beach Coastal Walk",
        duration: Measurement(value: 3.1, unit: .hours)
    ),
    Walk(
        title: "Bottle Lake Forest",
        duration: Measurement(value: 2, unit: .hours)
    ),
    Walk(
        title: "Old Halswell Quarry Loop",
        duration: Measurement(value: 0.5, unit: .hours)
    ),
    ...
]

尝试直接在图表中使用测量值

让我们定义一个Chart,并将walks数组作为数据参数传递给它。因为我们知道我们的walk标题是唯一的,所以我们可以直接使用它们作为id,但你也可以将你的数据模型改为Identifiable

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Chart(walks, id: \.title) { walk in
    BarMark(
        x: .value("Duration", walk.duration),
        y: .value("Walk", walk.title)
    )
}

注意,因为Measurement<UnitDuration>没有遵守Plottable协议,我们会得到一个错误:「Initializer 'init(x:y:width:height:stacking:)' requires that 'Measurement<UnitDuration>' conform to 'Plottable'」

BarkMark的初始化器期望收到一个用于x和y的PlottableValue参数。而且PlottableValue的值类型必须符合Plottable协议。

我们有几个选择来解决这个错误。我们可以提取测量值的value,它是一个Double类型,它是默认符合Plottable的,我们可以扩展具有Plottable一致性的Measurement<UnitDuration>,或者我们可以定义一个包装了测量的类型并使其符合Plottable协议。

如果我们简单地从测量值中提取,我们就会失去上下文,不知道用什么单位来创建测量值。这意味着,我们将无法正确格式化图表的标签来向用户表示单位。虽然我们可以记住我们在创建测量时使用了小时hours,但这并不理想。例如,我们可以决定以后改变数据模型,以分钟为单位存储持续时间,或者数据可能来自其他地方,所以手动重构单位并不是一个完美的解决方案。

Plottable的一致性来扩展Measurement<UnitDuration>是可行的,但根据Swift中关于外部类型的追溯一致性的警告(Warning for Retroactive Conformances of External Types),如果Swift Charts在未来添加了这种一致性,它可能会被破坏。

我们将研究如何定义我们自己的类型来包装 measurement,并为我们的自定义类型添加Plottable的一致性。

设计一个符合 Plottable 标准的包装器类型

我们将定义一个自定义的PlottableMeasurement类型,并使其成为通用的,所以它可以容纳任何类型的单位的测量类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct PlottableMeasurement<UnitType: Unit> {
    var measurement: Measurement<UnitType>
}

然后,我们将为PlottableMeasurement添加Plottable的一致性,其单位为UnitDuration类型。我们可以在将来添加对其他单位的支持。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extension PlottableMeasurement: Plottable where UnitType == UnitDuration {
    var primitivePlottable: Double {
        self.measurement.converted(to: .minutes).value
    }
    
    init?(primitivePlottable: Double) {
        self.init(
            measurement: Measurement(
                value: primitivePlottable,
                unit: .minutes
            )
        )
    }
}

Plottable协议有两个要求:primitivePlottable属性必须返回原始类型之一,如DoubleStringDate,以及一个可失败的初始化器,从原始plottable类型创建一个值。

我决定将测量值转换为分钟,但你可以选择适合你需要的任何其他单位。只是在与原始值转换时要使用相同的单位,这一点很重要。

我们现在可以更新我们的图表,以使用我们的自定义Plottable类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Chart(walks, id: \.title) { walk in
    BarMark(
        x: .value(
            "Duration",
            PlottableMeasurement(measurement: walk.duration)
        ),
        y: .value("Walk", walk.title)
    )
}

它可以工作,但X轴上的标签没有格式化,没有向用户显示测量单位。我们接下来要解决这个问题。

步行时间柱状图的截图,X轴上的标签显示为分钟数,但没有单位

显示带有测量单位的格式化标签

为了定制X轴上的标签,我们将使用chartXAxis(content:)修改器,并用传递给我们的值重构x轴的标记。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Chart(walks, id: \.title) { ... }
    .chartXAxis {
        AxisMarks { value in
            AxisGridLine()
            AxisValueLabel("""
            \(value.as(PlottableMeasurement.self)!
                .measurement
                .converted(to: .hours),
            format: .measurement(
                width: .narrow,
                numberFormatStyle: .number.precision(
                    .fractionLength(0))
                )
            )
            """)
        }
    }

我们首先添加网格线,然后重构给定值的标签。

AxisValueLabel在初始化器中接受一个LocalizedStringKey,它可以通过插值测量和指定其格式风格来构建。

我们收到的值是使用我们在Plottable一致性中定义的初始化器创建的,所以在我们的案例中,测量值是以分钟为单位提供的。但我相信对于这个特定的图表,使用小时会更好。我们可以很容易地将测量值转换为插值内部所需的单位。在这里,我们确定该值是PlottableMeasurement类型的,所以我们可以强制解包类型转换。

我选择了缩小的格式和小数点后零位数作为数字样式,但你可以根据你的具体图表调整这些设置。

最后的结果是在X轴上显示以小时为单位的格式化持续时间。

步行时间柱状图的截图,X轴上的标签显示了以小时为单位的格式化数字

你可以从我们的GitHub repo中获得这篇文章中使用的项目的完整示例代码

Using Measurements from Foundation for values in Swift Charts https://nilcoalescing.com/blog/UsingMeasurementsFromFoundationAsValuesInSwiftCharts/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
(转)母版页和相对路径
一个经常让开发人员疑惑的问题是母版页是如何处理相对路径的。如果你使用的是静态文字,这一问题不会困扰你。不过,如果你加入了<img>标签或者指向其他资源的HTML标签,问题就可能发生。
SAP梦心
2022/05/10
1.8K0
(转)母版页和相对路径
Asp.net页面生命周期
前言                                      本篇记录的是Asp.net页面生命周期,也就是管道模型的最末端HttpHandler的生命周期。(Page继承了IHttpHandler接口。想了解管道模型,请参考asp.net管道模型(管线模型)之一发不可收拾)。如有不足请大家指出^_^!!  本篇主要参考:ASP.NET编程模型之页面生命周期十一步详解 ASP.NET编程模型之ASP.NET页面生命周期图解        《亮剑.net 深入体验与实战精要》 正文    
^_^肥仔John
2018/01/18
2.4K0
使用RadControls的RadMenu控件开发系统菜单
关于菜单这个话题我想应该是不讲则懂,所以本文不会多讲这些概念,则重关注RadControls控件中的RadMenu控件的使用,结合数据库来开发一个系统菜单。
全栈程序员站长
2022/09/15
6260
使用RadControls的RadMenu控件开发系统菜单
VS2008(C#)子页嵌套母版页的控件访问方法(三)
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage_MasterPage" %>
阳光岛主
2019/02/19
1.1K0
ASP.Net请求处理机制初步探索之旅 - Part 3 管道
开篇:上一篇我们了解了一个ASP.Net页面请求的核心处理入口,它经历了三个重要的入口,分别是:ISAPIRuntime.ProcessRequest()、HttpRuntime.ProcessRequest()以及HttpApplication.Init()。其中,在HttpApplication的Init()方法中触发了请求处理管道事件的执行,本篇我们就来看看所谓的请求处理管道。
Edison Zhou
2018/08/20
1.2K0
ASP.Net请求处理机制初步探索之旅 - Part 3 管道
ASP.NET中使用UpdatePanel实现局部异步刷新方法和攻略「建议收藏」
转载自:ching126,http://blog.csdn.net/chenhongwu666/article/details/41392529
全栈程序员站长
2022/09/15
2.3K0
asp.net web forms之动态编译
在客户端请求aspx页面。将动态编译aspx页面和aspx.cs代码文件。第一次编译之后。将会缓存编译后的资源,而之后的请求,
小明爱学习
2019/01/07
1.9K0
C#进阶-ASP.NET常用控件总结
ASP.NET Panel 控件用于将一组控件组织在一起,并可以通过控件的 Visible 属性来控制它们的可见性。
Damon小智
2024/03/15
1930
C#进阶-ASP.NET常用控件总结
ASP.NET MVC 重点教程一周年版 第十一回 母版页、用户自定义控件及文件上传
1.母版页是与Controller无关的,母版页只是一个View文件,而没有任何Controller与之相对应。
重典
2022/04/11
1.2K0
ASP.NET MVC 重点教程一周年版 第十一回 母版页、用户自定义控件及文件上传
七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)—
葡萄城控件
2018/01/10
3.2K0
七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
【译】ASP.NET应用程序和页面生命周期
  一、此文是Code Project社区2010年4月ASP.NET板块的最佳文章,说明了此文的份量;
Edison Zhou
2018/08/20
1.1K0
【译】ASP.NET应用程序和页面生命周期
关于ContentPlaceHolder与Content控件
ContentPlaceHolder 控件:在 ASP.NET 母版页中定义内容区域。
全栈程序员站长
2022/09/14
7100
真因验证[客户端认证失败]
在上一篇使用jQuery.Validate进行客户端验证(初级篇)中我介绍了为什么选用jQuery.Validate作为客户端的理由,同时也介绍了jQuery.Validate的基本用法以及中文验证消息的修改方法,今天的中级篇我将介绍下jQuery.Validate的一些常见的验证的使用方法。
Java架构师必看
2022/03/30
2.5K0
真因验证[客户端认证失败]
ASP.NET MVC 重点教程一周年版 第一回 安装,并使ASP.NET MVC页面运行起来
从前写过一系列的ASP.NET MVC教程,ASP.NET MVC在这之后历经5个preview版本终于到今天的RC版本,而且不久就要正式推出正式版本,所以值此之际,重典也重新修正这一系列的教程,使之与时俱进。
重典
2022/04/11
6850
ASP.NET MVC 重点教程一周年版 第一回 安装,并使ASP.NET MVC页面运行起来
编程小记 -- ASP.NET的GridView使用教程
最近有个ASP.NET的小Demo,用到一些ASP.NET的知识,本篇讲的是ASP.NET的GridView使用,GridView的使用还是非常方便的,包括数据的动态绑定,表格的编辑都非常简单,不用再为HTML的Table格式发愁了哈哈哈。本篇教程说是GridView的教程,其实是整个功能实现的总结,包括我编程时的思路、实现功能的小技巧等等。
浩Coding
2019/07/03
2K0
VS2008(C#)子页嵌套母版页的控件访问方法(一)
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage_MasterPage" %>
阳光岛主
2019/02/19
1.3K0
ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
KenTalk
2018/11/12
2.9K0
ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门
Ajax之三 Ajax服务器端控件
Ajax Extensions是Asp.NetAJAX框架的核心组件,只有使用它提供的服务,才能实现局部刷新和个性化组件的AJAX效果。
用户9184480
2024/12/17
1050
Ajax之三 Ajax服务器端控件
ASP.NET Core 入门教程 7、ASP.NET Core MVC 分部视图入门
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-06
KenTalk
2018/12/21
2.1K0
ASP.NET Core 入门教程 7、ASP.NET Core MVC 分部视图入门
ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期
开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们,我们可以注入一些自定义的业务逻辑实现应用的个性化设计。本篇,我们来看看WebForm模式下的页面生命周期。
Edison Zhou
2018/08/20
1.4K0
ASP.Net请求处理机制初步探索之旅 - Part 4  WebForm页面生命周期
推荐阅读
相关推荐
(转)母版页和相对路径
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验