天天看点

CombinedChart 实现单个柱形图+折线图

  • 实现默认选中
  • 实现选中不可取消
  • 实现渐变色
  • 等等不慢慢看api还真不好搞啊
package com.xxmassdeveloper.mpchartexample;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.github.mikephil.charting.charts.CombinedChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.CombinedData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.Fill;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ManagerChartActivity extends DemoBase {

    private CombinedChart dataChart;//图表
    private CombinedData data; //组合图表数据
    private Highlight mHighlight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_manager_chart);

        setContentView(R.layout.activity_manager_chart);
        dataChart = (CombinedChart) findViewById(R.id.manager_chart);
        showDataOnChart();//设置数据
        Legend legend = dataChart.getLegend();
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);

        dataChart.setTouchEnabled(true);
        dataChart.getLegend().setEnabled(false);//隐藏图例
        dataChart.setDoubleTapToZoomEnabled(false);//不能双击放大
        dataChart.setScaleYEnabled(false);

        dataChart.setHighlightPerDragEnabled(true);//禁止通过拖拽高亮

        dataChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
            @Override
            public void onValueSelected(Entry e, Highlight h) {

                Log.d("点击"," "+e.getX()+" H : "+h.toString()+" 位置 ");


//                dataChart.highlightValue(h);
                mHighlight = h;

            }

            @Override
            public void onNothingSelected() {
                Log.d("点击 onNothingSelected"," ");
                //不允许取消
                if (mHighlight != null)
                    dataChart.highlightValue(mHighlight);
            }
        });

        IBarDataSet iBarDataSet = data.getBarData().getDataSetByIndex(0);
        BarEntry barEntry = iBarDataSet.getEntryForIndex(8);//默认选中九月柱形图
        //获取柱形图数据
        dataChart.highlightValue(barEntry.getX(),barEntry.getY(),0,1,true);

    }

    @Override
    protected void saveToGallery() {

    }

    /**
     * 展示数据
     */
    private void showDataOnChart() {
        //绘制图表数据
        data = new CombinedData();
        //设置柱状图数据
        data.setData(getBarData());
        //设置折线图数据
        data.setData(getLineData());

        dataChart.setData(data);
        //设置横坐标数据
        setAxisXBottom();
        //设置右侧纵坐标数据
        setAxisYRight();
        //设置左侧纵坐标数据
        setAxisYLeft();
//        dataChart.setTouchEnabled(false);
        dataChart.getDescription().setEnabled(false);
        dataChart.setDrawGridBackground(false);
        dataChart.setDrawBarShadow(false);

//        dataChart.setHighlightFullBarEnabled(true);
        dataChart.animateX(2000);
    }

    /**
     * 设置横坐标数据
     */
    private void setAxisXBottom() {
        String[] date = {"1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"};
        List<String> valuesX = new ArrayList<>(Arrays.asList(date));

        XAxis bottomAxis = dataChart.getXAxis();
        bottomAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        bottomAxis.setCenterAxisLabels(true);//标签绘制在中间
        bottomAxis.setDrawGridLines(false);//不️绘制网格线
        bottomAxis.setValueFormatter(new IndexAxisValueFormatter(valuesX));//设置底部数据
        bottomAxis.setAxisMinimum(data.getXMin());          //设置x轴最小值
        bottomAxis.setAxisMaximum(data.getXMax() + 0.5f);   //设置x轴最大值
        bottomAxis.setLabelCount(date.length);              //设置标签的数量
        bottomAxis.setAxisLineColor(Color.parseColor("#F6F8FA"));//设置轴线颜色
        bottomAxis.setAxisLineWidth(3); //设置轴线宽度
        bottomAxis.setTextColor(Color.parseColor("#364258"));
        //在放大时为轴设置最小的间隔。坐标轴不允许低于这个极限。这可以用来避免标签复制时,放大。
        bottomAxis.setGranularity(1f);

    }

    /**
     * 设置右侧纵坐标数据
     */
    private void setAxisYRight() {
        YAxis right = dataChart.getAxisRight();
        right.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return value + "℃";
            }
        });
        right.setAxisMinimum(0f);//为坐标轴设置最小值
        right.setDrawGridLines(false);
        right.setEnabled(false);
    }

    /**
     * 设置左侧纵坐标数据
     */
    private void setAxisYLeft() {
        YAxis left = dataChart.getAxisLeft();
        left.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return value + "ml";
            }
        });
        left.setDrawGridLines(false);
        left.setAxisMinimum(0f);//为坐标轴设置最小值
        left.setEnabled(false);
    }

    /**
     * 设置折线图绘制数据
     * 温度
     * @return
     */
    public LineData getLineData() {
        LineData lineData = new LineData();
        List<Entry> customCounts = new ArrayList<>();
        float[] data = {10.0f, 2.2f, 3.3f, 4.5f, 6.3f, 10.2f, 20.3f, 23.4f, 25.0f, 16.5f, 12.0f, 6.2f};
        //人数
        for (int i = 0; i < data.length; i++) {
            customCounts.add(new Entry(i + 0.5f,data[i]));
        }
        LineDataSet lineDataSet = new LineDataSet(customCounts,"平均温度");
        lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
        lineDataSet.setColor(Color.parseColor("#44D7C8"));
        lineDataSet.setCircleColor(Color.parseColor("#44D7C8"));
        lineDataSet.setCircleRadius(4);
        lineDataSet.setLineWidth(2);
        lineDataSet.setValueTextSize(12);
        lineDataSet.setValueTextColor(Color.parseColor("#44D7C8"));
        lineDataSet.setDrawVerticalHighlightIndicator(true);  //去除十字线
        lineDataSet.setDrawHorizontalHighlightIndicator(true);//去除十字线

        lineDataSet.setMode(LineDataSet.Mode.LINEAR);//设置曲线链接
        lineDataSet.setDrawValues(false);

        lineData.addDataSet(lineDataSet);
        lineData.setHighlightEnabled(false);//关闭折线图的高亮
        return lineData;
    }

    /**
     * 设置柱状图绘制数据
     *
     * @return
     */
    public BarData getBarData() {
        BarData barData = new BarData();
        //总量金额
        List<BarEntry> amounts = new ArrayList<>();
        float[] z = {12.0f, 4.9f, 7.0f, 23.2f, 25.6f, 76.7f, 135.6f, 162.2f, 32.6f, 20.0f, 6.4f, 3.3f};
        //平均金额
        List<BarEntry> averages = new ArrayList<>();
        float[] j = {80f, 80f, 80f, 80f, 80f, 80f, 80f, 80f, 80f, 80f, 80f, 80f};
        //添加数据
        for (int i = 0; i < z.length; i++) {
            amounts.add(new BarEntry(i,z[i]));
            averages.add(new BarEntry(i,j[i]));

        }

        int startColor1 = ContextCompat.getColor(this, R.color.red_start);
//        int startColor2 = ContextCompat.getColor(this, R.color.red_start2);
        int endColor1 = ContextCompat.getColor(this, R.color.red_end);
//        int endColor2 = ContextCompat.getColor(this, R.color.red_end2);

        List<Fill> gradientFills = new ArrayList<>();
        gradientFills.add(new Fill(startColor1, endColor1));
//        gradientFills.add(new Fill(startColor2, endColor2));

        //设置总数的柱状图
        BarDataSet amountBar = new BarDataSet(amounts,"蒸发量");
        amountBar.setAxisDependency(YAxis.AxisDependency.LEFT);
//        amountBar.setColor(Color.parseColor("#C23531"));
        amountBar.setDrawValues(false);
        amountBar.setFills(gradientFills);//设置柱状图颜色
        amountBar.setHighLightColor(ContextCompat.getColor(this,R.color.red_end));//设置高亮颜色
        amountBar.setHighLightAlpha(200);

        //设置平均的柱状图
        BarDataSet averageBar = new BarDataSet(averages,"降水量");
        averageBar.setAxisDependency(YAxis.AxisDependency.LEFT);
        averageBar.setColor(Color.parseColor("#2F4554"));
//        amountBar.setFills(gradientFills);//设置柱状图颜色
        averageBar.setDrawValues(false);

        amountBar.setValueTextSize(10);
        averageBar.setValueTextSize(10);


        barData.addDataSet(amountBar);//添加一个柱状图的数据
//        barData.addDataSet(averageBar);//暂时不加第二个柱子
        //设置柱状图显示的大小
        float groupSpace = 0.4f;
        float barSpace = 0.4f;
        float barWidth = 0.2f;
        barData.setBarWidth(barWidth);

        barData.groupBarsNew(0, groupSpace, barSpace);
        return barData;
    }
}
           

BarData.java 新加方法

其实只是把前三行代码去掉

public void groupBarsNew(float fromX, float groupSpace, float barSpace) {

//        int setCount = mDataSets.size();
//        if (setCount <= 1) {
//            throw new RuntimeException("BarData needs to hold at least 2 BarDataSets to allow grouping.");
//        }

        IBarDataSet max = getMaxEntryCountSet();//获取数量最多柱状图数据集

        int maxEntryCount = max.getEntryCount();//获取数量

        float groupSpaceWidthHalf = groupSpace / 2f;// 组间距
        float barSpaceHalf = barSpace / 2f; //状态条间距
        float barWidthHalf = mBarWidth / 2f;//一半的宽度

        float interval = getGroupWidth(groupSpace, barSpace);//绘制一组数据需要的长度
        //遍历最大数量
        for (int i = 0; i < maxEntryCount; i++) {

            float start = fromX;
            fromX += groupSpaceWidthHalf;//加一半groupSpace
            //遍历数据集
            for (IBarDataSet set : mDataSets) {

                fromX += barSpaceHalf;//加上一半的barSpace
                fromX += barWidthHalf;//加上一半的barWidth

                if (i < set.getEntryCount()) {

                    BarEntry entry = set.getEntryForIndex(i);//获取对应的柱状图条

                    if (entry != null) {
                        entry.setX(fromX);//设置起点
                    }
                }

                fromX += barWidthHalf;//加上一半的barWidth
                fromX += barSpaceHalf;//加上一半的barSpace
            }

            fromX += groupSpaceWidthHalf;//加一半groupSpace
            float end = fromX;
            float innerInterval = end - start; //一组数据的长度

            float diff = interval - innerInterval;//剩余空间

            // correct rounding errors
            if (diff > 0 || diff < 0) {
                fromX += diff;
            }
        }

        notifyDataChanged();
    }
           

这是一个不错的教程