MPAndroidChart 自定义 MarkerView

1,802 阅读1分钟

MarkerView 顾名思义就是标记视图,点击图表上的数值时一般都需要一个提示框用于显示数值,MPAndroidChart 也提供了对应的接口,setMarker(MarkerView)。 效果图如下:

这边画的比较简陋,布局可以自定义:

一、绘制图表

堆叠柱状图的实现可以参考我的另外一篇文章,MPAndroidChart实现堆叠柱状图

二、自定义 MarkerView

public class MyMarkView extends MarkerView {
  private TextView tv1;
  private TextView tv2;

  public MyMarkView(Context context) {
    super(context, R.layout.mark_view);
    initView();
  }

  private void initView() {
    tv1 = findViewById(R.id.tv1);
    tv2 = findViewById(R.id.tv2);
  }

  @Override
  public void refreshContent(Entry e, Highlight highlight) {
	//更新显示数据,由于是柱状图,所以可以强制转换为BarEntry
    BarEntry barEntry = (BarEntry) e;
    //获取Y值列表
    float[] values = barEntry.getYVals();

    tv1.setText(String.format(Locale.US, "数据1: %.2f", values[0]));
    tv2.setText(String.format(Locale.US, "数据2: %.2f", values[1]));
    super.refreshContent(e, highlight);
  }

  private MPPointF mOffset;

  @Override
  public MPPointF getOffset() {
  	//设置MarkerView的偏移量,就是提示框显示的位置
    if (mOffset == null) {
      // center the marker horizontally and vertically
      mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
    }

    return mOffset;
  }
}

三、添加 MarkerView

初始化图表时,增加以下代码:

    MyMarkView myMarkView = new MyMarkView(this);
    //必须设置,否则MarkerView会超出图表
    myMarkView.setChartView(barChart);
    barChart.setMarker(myMarkView);

四、MarkerView 显示位置

MarkerView 显示位置主要在 getOffsetForDrawingAtPoint 方法中进行计算的,具体源码如下:

    @Override
    public MPPointF getOffsetForDrawingAtPoint(float posX, float posY) {
		//获取我们设置的偏移量
        MPPointF offset = getOffset();
        mOffset2.x = offset.x;
        mOffset2.y = offset.y;
		//获取图表对象,如果没有调用setChartView方法,该chart就为空
        Chart chart = getChartView();
		//获取 MarkerView 的宽和高
        float width = getWidth();
        float height = getHeight();

		//计算最终位置
        if (posX + mOffset2.x < 0) {
            mOffset2.x = - posX;
        } else if (chart != null && posX + width + mOffset2.x > chart.getWidth()) {
            mOffset2.x = chart.getWidth() - posX - width;
        }

        if (posY + mOffset2.y < 0) {
            mOffset2.y = - posY;
        } else if (chart != null && posY + height + mOffset2.y > chart.getHeight()) {
            mOffset2.y = chart.getHeight() - posY - height;
        }

        return mOffset2;
    }

如果想自定义显示位置,直接重写该方法即可。