最终要实现的效果如下图的Y轴:
最终的效果图
Y轴主要分成两个部分,从原点到第一根刻度线,代表0-70%,平均分布;从第一个刻度线到顶部,代表70%-100%,也是平均分布。
最开始看到需求的时候,想通过将柱形图拆分成两个等差的柱形图,然后通过帧布局重叠两个柱形图来达到UI效果。但是在实践过程中,发现如果改变了一个图标对应一个BarChart的逻辑,就要进一步修改ViewPager的实现逻辑,会加很多判断逻辑。ViewPager是实现图标翻页的组件,在这个页面的作用就是切换日期时图标随之切换。最终放弃了这种方式,当然也不代表着这种思路实现不了等距不等差的效果。
最终实现等距不等差的效果,是通过将具体数据进行了两次转换。第一次是在数据赋值给柱形图前,将小于70%的数据进行转换;第二次是在展示详情时,将 小于70%的数据转换回原始数值进行展示。
这里需要注意一点,这个图标是倒柱形,不是正常的正柱形,可能会对于转换思路的理解造成一定的困扰。
对数据填充到BarChart前进行转换思路进行解释,转换思路如下图(Figure.1 填充数据转换思路)。不等差的边界在70%,所以先对所有数据进行判断,如果大于70%,则使用原值,如果小于70%,则进行转换,转换逻辑如下,先将柱形展示在等差等距的原始图标上,将展示的柱形拆分成两个部分,一个是70%-100%的柱形高度,由于这部分数据都是小于70%的,所以这部分肯定都会有,第二部分是小于70%的柱形,计算这部分柱形在原始图标中0-70%范围中所占比例,然后计算这个比例在60%-70%这个范围内的柱形高度,最后将计算出来的柱形高度和原来的柱形高度相加,这个相加得到的柱形高度对应的数值,就是在需求的图标中应该展示的柱形。
Figure.1 填充数据转换思路
举例说明,原始数据是56%,拆分成两部分,一部分是代表了70%-100%的30%的柱形高度,一部分是从56%-70%的14%柱形高度,将14%缩小7倍,就是2%,最终得到转换后的柱形高度是32%,对应的Y轴数值应该是68%。
在markerView中会显示柱形的具体Y值,当点击了Y值小于70%的柱形时,在不做转换的情况下,会展示出BarChart的填充数据,也就是被转换过一次的数值。这时候就需要将已转换的值还原为原始数值进行展示。思路其实就是将第一次转换的思路进行逆转,这里以实例进行说明。(Figure.2 转换为原始数据思路)
Figure.2 转换为原始数据思路
如果点击到的柱形填充的Y数值是67%,对应柱形高度是33%,除了70%-100%的柱形高度30%,还有3%的柱形高度在60%-70%之间,这3%柱形高度还原到正常的0-70%的图标中,对应的是21%的柱形高度,将两个柱形高度相加,得到51%的柱形高度,对应的原始数值为49%。
通过对填充数据的两次转换,比较容易实现图标等距不等差的效果,对于后期的维护也比较方便,不需要对基类进行扩展。这种等距不等差的效果不仅对BarChart有效,对于LineChart也一样有效。遇到等距不等差的需求时,应该优先考虑这是实现方式。
最后贴一些主要的代码,这一行是填充数据前的转换(用的是kotlin,不过应该不影响理解):
BarEntry((i.toFloat()) - 0.5f, if (y > -30) y else (-30 (y 30) / 7))
下面的是在详情展示时将Y轴的值转换回原始值:
tvValue.text = when {
entry.y > -30f -> (100 entry.y.toInt()).toString()
else -> (70 (entry.y 30) * 7).toInt().toString()
}
如果还有疑问的可以给我留言,可以互相交流一下。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved