使用 MPAndroidChart 获得 BarDataSet 中的数据

问题描述

在使用 MPAndroidChart 绘制柱状图时,我们可能需要在用户选择某个柱子时获取该柱子所属的 BarDataSet 的数据。然而,MPAndroidChart 并没有提供直接获得 BarDataSet 的方法。

解决方案

为了解决这个问题,我们可以通过自定义一个 BarChartRenderer 来获取 BarDataSet 的数据。

首先,我们需要了解 MPAndroidChart 的绘制原理。MPAndroidChart 使用 Renderer 来负责具体的绘制操作。BarChartRenderer 是 MPAndroidChart 中负责柱状图绘制的 Renderer。

我们可以通过继承 BarChartRenderer 来自定义一个新的 Renderer,并在其中添加获取 BarDataSet 的方法。

以下是具体的步骤:

  1. 创建自定义 Renderer 类

    import com.github.mikephil.charting.animation.ChartAnimator;
    import com.github.mikephil.charting.charts.BarChart;
    import com.github.mikephil.charting.data.BarData;
    import com.github.mikephil.charting.data.BarDataSet;
    import com.github.mikephil.charting.renderer.BarChartRenderer;
    import com.github.mikephil.charting.utils.ViewPortHandler;
    
    public class CustomBarChartRenderer extends BarChartRenderer {
        
        public CustomBarChartRenderer(BarChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
            super(chart, animator, viewPortHandler);
        }
    
        // 添加获取 BarDataSet 的方法
        public BarDataSet getSelectedBarDataSet() {
            if (mViewPortHandler == null || mChart == null || mChart.getBarData() == null) {
                return null;
            }
    
            BarData barData = mChart.getBarData();
            if (barData.getDataSets() == null || barData.getDataSets().size() == 0) {
                return null;
            }
    
            if (mHighlighter == null || mChart.getHighlighter() == null) {
                return null;
            }
    
            int datasetIndex = mChart.getHighlighter().getHighlight().getDataSetIndex();
            return (BarDataSet)barData.getDataSets().get(datasetIndex);
        }
    }
    
  2. 在 BarChart 中使用自定义 Renderer

    import android.content.Context;
    import android.util.AttributeSet;
    
    import com.github.mikephil.charting.charts.BarChart;
    import com.github.mikephil.charting.renderer.RendererFactory;
    
    public class CustomBarChart extends BarChart {
        
        public CustomBarChart(Context context) {
            super(context);
        }
    
        public CustomBarChart(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomBarChart(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void init() {
            super.init();
            mRenderer = new CustomBarChartRenderer(this, mAnimator, mViewPortHandler);
        }
    }
    
  3. 使用自定义的 BarChart

    CustomBarChart barChart = findViewById(R.id.bar_chart);
    BarDataSet selectedDataSet = barChart.getRenderer().getSelectedBarDataSet();
    

通过以上步骤,我们就可以在用户选择某个柱子时获取该柱子所属的 BarDataSet 的数据了。

代码示例

以下是一个完整的示例:

import android.content.Context;
import android.util.AttributeSet;

import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.renderer.BarChartRenderer;
import com.github.mikephil.charting.renderer.RendererFactory;
import com.github.mikephil.charting.utils.ViewPortHandler;

public class CustomBarChart extends BarChart {
    
    public CustomBarChart(Context context) {
        super(context);
    }

    public CustomBarChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomBarChart(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void init() {
        super.init();
        mRenderer = new CustomBarChartRenderer(this, mAnimator, mViewPortHandler);
    }
}

class CustomBarChartRenderer extends BarChartRenderer {
    
    public CustomBarChartRenderer(BarChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
        super(chart, animator, viewPortHandler);
    }

    public BarDataSet getSelectedBarDataSet() {
        if (mViewPortHandler == null || mChart == null || mChart.getBarData() == null) {
            return null;
        }

        BarData barData = mChart.getBarData();
        if (barData.getDataSets() == null || barData.getDataSets().size() == 0) {
            return null;