SwiftUI Chart如何修改字体颜色

原创 吴就业 118 0 2024-07-07

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/52c19642c3c74080a74f919f2a1921e9

作者:吴就业
链接:https://wujiuye.com/article/52c19642c3c74080a74f919f2a1921e9
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

SwiftUI Charts 是苹果官方提供的一个用于绘制图表的组件库。

笔者在使用SwiftUI Charts 遇到了一个问题:使用Charts绘制的图表,默认文字都是灰色的,当我们app的主题颜色是固定深色的情况下(不是跟随系统的主题深色),图表的文字会看不清。

以柱形图为例,案例代码如下:

// 用于绘制图表的数据的结构体
struct BarItem: Identifiable {
    var id = UUID()
    let category: String // 多项对比,分类名称
    let name: String // x轴名称
    let value: Double // y轴值
    let color: Color
}

Chart(dataArray) { data in
	BarMark(
     x: .value("Name", data.name),
     y: .value("Value", data.value)
  )
  .foregroundStyle(data.color)
  .foregroundStyle(by: .value("Category", data.category))
  .annotation(position: .overlay) {
       Text("\(Int(data.value))")
            .font(.caption)
            .foregroundStyle(Color.white)
   }
}.frame(maxWidth: .infinity, maxHeight: 250, alignment: .center)

案例效果如下:

截屏2024-07-07 22.18.15

可以看到,只有柱形图上的数值的颜色是白色,其它x轴、y轴等文本字体颜色都是深色的,跟背景颜色冲突了,会看不清。

柱形图上的数值的颜色是白色的,因为是我们通过annotation函数设置的,代码如下。

.annotation(position: .overlay) {
       Text("\(Int(data.value))")
            .font(.caption)
            .foregroundStyle(Color.white)
   }

那么怎么修改其他文字的字体颜色呢?

图表(Chart)是由很多组件组成的,首先我们需要了解我们想要修改的文本涉及图表中的哪些组件,这样才能知道怎么搜索资料。参考这篇博客文章:《ECharts 图表组成》,再根据上图理解,我们需要修改的图表组件包括:

Legend:图例是图表的辅助视觉引导组件,用以解释说明图表中各数据序列的含义及图表中数据的筛选。

笔者从官方api文档《Customizing axes in Swift Charts》找到了相关的API。

其中xAxis组件和yAxis组件分别是使用Chart的chartXAxis和chartYAxis函数设置,通过AxisMarks来设置坐标轴显示值的Label,然后给Label设置前景色:AxisValueLabel().foregroundStyle(Color.white)

Legend组件则通过使用Chart的chartLegend函数设置,但不同于chartXAxis和chartYAxis,调用chartLegend我们需要完全自己绘制Legend组件。在构造BarMark的时候,我们使用foregroundStyle(by: .value("Category", data.category))设置了使用category自动绘制Legend,同样的,调用chartLegend函数我们需要先获取到所有category,并且获取到category对应的color,最后通过ForEach为每个category绘制一个Label,如用category的color画一个小圈,再用Text显示category。

修改后代码如下:

struct BarItem: Identifiable {
    var id = UUID()
    let category: String
    let name: String
    let value: Double
    let color: Color
}

struct ChartLegend: Identifiable {
    var id = UUID()
    var category: String
    var color: Color
}

func getChartLegend(_ dataArray:[BarItem])-> [ChartLegend] {
	// ....
}

Chart(dataArray) { data in
	BarMark(
     x: .value("Name", data.name),
     y: .value("Value", data.value)
  )
  .foregroundStyle(data.color)
  .foregroundStyle(by: .value("Category", data.category))
  .annotation(position: .overlay) {
       Text("\(Int(data.value))")
            .font(.caption)
            .foregroundStyle(Color.white)
   }
}.frame(maxWidth: .infinity, maxHeight: 250, alignment: .center)
	.chartYAxis {
       AxisMarks(
          values: [0, 2, 4, 6, 8, 10] // Y轴坐标的取值
       ) {
           AxisValueLabel().foregroundStyle(Color.white)
       }
   }
   .chartXAxis {
        AxisMarks {
            AxisValueLabel().foregroundStyle(Color.white)
        }
   }
   .chartLegend(position: .bottom, alignment: .bottomLeading, spacing: 8, content: {
        HStack{
             ForEach(getChartLegend(dataArray)) { item in
                  Label(
                       title: {
                           Text("\(item.category)").font(.caption).foregroundStyle(Color.white)
                       },
                       icon: {
                            Circle().fill(item.color).frame(width: 8, height: 8)
                       }
                  )
             }
       }.frame(maxWidth: .infinity, alignment: .leading)
  })

修改后的效果如下:

截屏2024-07-07 22.18.51


参考文献:

#前端

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

如何编译构建一个同时支持多cpu架构的静态链接库(.a文件)

我想要让自己的mac OS应用支持更多用户可以使用,就必须要打出一个能同在amd64架构cpu的mac os设备上运行,也需要能在arm64架构cpu的mac os设备上运行。

使用node:alpine基础镜像今天突然就构建不了了

我的一个nextjs项目使用node:alpine基础镜像,在此之前部署到线上都能正常构建和运行,今天修改点代码提交到生产环境,发现竟然镜像构建失败了。

SwiftUI macOS开发,Button和TextField控件设置背景色不生效的问题

SwiftUI macOS开发,Button和TextField控件设置背景色不生效的问题。

Mac APP开发,Swift调用C静态链接库的函数

开发Mac APP,Swift如何调用C函数,以及如何传递回调函数,是一个比较复杂的Swift调用C的场景。

go编译为c静态链接库给c语言调用,c语言传递函数给go语言回调

c语言调用go语言怎么传递回调函数,go怎么调用c传递的回调函数?本篇提供案例代码,实测方法可行。