MPAndroidChart 修改柱状图高亮效果

MPAndroidChart 默认的选中高亮效果如下:

在这里插入图片描述
只是颜色加深,然后设计想要实现下面这种效果:

在这里插入图片描述
类似阴影效果,且显示的宽度需要增加。

一、MPAndroidChart 是否支持

查看该框架对外的接口,发现下面两个方法:

 BarDataSet set1 = new BarDataSet(yValues, "");
 set1.setHighLightColor(ContextCompat.getColor(this, R.color.black));
 set1.setHighLightAlpha(40);

只能修改高亮颜色和透明度,没有办法修改宽度和高度,无法达到我们想要的效果。
没有办法,只能先查看源码是如何实现,然后尝试去修改了。

二、查看源码实现

setHighLightAlpha() 方法入手:

//BarDataSet.java
    public void setHighLightAlpha(int alpha) {
        mHighLightAlpha = alpha;
    }

    @Override
    public int getHighLightAlpha() {
        return mHighLightAlpha;
    }

查看 getHighLightAlpha() 方法在哪里调用:

//BarChartRenderer.java
    @Override
    public void drawHighlighted(Canvas c, Highlight[] indices) {

        BarData barData = mChart.getBarData();

        for (Highlight high : indices) {

            IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex());
            ......
            prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() / 2f, trans);

            setHighlightDrawPos(high, mBarRect);
            //原来高亮背景就是绘制了一个矩形
            c.drawRect(mBarRect, mHighlightPaint);
        }
    }

从源码中可以看出,点击效果就是通过点击位置,重新绘制一个矩形。
所以重点就是 mBarRect 的赋值。

//BarChartRenderer.java
    protected void prepareBarHighlight(float x, float y1, float y2, float barWidthHalf, Transformer trans) {

        float left = x - barWidthHalf;
        float right = x + barWidthHalf;
        float top = y1;
        float bottom = y2;

        mBarRect.set(left, top, right, bottom);

        trans.rectToPixelPhase(mBarRect, mAnimator.getPhaseY());
    }

可以看到只要复写该方法,修改参数,就可以修改高亮矩形框的宽高。

三、代码实现

3.1 重写 BarChartRenderer 类

查看源码,可以发现 BarChartRenderer 的初始化位置,且支持自定义:

//BarChart.java
    @Override
    protected void init() {
        super.init();
		//初始化地方
        mRenderer = new BarChartRenderer(this, mAnimator, mViewPortHandler);

        setHighlighter(new BarHighlighter(this));

        getXAxis().setSpaceMin(0.5f);
        getXAxis().setSpaceMax(0.5f);
    }
    //支持开发者自定义
    public void setRenderer(DataRenderer renderer) {

        if (renderer != null)
            mRenderer = renderer;
    }

自定义 BarChartRenderer

public class TestBarChartRenderer extends BarChartRenderer {

  private Transformer transformer;

  public TestBarChartRenderer(
      BarDataProvider chart,
      ChartAnimator animator,
      ViewPortHandler viewPortHandler) {
    super(chart, animator, viewPortHandler);
  }

  @Override
  protected void prepareBarHighlight(float x, float y1, float y2, float barWidthHalf,
      Transformer trans) {
    transformer = trans;
    //修改高亮效果的高度和宽度,getYChartMax获取的就是表格的最大值
    super.prepareBarHighlight(x, mChart.getYChartMax(), y2, barWidthHalf + 0.2f, trans);
  }

}

//设置自定义Renderer
barChart.setRenderer(
        new TestBarChartRenderer(barChart, barChart.getAnimator(), barChart.getViewPortHandler()));
//点击整条数据高亮
barChart.setHighlightFullBarEnabled(true);


上面修改后虽然效果实现了,但是会导致一个问题,点击数据后,所有的数据的标记视图都在同一高度:

在这里插入图片描述
在这里插入图片描述
查看源码发现:

//BarChartRenderer.java
    @Override
    public void drawHighlighted(Canvas c, Highlight[] indices) {

        BarData barData = mChart.getBarData();

        for (Highlight high : indices) {

            IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex());
            ......
            prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() / 2f, trans);
			//修改高亮数据
            setHighlightDrawPos(high, mBarRect);
            //原来高亮背景就是绘制了一个矩形
            c.drawRect(mBarRect, mHighlightPaint);
        }
    }

 protected void setHighlightDrawPos(Highlight high, RectF bar) {
 		//这个位置会影响标记视图的显示位置
        high.setDraw(bar.centerX(), bar.top);
    }

所以在 prepareBarHighlight() 方法中修改完数据后,需要在 setHighlightDrawPos() 方法中还原真实的数据。最终代码如下:

public class TestBarChartRenderer extends BarChartRenderer {

  private Transformer transformer;

  public TestBarChartRenderer(
      BarDataProvider chart,
      ChartAnimator animator,
      ViewPortHandler viewPortHandler) {
    super(chart, animator, viewPortHandler);
  }

  @Override
  protected void prepareBarHighlight(float x, float y1, float y2, float barWidthHalf,
      Transformer trans) {
    transformer = trans;
    //修改高亮背景的高度和宽度
    super.prepareBarHighlight(x, mChart.getYChartMax(), y2, barWidthHalf + 0.2f, trans);
  }

  @Override
  protected void setHighlightDrawPos(Highlight high, RectF bar) {
    if (transformer != null) {
      //还原真实的点击数据
      float barWidthHalf = mChart.getBarData().getBarWidth() / 2f;
      float x = high.getX();
      RectF rectF = new RectF();
      rectF.set(x - barWidthHalf, high.getY(), x + barWidthHalf, 0f);

      transformer.rectToPixelPhase(rectF, mAnimator.getPhaseY());

      super.setHighlightDrawPos(high, rectF);

    } else {
      super.setHighlightDrawPos(high, bar);
    }
  }
}

柱状图的实现可以参考:
MPAndroidChart实现堆叠柱状图
MPAndroidChart 自定义 MarkerView

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值