在 MPAndroidChart 库中,如何在长时将 X 轴标签包装成两行?

Posted

技术标签:

【中文标题】在 MPAndroidChart 库中,如何在长时将 X 轴标签包装成两行?【英文标题】:In MPAndroidChart Library, How to wrap X Axis Labels to two lines when long? 【发布时间】:2015-12-07 04:06:35 【问题描述】:

我试图显示 X 轴标签以在它们很长时转到 2 行。如何在 LineChart 中实现这一点?请参阅下面的屏幕截图。我想要时间去二线而不是呆在约会旁边

【问题讨论】:

也就是说,当日期和时间太长时,您想要在日期和时间之间换行?你打算如何检测/定义它是否太长? @Ultimater - 我在想可能取决于字符数。 @NinjaCoder,你找到办法了吗? @FelipeMosso 我不认为这是可能的 :( 您找到解决方案了吗? @NinjaCoder 【参考方案1】:

这看起来像是您必须通过根据您的需要修改库来实现自己的东西。

目前默认情况下无法在 x 轴上有多条线。因此,原因是 android Canvas 不能简单地绘制一个字符串,例如像这样"Line 1\nLine2" 两行。

【讨论】:

【参考方案2】:

我修改了库以允许在 xAxis 上使用多行标签 \n

https://github.com/fabriziogueli/MPAndroidChart/tree/axis_multiline_labels

它现在可以工作,但需要进一步测试,也许还需要一些代码样式/调整。

XAxis xAxis = mChart.getXAxis();
xAxis.setMultiLineLabel(true);

然后您可以使用例如这样的 SimpleDateFormat:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy\nHH:mm a");

也许您必须为图表设置额外的底部偏移:

mChart.setExtraBottomOffset(50);

【讨论】:

您能否在答案中包含您使用的类中的一些 sn-ps?我假设您必须以某种方式修改渲染器,也许是 Utils 是的,我修改了 XAxisRenderer 和 Utils 类。您可以在此处查看更改:github.com/fabriziogueli/MPAndroidChart/commit/… 这很好用,希望它会尽快合并到主项目中!反正有没有使文本居中?现在,它是左对齐的,这看起来很奇怪。谢谢! @Bourne 你是对的,对齐有问题。我修好了它。在此处查看新版本:github.com/fabriziogueli/MPAndroidChart/tree/…。 @fabriziogueli 太棒了,效果很好!我只想提醒任何想要使用它的人,第二行仍然与第一行对齐,因此它不是以每行为中心的。这可能会采用一个更强大的解决方案,其中包含多个字符串(可能是数组列表)?但是当前的对齐修复使它变得更好,而且,就我的目的而言,我只需在第二行添加一个额外的空格就可以使它看起来非常好(即我使用“MMM d\n yyyy”而不是“ MMM d\nyyyy").【参考方案3】:

对于像我这样想要实现这一目标但保留原始库的人,这里有一个受@fgueli 修改启发的简单解决方案。这仅适用于一个换行符(在您的标签中添加“\n”),但您可以轻松地将其调整为您的需求。

    XAxisRenderer 的子类

    public class CustomXAxisRenderer extends XAxisRenderer 
        public CustomXAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer trans) 
             super(viewPortHandler, xAxis, trans);
        
    
        @Override
        protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) 
            String line[] = formattedLabel.split("\n");
            Utils.drawXAxisValue(c, line[0], x, y, mAxisLabelPaint, anchor, angleDegrees);
            Utils.drawXAxisValue(c, line[1], x + mAxisLabelPaint.getTextSize(), y + mAxisLabelPaint.getTextSize(), mAxisLabelPaint, anchor, angleDegrees);
        
    
    

    在所需图表上设置此渲染器

    lineChart.setXAxisRenderer(new CustomXAxisRenderer(lineChart.getViewPortHandler(), lineChart.getXAxis(), lineChart.getTransformer(YAxis.AxisDependency.LEFT)));
    

    享受吧!

【讨论】:

请在您的答案中包含情节而不是链接,稍后链接可能会断开,您的答案将不完整 @Ibo 很抱歉,但我不能:你还不能在你的帖子中嵌入图片,所以我们提供了一个链接。只要您在网站上获得 10 声望,您就可以嵌入图片。 当设置 LEFT YAxis 以启用 false 以隐藏它时,此解决方案不适用于 Horizo​​ntalBarChart。当使用 RIGHT YAxis 获取变压器时,它会给出12-19 18:46:19.631 10003-10003/com.aegisisc.samplecharts A/libc: Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 10003 (sc.samplecharts) @RahulParihar,只是增加视口偏移量,所以可以看到第二行,如下所示:chart.setViewPortOffsets(0, 0, 0, getResources().getDimensionPixelSize(R.dimen.radiobutton_size));在我的情况下,radiobutton_size 为 36dp(文本大小为 8dp) 顺便说一句,如果想要使多行文本居中(因此 line[0] 将高于 line[0] 居中),他不应该使用Utils.drawXAxisValue(c, line[1], x + mAxisLabelPaint.getTextSize(), y + mAxisLabelPaint.getTextSize(), mAxisLabelPaint, anchor, angleDegrees);,而是使用Utils.drawXAxisValue(c, line[1], x, y + mAxisLabelPaint.getTextSize(), mAxisLabelPaint, anchor, angleDegrees);【参考方案4】:

无需偏移x坐标。对于多行场景,代码应该是

@Override
protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) 
    String lines[] = formattedLabel.split("\n");
    for (int i = 0; i < lines.length; i++) 
        float vOffset = i * mAxisLabelPaint.getTextSize();
        Utils.drawXAxisValue(c, lines[i], x, y + vOffset, mAxisLabelPaint, anchor, angleDegrees);
    

【讨论】:

【参考方案5】:

使用@Guillaume Jounel 答案,然后添加:

XAxis xAxis = lineChart.getXAxis();    
xAxis.setLabelRotationAngle(-30f);

【讨论】:

【参考方案6】:

@Guillaume Jounel 答案的改进版本支持多个换行符,以及不带换行符的字符串。

@Override
protected void drawLabel(Canvas c, String formattedLabel, float x, float y,
                             MPPointF anchor, float angleDegrees) 
String line[] = formattedLabel.split("\n");
Utils.drawXAxisValue(c, line[0], x, y, mAxisLabelPaint, anchor, angleDegrees);
    for (int i = 1; i < line.length; i++)  // we've already processed 1st line
         Utils.drawXAxisValue(c, line[i], x, y + mAxisLabelPaint.getTextSize() * i,
             mAxisLabelPaint, anchor, angleDegrees);
    

【讨论】:

这很好用,但我需要在图表下方添加额外的空间,如下所示:chart.setExtraOffsets(0.toFloat(), 0.toFloat(), 0.toFloat(), xLabelExtraHeight) 我可以用这种方法将drawable添加到文本中吗?【参考方案7】:

在下面的水平条形图中解决了这个问题。

class CustomXAxisRenderer(viewPortHandler: ViewPortHandler?, xAxis: XAxis?, trans: Transformer?, chart: HorizontalBarChart) : XAxisRendererHorizontalBarChart(viewPortHandler, xAxis, trans, chart) 
    override fun drawLabel(c: Canvas?, formattedLabel: String, x: Float, y: Float, anchor: MPPointF?, angleDegrees: Float) 
        val line: List<String> = formattedLabel.split("\n")
        Utils.drawXAxisValue(c, line[0], x, y, mAxisLabelPaint, anchor, angleDegrees)
        for (i in 1 until line.size) 
            Utils.drawXAxisValue(c, line[i], x, y + mAxisLabelPaint.textSize * i,
                mAxisLabelPaint, anchor, angleDegrees)
        
    

并调用如下

barChart.setXAxisRenderer(CustomXAxisRenderer(barChart.viewPortHandler, xAxis, barChart.getTransformer(yAxis.axisDependency), barChart))

【讨论】:

在这个标签的起始偏移量是错误的,你能帮帮我吗?

以上是关于在 MPAndroidChart 库中,如何在长时将 X 轴标签包装成两行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中使用 MPAndroidChart 自定义饼图?

MPAndroidChart - 如何在最后一个条目中绘制圆圈?

mpandroidchart - 如何避免 Y 轴中的重复值?

MPAndroidChart:如何以固定间隔设置 x 轴标签

在 MPAndroidChart 条形图中为条形设置不同的颜色

在 MPAndroidChart 中,如何将 X 轴标签分成两条线?对使用任何修改后的库不感兴趣