Charts: 停止轴标签重复。

创建于 2015-08-24  ·  51评论  ·  资料来源: danielgindi/Charts

在应用程序中,我遇到了一个问题,即BarChartViewLineChartView的左轴上的标签重复。

我首先添加了下面的代码片段,以确保轴上的标签数量不超过 y 数据中的最大值。

self.chartView.leftAxis.labelCount = self.chartView.data.yMax > YAxisMaxLabelCount ? YAxisMaxLabelCount : self.chartView.data.yMax;

这确保了如果 y 数据中的最大值是3 ,那么轴内只会有3标签。 现在,如果图形不是交互式的,即用户无法缩放图表,这可以正常工作。

一旦用户明显缩放,标签的数量保持不变,值格式化程序会填补空白,允许值重复。

_没有重复值的轴示例_
screen shot 2015-08-24 at 5 07 29 pm

_相同图表但放大的示例_
screen shot 2015-08-24 at 5 07 54 pm

屏幕截图显示左轴重复值2 。 您对解决这个重复标签问题的最佳建议是什么? 任何帮助将不胜感激。 如果您需要任何进一步的信息,请告诉我。

谢谢

最有用的评论

这是在 2.2.4 中发布的,作为granularity功能

所有51条评论

我猜这不是重复的标签,而是包含十进制值和整数格式化程序? 您需要检查每个 x 轴标签的原始值是什么,以及在 y 轴渲染器中绘制 xAxis 标签时如何格式化它。

我可以通过添加一个检查来确保每个标签的间隔始终是一个整数值来做到这一点。
更改在ChartYAxisRenderer类的computeAxisValues()函数内

var interval = ChartUtils.roundToNextSignificant(number: Double(rawInterval))
if(_yAxis.valueFormatter?.maximumFractionDigits == 0)
{
    interval = interval < 1 ? 1 : floor(interval)
}

如果值格式化程序要求没有小数位,那么它会降低间隔,如果它小于整数1 ,它将间隔设置为1

你想要一个拉取请求吗?

谢谢你的帮助。

如果您有十进制值,为什么 maximumFractionDigits 为 0? 我认为这是格式化程序问题。

我不想要十进制值,这就是我设置maximumFractionDigits = 0的原因

朋友,您的数据是十进制的,您只想使用格式化程序放弃小数位数,这没有意义。 为什么不先将数据转换为整数?

我给图表的 y 值是

(1, 3, 2, 0, 0, 7, 0)

一旦我创建了ChartDataSet ,这些值就会翻倍。

ChartDataSet, label: , 7 entries:
ChartDataEntry, xIndex: 0, value 1.0
ChartDataEntry, xIndex: 1, value 3.0
ChartDataEntry, xIndex: 2, value 2.0
ChartDataEntry, xIndex: 3, value 0.0
ChartDataEntry, xIndex: 4, value 0.0
ChartDataEntry, xIndex: 5, value 7.0
ChartDataEntry, xIndex: 6, value 0.0

这是因为您的ChartDataEntry类将值保存为Double

/// the actual value (y axis)
public var value = Double(0.0)

尽管值已更改为两倍,但图表确实首先显示了正确的标签增量,但一旦图表放大, ChartYAxisRenderer希望填补空白,并且我的值格式化程序删除了任何它显示为重复值的小数位数。

我不希望图表假设我想要整数之间的附加值,因为只想显示整数的标签。

所以这让我看到我正在向图表提供正确的数据,但图表正在对我想要做的事情做出假设。 这对于默认值来说很好,但也应该提供仅在轴上显示整数的选项。

通过添加对值格式化程序的检查,它允许这种行为。 您可能知道提供此行为的更好方法,而不是检查值格式化程序,但这是我想要的一些人的用例。

我刚刚注意到我在提交 a7e30dd16fbfaecb8e44c01ad8618a3a745fd101 处使用代码库,并且当此更改实施到 Charts 的最新提交时,它不会按预期运行。

您能否建议如何最好地实现我想要的行为?

我附上了预期行为的 gif。

您可以在下面看到没有标签显示相同的值,并且图表没有尝试在其他标签之间放置任何标签,因为要求标签是整个值。

chart

啊,我明白了。 如果您缩放到 [3,4],则范围将是 [3,4],并且轴想要显示 [3.0, 3.2, 3.4, 3.6, 3.8, 4.0],并且您不想要小数位数,是吗?

其实我也无能为力...因为你的数据很小,我们要在那里显示4-6个标签...如果范围是[0,1],你需要显示5个标签,怎么办?你显示的不是小数位数吗?

我认为如果范围太小,显示小数位数是可以的,但如果你真的不想要它,那么你可以像你一样做。 或者你会接受只显示名为showOnlyMinMaxEnabled的最大和最小标签

顺便说一句,您的屏幕截图效果很好,解决了您的问题

还有一些属性可以帮助您限制标签数量。 您可以尝试修改并适合不同的比例级别。

    public func setLabelCount(count: Int, force: Bool)
    {
        _labelCount = count

        if (_labelCount > 25)
        {
            _labelCount = 25
        }
        if (_labelCount < 2)
        {
            _labelCount = 2
        }

        forceLabelsEnabled = force
    }

要在 Y 轴上具有相同的行为,需要设置 Y 缩放限制。 第382章

388

@steprescott ,#388 解决了你的问题吗?

通过查看问题 #388 的提交,唯一的变化是视口上的新属性。

我将如何获得 gif 中显示的预期行为但您的更改?

@steprescott ,尝试使用 [_chartView.viewPortHandler setMaximumScaleY: 2.f]; 例如,像这样缩放的粒度不会太大而无法显示重复值。 一个很好的例子是当你有一个没有限制的水平字符线时,当缩放很大时所有 Y 值都会重复。 使用MaximumScaleY 这种重复不会发生。

无限制:
screen shot 2015-09-22 at 23 29 16

限制为 2f:
screen shot 2015-09-22 at 23 30 07

嘿@noais

这适用于具有较大范围值的数据集,但如果您的值范围较小,例如值为 0 - 7 的数组,则放大 2 倍可能会提供重复的标签。

尽管通过限制缩放因子解决了您的问题,但它并不能解决重复整数值的问题。

在编辑指向提交 a7e30dd16fbfaecb8e44c01ad8618a3a745fd101 的ChartYAxisRenderer类时,我确实得到了预期的结果。

这是通过降低价值来完成的。

var interval = ChartUtils.roundToNextSignificant(number: Double(rawInterval))
if(_yAxis.valueFormatter?.maximumFractionDigits == 0)
{
    interval = interval < 1 ? 1 : floor(interval)
}

虽然这有效(但在使用此 repo 的 HEAD 时无效)我觉得你们会知道在您的框架内有一个更好的位置来放置它以提供与 gif 中所示相同的结果。

可能是轴上的属性allowRepeatingValues BOOL 。 你们会更清楚的。

是的,你说得对,这是一种解决方法。 让我试试看是否容易创建像 allowRepeatingValues 这样的方法。

这将是最有帮助的,谢谢。

@noais和@liuxuan30。 你有机会对此进行调查吗? 我能够使用框架获得所需的效果,但我不知道该属性在框架中的最佳位置,以及是否有更好的方法来实现相同的结果。

谢谢你的时间。

我仍然认为这是因为生成带有小数字的重复标签的格式化程序,而不是算法。 如果删除格式化程序,它将正确显示数字,对吗?
你可以用你的代码解决它,但我不确定它是否适合每个人。
@danielgindi你怎么看

大家好,为allowRepeatingValues 投票,我的数字很小,不想显示重复的y 轴值

当我所有的值都为零时,我会得到这些重复的轴标签-
chart

另外,我注意到虽然我的代码片段可以满足我的需要,但它并没有删除重复值,只是只允许整数。 因此,通过检查数字格式化程序并不是一种可怕的添加方式。

该片段不允许删除重复值,因此如果值是1.1, 1.2, 1.2, 1.3并且您希望保留单个十进制数字,它将不起作用。 你们将知道此功能的最佳位置和实现,以及人们花时间查看框架的当前问题并为他们投票,这表明它也是其他人想要的选项。

允许重复值:+1:

@noais @liuxuan30你有比我建议的更好的解决方案吗?

不,除了allowRepeatingValues ..因为你原来的问题是关于格式化程序。 您不希望十进制数字处于某个级别,但您的数据实际上具有下一个级别

理想情况下,图表不应显示重复值! 是否可以通过某种逻辑隐藏重复值,从而仅产生唯一值?

@vigyanhoon背后不是“重复”值,而是格式化程序导致值被“重复”。 如果不想重复,给个十进制格式化器就可以解决。

@liuxuan30你能解释一下“_给一个十进制格式化程序_”是什么意思吗? 使用我的数据,我提供了一个设置maximumFractionDigits = 0的格式化程序。 我不确定如何通过目前的情况获得预期的结果? 您是否能够使用该框架生成一个图表,它给出的结果与我在 8 月 28 日发布的 gif 相同?

您的意思是使用 numberFormatter.allowsFloats = NO,如果是,它对我没有帮助,我仍然看到重复的 INT?! 我设法不显示重复值的唯一方法是在 xAxis(顶部/底部)上使用 2 个标签

@steprescott抱歉,如果我不清楚。 MaximumFractionDigits不能为0,否则只会显示整数部分。 我确实遇到过类似的问题,如果数据范围很小并且需要 5~6 个标签,则给 maximumFractionDigits = 0 将具有重复值。 我想没有简单的方法可以解决这个问题。 想想如果数据范围是[0,2],我要显示5个标签:0、0.4、0.8、1.2、1.6、2.0。 如果我们应用 maximumFractionDigits = 0,它可能是 0、0、1、1、2、2

@injectios ,MaximumFractionDigits = 2 甚至 4 怎么样?

嘿大家!
我有同样的问题。

@ liuxuan30取决于数据的类型,有小数是没有意义的。 就像人类图表一样,你永远不会有 1.5 个人类,要么是 1,要么是 2。

@jpros你得到了一点,但从数学角度来看,我们不能在 [0,2] 范围内有 4 个没有小数的标签。

所以要么打开yAxis.showOnlyMinMaxEnabled以避免重复值作为现在的工作,
或者你实现你的逻辑来计算你自己的价值在ChartYAxisRenderer.computeAxis以避免,
或者我们必须等待功能“allowRepeatValues”

@PhilJay我们目前有什么解决方案吗? :-)

从 Android(和 ofc iOS)POV,此行在这里: https ://github.com/PhilJay/MPAndroidChart/blob/master/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRenderer.java#L108

可能是解决这个问题的地方。 计算了float interval的轴标签,如果两个标签的格式相同,则可以使用它来防止对标签的进一步更改。
这正是我快速思考时想到的。 你怎么看?

我通过设置最大值摆脱了重复

leftAxis.customAxisMax = maxYLabelCount

@vigyanhoon这是完全不同的事情,价值可能是数百万,而 maxYLabelCount 不能。 customAxisMax 是定义轴范围的最大值。

+1 用于解决渲染问题。 我还有一个人的图表,我有 [0, 0, 1, 1, 2, 2]。 将numberFormatter.maximumFractionDigits设置为 0 以外的任何值都没有任何意义。

@steprescott建议的以下代码也为我修复了。 我在这里的叉子中添加了它:

https://github.com/natanrolnik/ios-charts/commit/01df4d9264e0adbef4db88763075376f4a0f255c

PR 能解决这个问题吗? 你觉得@danielgindi @liuxuan30 @steprescott怎么样? 是否存在此代码无法修复的情况? 如果是这样,有什么更好的解决方案?

@natanrolnik如果用户放大并且范围变为 [25.2, 25.3] 怎么办? 间隔应该是 1.0,而应该是 0.02。
如果用户专门将最大分数数设置为 0 应该会有所帮助,我们会限制间隔。 我没有测试负值。
我们还没有更好的解决方案,但我猜像“allowRepeatValues”这样的功能是我们能想到的?

我同意allowRepeatedValues

我认为@steprescott是一个很好的解决方案。 只需要将值一调整为粒度变量。

有了这个@liuxuan30问题就不再存在了。

如果我们将这段代码放在 ChartYAxisRenderer 的第 75 行:

interval = interval < granuality ? granuality : interval       

https://github.com/noais/ios-charts/compare/master...Noais
你怎么看?

好的,所以现在关闭了,但它没有合并到 master 中。 这可能会在什么时候发生?

这是在 2.2.4 中发布的,作为granularity功能

我不确定我是否应该在这里发布这个问题,但这对我来说很有意义。

我的 xAxis 标签有一个非常相似的问题。 我有一个自定义的 IAxisValueFormatter,它返回时间字符串,它为某些图表提供像这样的“22:00”、“23:00”这样的时间,像这样的“周一”、“周四”这样的工作日。 给别人等等。。

当图表放大太多时,值开始重复,如下所示:

Screenshot 2019-07-19 at 17 59 11

在这种情况下, granularity功能不起作用,因为它适用于数字之间的差异。

您对我如何阻止这些标签重复有任何想法吗?

谢谢

将粒度启用设置为对我来说是错误的工作
leftAxis.granularityEnabled = true

大家好,我想让 xAxis 值在放大时不重复
我的格式化程序:
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
让日期 = 日期(timeIntervalSince1970:值)
返回 date.formattedString(withDateFormat: .daymonth)
}
我也使用粒度,但我仍然有同样的问题
xAxis.granularity = 1.0
xAxis.granularityEnabled = true

谁能知道如何解决它?

@艾梅克
我有同样的问题,你找到解决方案了吗?

当我强制 x 轴标签计数并绘制几个点时,我遇到了同样的问题。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

brytnvmg picture brytnvmg  ·  4评论

Bharati555 picture Bharati555  ·  4评论

newbiebie picture newbiebie  ·  3评论

guanyanlin picture guanyanlin  ·  3评论

guoyutaog picture guoyutaog  ·  3评论