使用JetPack构成第3部分的更容易访问的图形:没有颜色的区分
#a11y #kotlin #android #jetpackcompose

这篇博客文章是我系列中关于JetPack Compose更访问图的第三篇文章。您可以从以下链接中找到前两个:

我们将介绍的第三个主题是通过颜色以外的其他方式来区分数据。颜色是区分数据的便捷方法,但是如果看不到颜色,该怎么办?或者,如果您看到不同的颜色怎么办?例如,我们在博客文章系列期间一直在开发的示例项目对于根本看不到颜色的人来说看起来像这样:

An example how the app looks for someone who can't see color at all. Lines are not distinguishable from each other.

和红绿色色盲的人:

An example how the app looks for someone with red-green color blindness. Lines are not distinguishable from each other.

为什么不单独使用颜色的另一个方面是手机屏幕以不同的方式显示颜色。对于低端手机而言,在高端外部屏幕上的一个明显差异可能几乎是相同的阴影,从而使使用情况不可能。

有更好的想法,而不仅仅是使用颜色来区分数据。在下一节中,让我们探索其他一些方式。

颜色的选项

谈论图表时,通常有两种方法可以提高数据的区分性:形状和模式。例如,如果条形图最初是通过颜色区分的,则添加不同颜色的图案可以区分这些条。

对于线图,这两个选项都是有效的。让我们通过添加各个点的不同形状和该行的某些模式来探索和区分数据。该解决方案不是最美丽的,因为我要混合这两个选项,但是它可以证明,而不是最终的设计。

代码

在我们开始的情况下,我们用来绘制数据点的功能如下:

drawPoints(
    points = pixelPoints.map { Offset(it.x + 20f, it.y) },
    pointMode = PointMode.Points,
    color = color,
    strokeWidth = 8.dp.toPx(),
    cap = StrokeCap.Round,
)

它从参数采取点和点模式,除此之外,所有内容均在辅助功能内定义。在此示例中,我们对strokeWidthcap-Properties感兴趣,因为我们使用它们来更改绘制数据点的方式。此外,我们将通过添加附加样式修改代码,以绘制数据点之间的路径。

让我们开始更改数据点的形状。首先,让我们为drawData扩展添加新参数,该参数封装了数据点和线的图形方法:

fun DrawScope.drawData(
    ...
    strokeWidth: Float = 8.dp.toPx(),
    strokeCap: StrokeCap = StrokeCap.Round
) { ... }

我们添加了两个新参数:strokeWidthstrokeCap,,然后将当前值设置为默认值。然后,我们在代码中使用这些新属性:

drawPoints(
    ...
    strokeWidth = strokeWidth,
    cap = strokeCap
)

注意:我们将它们添加到两个drawPoints方法中,因为有一个用于突出显示的点,一个用于所有点。

然后,在Graph-composobable中,我们为每个数据集添加了实际差异化:

drawData(
    ... // Engineering data
    strokeCap = StrokeCap.Round,
)
drawData(
    ... // ICT-data
    strokeCap = StrokeCap.Square,
)
drawData(
    ... // Total data
    strokeCap = StrokeCap.Butt,
    strokeWidth = 12.dp.toPx(),
)

当我们设置默认值时,如果值为默认值,则不需要传递两个参数的值。 ICT和工程数据就是这种情况,因为我们希望保持点相同。实际上,出于相同的原因,我们不需要通过工程数据的strokeCap值传递 - 但我选择添加它以清楚并显示不同的值。

好吧,在这些更改之后,这些点看起来不同。对于工程数据,什么都没有改变,但是对于ICT数据和总数据,这些点是矩形,并且总数据比其他数据更重要。

让我们在查看结果之前添加另一个差异化器。我们还希望能够彼此区分线,而一种方法是改变行模式。在此示例中,我们将为其中一个数据集添加虚线。

让我们从为drawData添加另一个新参数:

fun DrawScope.drawData(
    dashed: Boolean = false,
) { ... }

新参数为dashed,,默认情况下设置为false。如果是真的,我们想更改我们正在绘制的路径的样式:

drawPath(
    path = path,
    color = color,
    style = Stroke(
        width = 3f,
        pathEffect = if (dashed) 
            PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f) 
        else null
    ),
)

我们为中风添加了thepathEffect,并将其设置为10f间隔的虚线路径效果。如果dashed是错误的,那么我们不设置路径效应 - 或者我们将其设置为null,这是其默认值。

最后要做的是将值传递给一个drawData功能之一,在这种情况下,我们将其传递给ICT数据:

drawData(
    ... // ICT-data
    strokeCap = StrokeCap.Square,
    dashed = true
)

这样,我们添加了形状和模式。最终实现如下:

The lines have now different point-styles and one of the datasets has a dashed line.

You can find the final code from this commit.

包起来

在这篇博客文章中,我们研究了通过颜色以外的其他方式改善区分数据。我们通过更改线图中的数据点以具有不同的形状并在其中一条线上添加虚线图案来介绍添加形状和图案。

本系列中的第四篇文章将涵盖开关设备以及导航应如何与之合作。发布它将需要一些时间 - 我需要找出为什么它不适应其应有的解决方案。

博客文章中的链接