如何将文本值放在MPAndroidChart圈中?

时间:2016-03-04 04:55:42

标签: android mpandroidchart

我正在开发一个基于图表的应用程序,我正在使用MPAndroidChart库,我需要将文本值放在圈内,我试图显示,谢谢你是否有任何相关的建议,

我附上了与该问题相关的屏幕截图。我需要这样做

enter image description here

但我得到这样的图片:

enter image description here

再次感谢您帮助解决此问题,



 ArrayList<Entry> e1 = new ArrayList<Entry>();

        float[] values = new float[]{48, 59, 79, 29, 39, 50, 60};
        for (int i = 0; i < values.length; i++) {
            e1.add(new Entry(values[i], i, "line3"));

        }
        int[] color = {Color.parseColor("#D13385"),    Color.parseColor("#37D04E"), Color.parseColor("#33D1D1"),  Color.parseColor("#D1C933")};
        LineDataSet d1 = new LineDataSet(e1, "" + cnt);
        d1.setColors(color);
        d1.setLineWidth(3.0f);
        d1.setCircleSize(7.0f);
        d1.setDrawValues(true);      
        d1.setCircleColor(Color.parseColor("#891e9a"));
        d1.setCircleColorHole(Color.parseColor("#891e9a"));
        d1.setDrawHighlightIndicators(false);
        d1.setDrawFilled(false);
        d1.setFillAlpha(20);     
        d1.setHighlightLineWidth(50f);
        d1.setValueTextSize(10f);
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:1)

目前不可能更改默认情况下绘制值的位置。您将不得不修改库以获得该行为。

答案 1 :(得分:0)

有点&#34; hacky&#34;,但我已经设法实现了这样的布局。您通过创建两组数据并将它们附加到同一图表来提供。一组(让我们称之为&#34;点&#34;)包含您需要显示为点的数据。第二个(&#34;行&#34;)向下偏移一点(y值减去一些实验选择的值)。现在你可以设置不显示&#34;行&#34;和#34;点&#34;的行,&#34;点&#34;没有值标签。 &#34; line&#34;和白色标签通过实验性地来回移动你的y值,你可以在一个图表的顶部实现重叠值标签(&#34;点&#34;将被&#34;行&#34;值覆盖)。

更新: 实际上,我提供的答案更优雅,我已经提供了!使用突出显示[]并创建高光数组。

   highlihts = new Highlight[values_dots.size()];

  for (int i = 0; i < values_dots.size(); i++) {
    Highlight h = new Highlight(values_dots.get(i).getX(),values_dots.get(i).getY(), 0);
    highlihts[i] = h;
  }
  chart.highlightValues(highlihts);

在CustomMarkerView类位置标记中,如:

  @Override
    public MPPointF getOffset() {
      return new MPPointF(-(getWidth() / 2), -(getHeight() / 2));
    }

动臂

P.S。 Philipp Jahoda,很棒的图书馆!

答案 2 :(得分:0)

有一种简单的方法可以做到这一点 定制制造商视图

标记视图

public class MyMarkerView extends MarkerView {

private final TextView tvContent;

public MyMarkerView(Context context, int layoutResource) {
    super(context, layoutResource);

    tvContent = findViewById(R.id.tvContent);
}

// runs every time the MarkerView is redrawn, can be used to update the
// content (user-interface)
@SuppressLint("SetTextI18n")
@Override
public void refreshContent(Entry e, Highlight highlight) {

    if (e instanceof CandleEntry) {

        CandleEntry  ce = (CandleEntry) e;

        tvContent.setText(Utils.formatNumber(ce.getHigh(), 0, true)+(ce.getData()));
    } else {

        tvContent.setText(Utils.formatNumber(e.getY(), 0, true)+"\n  "+(e.getData()));
    }

    super.refreshContent(e, highlight);
}

@Override
public MPPointF getOffset() {
    return new MPPointF(-(getWidth() / 2), -getHeight());
}

} 最后在你的活动中

 values.add(new Entry(i, val,"Custom message per value"));

预览就像 example screen shot

答案 3 :(得分:0)

有一个简单的方法可以做到这一点

定制制造商视图

<TextView
    android:id="@+id/tvContent"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="7dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:text=""
    android:textSize="12sp"
    android:textColor="@android:color/white"
    android:ellipsize="end"
    android:singleLine="true"
    android:textAppearance="?android:attr/textAppearanceSmall" />

标记视图类

public class MyMarkerView extends MarkerView {

private final TextView tvContent;

public MyMarkerView(Context context, int layoutResource) {
    super(context, layoutResource);

    tvContent = findViewById(R.id.tvContent);
}

// runs every time the MarkerView is redrawn, can be used to update the
// content (user-interface)
@SuppressLint("SetTextI18n")
@Override
public void refreshContent(Entry e, Highlight highlight) {

    if (e instanceof CandleEntry) {

        CandleEntry  ce = (CandleEntry) e;

        tvContent.setText(Utils.formatNumber(ce.getHigh(), 0, true)+(ce.getData()));
    } else {

        tvContent.setText(Utils.formatNumber(e.getY(), 0, true)+"\n  "+(e.getData()));
    }

    super.refreshContent(e, highlight);
}

@Override
public MPPointF getOffset() {
    return new MPPointF(-(getWidth() / 2), -getHeight());
}

} 最后在你的活动中

 values.add(new Entry(i, val,"Custom message per value"));

预览就像 example screen shot

答案 4 :(得分:0)

有两种可能:

(1) 不太好:移动标签位置的 y 值

  • 两组数据,一组用于文本,一组用于线条(包括圆圈)
  • 修改具有恒定偏移量的文本值的 y 位置

优点:简单

缺点:偏移量并不总是恒定的 (see offset is not always similar)

(2) 更好:覆盖 LineChartRenderer 中的 drawValues 方法

在 LineChartRenderer.java -> drawValues 中,文本被这一行垂直移动:

drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));

所以要去掉“-valOffset”:

1.覆盖 drawValues 方法

创建一个新的java文件“CenteredTextLineChartRenderer.java”并覆盖LineChartRenderer中的drawValues方法

2.修改y-valOffset为y+textHeight*0.35f

添加 float textHeight = dataSet.getValueTextSize();

public class CenteredTextLineChartRenderer extends LineChartRenderer {

public CenteredTextLineChartRenderer(LineDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
    super(chart, animator, viewPortHandler);
}

//Modified drawValues Method
// Center label on coordinate instead of applying a valOffset

@Override
public void drawValues(Canvas c) {

    if (isDrawingValuesAllowed(mChart)) {

        List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();

        for (int i = 0; i < dataSets.size(); i++) {

            ILineDataSet dataSet = dataSets.get(i);

            float textHeight = dataSet.getValueTextSize();

            if (!shouldDrawValues(dataSet) || dataSet.getEntryCount() < 1)
                continue;

            // apply the text-styling defined by the DataSet
            applyValueTextStyle(dataSet);

            Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

            // make sure the values do not interfear with the circles
            int valOffset = (int) (dataSet.getCircleRadius() * 1.75f);

            if (!dataSet.isDrawCirclesEnabled())
                valOffset = valOffset / 2;

            mXBounds.set(mChart, dataSet);

            float[] positions = trans.generateTransformedValuesLine(dataSet, mAnimator.getPhaseX(), mAnimator
                    .getPhaseY(), mXBounds.min, mXBounds.max);
            ValueFormatter formatter = dataSet.getValueFormatter();

            MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
            iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
            iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);

            for (int j = 0; j < positions.length; j += 2) {

                float x = positions[j];
                float y = positions[j + 1];

                if (!mViewPortHandler.isInBoundsRight(x))
                    break;

                if (!mViewPortHandler.isInBoundsLeft(x) || !mViewPortHandler.isInBoundsY(y))
                    continue;

                Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);

                if (dataSet.isDrawValuesEnabled()) {
                    //drawValue(c, formatter.getPointLabel(entry), x, y - valOffset, dataSet.getValueTextColor(j / 2));
                    drawValue(c, formatter.getPointLabel(entry), x, y+textHeight*0.35f, dataSet.getValueTextColor(j / 2));
                }

                if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {

                    Drawable icon = entry.getIcon();

                    Utils.drawImage(
                            c,
                            icon,
                            (int)(x + iconsOffset.x),
                            (int)(y + iconsOffset.y),
                            icon.getIntrinsicWidth(),
                            icon.getIntrinsicHeight());
                }
            }

            MPPointF.recycleInstance(iconsOffset);
        }
    }
}

}

3.将您自己的 LineChart 渲染器设置为您修改后的 drawValues 类

LineChart mChart = (LineChart) mainActivity.findViewById(R.id.LineChart);

mChart.setRenderer(new CenteredTextLineChartRenderer(mChart,mChart.getAnimator(),mChart.getViewPortHandler()));
  1. 运行您的代码并手动调整 CenteredTextLineChartRenderer 类中的 0.35f 偏移

Now your text is always vertically centered!

重要提示:删除 valOffset 后,您的标签不会垂直居中,因为文本锚点不在文本标签的中心。所以你必须手动插入一个偏移量“textHeight*0.35f”(试试看)。但是方法 (2) 的一大优点是文本始终以相同的偏移量居中,例如在横向模式和其他屏幕尺寸上...