MPAndroidChart3.0使用詳解(二)----柱狀圖、折線圖、組合圖的使用
上篇主要講到了MPAndroidChart這個開源庫的一些基本特性和基礎設定,現在來講下我們經常要用到的柱狀圖(直方圖)、折線圖和組合圖的使用。
柱狀圖
再講之前,先看效果圖。
第一個是單個柱狀圖,第二個是組合(group)的柱狀圖
使用
1、首先先建立BarChart物件,並初始化,進行些基礎設定
2、為BarChart新增物件,利用BarEntry新增x軸,y軸的資料
3、初始化BarDataSet物件,為BarDataSet新增BarEntry物件
4、初始化BarData物件,為BarData新增BarDataSet
5、為BarChart新增BarData,即BarChart.setData(barData)
這樣就完成了柱狀圖的繪製。
一些BarChart屬性的設定
setDrawValueAboveBar(boolean enabled):// 如果設定為true,在條形圖上方顯示值。如果為false,會顯示在頂部下方。
setDrawBarShadow(boolean enabled):// 是否顯示陰影。啟動它會降低約40%的效能
setDrawValuesForWholeStack(boolean enabled):// 如果設定為true,堆疊條形的所有值會分別繪製,而不僅僅是他們所有的頂部總和。
setDrawHighlightArrow(boolean enabled):// 是否強調繪製箭頭
這裡已經封裝好了一個BarChartManager,使用的時候只用新增資料即可。程式碼如下:
import android.graphics.Color;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
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.interfaces.datasets.IBarDataSet;
import java.util.ArrayList;
import java.util.List;
/**
* Descriptions:柱狀圖管理類
*/
public class BarChartManager {
private BarChart mBarChart;
private YAxis leftAxis;
private YAxis rightAxis;
private XAxis xAxis;
//顏色集合
List<Integer> colors = new ArrayList<>();
public BarChartManager(BarChart barChart) {
this.mBarChart = barChart;
leftAxis = mBarChart.getAxisLeft();
rightAxis = mBarChart.getAxisRight();
xAxis = mBarChart.getXAxis();
colors.add(Color.GREEN);
colors.add(Color.BLUE);
colors.add(Color.RED);
colors.add(Color.CYAN);
initBarChart();
}
/**
* 初始化LineChart
*/
private void initBarChart() {
//背景顏色
mBarChart.setBackgroundColor(Color.WHITE);
//網格
mBarChart.setDrawGridBackground(false);
//背景陰影
mBarChart.setDrawBarShadow(false);
mBarChart.setHighlightFullBarEnabled(false);
//顯示邊界
mBarChart.setDrawBorders(false);
//設定動畫效果
mBarChart.animateY(1000, Easing.EasingOption.Linear);
mBarChart.animateX(1000, Easing.EasingOption.Linear);
//圖表的描述
mBarChart.getDescription().setText("");
//折線圖例 標籤 設定
Legend legend = mBarChart.getLegend();
legend.setForm(Legend.LegendForm.SQUARE);//圖示 標籤的形狀。 正方形
legend.setTextSize(11f);
//顯示位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setDrawInside(false);
//XY軸的設定
//X軸設定顯示位置在底部
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setGranularity(1f);//設定最小的區間,避免標籤的迅速增多
xAxis.setDrawGridLines(false);//設定豎狀的線是否顯示
xAxis.setCenterAxisLabels(true);//設定標籤居中
// xAxis.setSpaceMax(10);
// xAxis.setValueFormatter();
leftAxis.setDrawGridLines(true);//設定橫狀的線是否顯示
leftAxis.enableGridDashedLine(6f, 3f, 0);//虛線
leftAxis.setAxisLineWidth(1f);
leftAxis.setEnabled(true);
leftAxis.setGridColor(0xacb3e5fc);
// leftAxis.setTextColor(0xb3e5fc);//設定左邊Y軸文字的顏色
// leftAxis.setAxisLineColor(0xb3e5fc);//設定左邊Y軸的顏色
// rightAxis.setDrawGridLines(false);//設定橫狀的線是否顯示
rightAxis.setEnabled(false);//隱藏右邊軸和數字
//保證Y軸從0開始,不然會上移一點
leftAxis.setAxisMinimum(0f);
rightAxis.setAxisMinimum(0f);
mBarChart.setDoubleTapToZoomEnabled(false); // 設定為false以禁止通過在其上雙擊縮放圖表。
// mBarChart.setBorderWidth(15);//設定邊界寬度
}
/**
* 展示柱狀圖(一條)
*
* @param xAxisValues
* @param yAxisValues
* @param label
* @param color
*/
public void showBarChart(List<Float> xAxisValues, List<Float> yAxisValues, String label, int color) {
ArrayList<BarEntry> entries = new ArrayList<>();
for (int i = 0; i < xAxisValues.size(); i++) {
entries.add(new BarEntry(xAxisValues.get(i), yAxisValues.get(i)));
}
// 每一個BarDataSet代表一類柱狀圖
BarDataSet barDataSet = new BarDataSet(entries, label);
barDataSet.setColor(color);
barDataSet.setValueTextSize(9f);
barDataSet.setFormLineWidth(1f);
barDataSet.setFormSize(15.f);
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(barDataSet);
BarData data = new BarData(dataSets);
//設定X軸的刻度數
xAxis.setLabelCount(xAxisValues.size()-1 , false);
mBarChart.setData(data);
}
/**
* 展示柱狀圖(多條)
*
* @param xAxisValues
* @param yAxisValues
* @param labels
* @param colours
*/
public void showBarChart(List<Float> xAxisValues, List<List<Float>> yAxisValues, List<String> labels, List<Integer> colours) {
BarData data = new BarData();
// xAxis.setValueFormatter(new StringAxisValueFormatter(xAxisValues));
for (int i = 0; i < yAxisValues.size(); i++) {
ArrayList<BarEntry> entries = new ArrayList<>();
for (int j = 0; j < yAxisValues.get(i).size(); j++) {
entries.add(new BarEntry(xAxisValues.get(i), yAxisValues.get(i).get(j)));
}
BarDataSet barDataSet = new BarDataSet(entries, labels.get(i));
barDataSet.setColor(colours.get(i));
barDataSet.setValueTextColor(colours.get(i));
barDataSet.setValueTextSize(10f);
barDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
data.addDataSet(barDataSet);
}
int amount = yAxisValues.size();
float groupSpace = 0.12f; //柱狀圖組之間的間距
float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet
// (0.2 + 0.02) * 4 + 0.12 = 1.00 -> 組成1個"group"的寬度
xAxis.setLabelCount(xAxisValues.size() - 1, false);
data.setBarWidth(barWidth);
data.groupBars(0, groupSpace, barSpace);
mBarChart.setData(data);
}
protected void showBarChart(List<String> xValues, List<List<Float>> yValuesList,List<String> labels){
mBarChart.getXAxis().setValueFormatter(new StringAxisValueFormatter(xValues));
BarData data = new BarData();
for (int i = 0; i < yValuesList.size(); i++) {
ArrayList<BarEntry> entries = new ArrayList<>();
for (int j = 0; j < yValuesList.get(i).size(); j++) {
entries.add(new BarEntry(i, yValuesList.get(i).get(j)));
}
// y軸的資料集合
BarDataSet barDataSet = new BarDataSet(entries, labels.get(i));
barDataSet.setColor(colors.get(i));
barDataSet.setValueTextColor(colors.get(i));
barDataSet.setValueTextSize(10f);
data.addDataSet(barDataSet);
}
int amount = yValuesList.size();
float groupSpace = 0.12f; //柱狀圖組之間的間距
float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet
// (0.2 + 0.02) * 4 + 0.12 = 1.00 -> interval per "group"
mBarChart.getXAxis().setLabelCount(xValues.size()-1, false);
data.setBarWidth(barWidth);
xAxis.setAxisMaximum(xValues.size());
xAxis.setAxisMinimum(0);
data.groupBars(0, groupSpace, barSpace);
mBarChart.setData(data);
}
protected BarData getBarData(List<String> xValues, List<List<Float>> yValuesList) {
mBarChart.getXAxis().setValueFormatter(new StringAxisValueFormatter(xValues));
BarData data = new BarData();
for (int i = 0; i < yValuesList.size(); i++) {
ArrayList<BarEntry> entries = new ArrayList<>();
for (int j = 0; j < yValuesList.get(i).size(); j++) {
entries.add(new BarEntry(i, yValuesList.get(i).get(j)));
}
// y軸的資料集合
BarDataSet barDataSet = new BarDataSet(entries, xValues.get(i));
barDataSet.setColor(colors.get(i));
barDataSet.setValueTextColor(colors.get(i));
barDataSet.setValueTextSize(10f);
data.addDataSet(barDataSet);
}
int amount = yValuesList.size();
float groupSpace = 0.12f; //柱狀圖組之間的間距
float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet
// (0.2 + 0.02) * 4 + 0.08 = 1.00 -> interval per "group"
mBarChart.getXAxis().setLabelCount(xValues.size()-1, false);
data.setBarWidth(barWidth);
data.groupBars(0, groupSpace, barSpace);
return data;
}
/**
* 設定Y軸值
*
* @param max
* @param min
* @param labelCount
*/
public void setYAxis(float max, float min, int labelCount) {
if (max < min) {
return;
}
leftAxis.setAxisMaximum(max);
leftAxis.setAxisMinimum(min);
leftAxis.setLabelCount(labelCount, false);
rightAxis.setAxisMaximum(max);
rightAxis.setAxisMinimum(min);
rightAxis.setLabelCount(labelCount, false);
mBarChart.invalidate();
}
/**
* 設定X軸的值
*
* @param max
* @param min
* @param labelCount
*/
public void setXAxis(float max, float min, int labelCount) {
xAxis.setAxisMaximum(max);
xAxis.setAxisMinimum(min);
xAxis.setLabelCount(labelCount, false);
mBarChart.invalidate();
}
/**
* 設定高限制線
*
* @param high
* @param name
*/
public void setHightLimitLine(float high, String name, int color) {
if (name == null) {
name = "高限制線";
}
LimitLine hightLimit = new LimitLine(high, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
hightLimit.setLineColor(color);
hightLimit.setTextColor(color);
leftAxis.addLimitLine(hightLimit);
mBarChart.invalidate();
}
/**
* 設定低限制線
*
* @param low
* @param name
*/
public void setLowLimitLine(int low, String name) {
if (name == null) {
name = "低限制線";
}
LimitLine hightLimit = new LimitLine(low, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
leftAxis.addLimitLine(hightLimit);
mBarChart.invalidate();
}
/**
* 設定描述資訊
*
* @param str
*/
public void setDescription(String str) {
Description description = new Description();
description.setText(str);
mBarChart.setDescription(description);
mBarChart.invalidate();
}
}
自定義的X軸資料轉換類
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.util.List;
/*
* Description: x軸資料轉換類
*/
public class StringAxisValueFormatter implements IAxisValueFormatter {
private List<String> xValues;
public StringAxisValueFormatter(List<String> xValues) {
this.xValues = xValues;
}
@Override
public String getFormattedValue(float v, AxisBase axisBase) {
try{
if (v < 0 || v > (xValues.size() - 1)){//使得兩側柱子完全顯示
return "";
}
return xValues.get((int)v);
}catch (Exception e){
return "";
}
}
}
Activity使用的時候:
private void testBarChart() {
BarChartManager barChartManager1 = new BarChartManager(barChart1);
BarChartManager barChartManager2 = new BarChartManager(barChart2);
//設定x軸的資料
ArrayList<String> xValues0 = new ArrayList<>();
xValues0.add("早晨");
xValues0.add("上午");
xValues0.add("中午");
xValues0.add("下午");
xValues0.add("晚上");
//設定x軸的資料
ArrayList<Float> xValues = new ArrayList<>();
for (int i = 1; i < 6; i++) {
xValues.add((float) i);
}
//設定y軸的資料()
List<List<Float>> yValues = new ArrayList<>();
for (int i = 0; i < 4; i++) {
List<Float> yValue = new ArrayList<>();
for (int j = 0; j < 5; j++) {
yValue.add((float) (Math.random() * 8)+2);
}
yValues.add(yValue);
}
//顏色集合
List<Integer> colors = new ArrayList<>();
colors.add(Color.GREEN);
colors.add(Color.BLUE);
colors.add(Color.RED);
colors.add(Color.CYAN);
//線的名字集合
List<String> names = new ArrayList<>();
names.add("柱狀一");
names.add("柱狀二");
names.add("柱狀三");
names.add("柱狀四");
//建立多條柱狀的圖表
barChartManager1.showBarChart(xValues, yValues.get(0), names.get(1), colors.get(3));
barChartManager2.showBarChart(xValues0, yValues,names);
}
折線圖
效果圖如下:
使用
1、初始化LineChart物件,設定基礎屬性
2、初始化Entry物件,新增x軸和y軸資料
3、初始化LineDataSet物件,為其新增Entry
4、初始化LineData物件,為其新增LineDataSet物件
5、設定資料,顯示圖表LineChart.setData(lineData)
一樣的,這裡也封裝了一個折線圖管理類LineChartManager,程式碼如下:
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
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.interfaces.datasets.ILineDataSet;
import java.util.ArrayList;
import java.util.List;
/**
* Descriptions: 折線圖管理類
*/
public class LineChartManager {
private LineChart lineChart;
private YAxis leftAxis; //左邊Y軸
private YAxis rightAxis; //右邊Y軸
private XAxis xAxis; //X軸
public LineChartManager(LineChart mLineChart) {
this.lineChart = mLineChart;
leftAxis = lineChart.getAxisLeft();
rightAxis = lineChart.getAxisRight();
xAxis = lineChart.getXAxis();
initLineChart();
}
/**
* 初始化LineChart
*/
private void initLineChart() {
lineChart.setDrawGridBackground(false);
//顯示邊界
lineChart.setDrawBorders(false);
//設定動畫效果
lineChart.animateY(1000, Easing.EasingOption.Linear);
lineChart.animateX(1000, Easing.EasingOption.Linear);
//折線圖例 標籤 設定
Legend legend = lineChart.getLegend();
legend.setForm(Legend.LegendForm.LINE);
legend.setTextSize(11f);
//顯示位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setDrawInside(false);
//XY軸的設定
//X軸設定顯示位置在底部
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setAxisMinimum(0f);
xAxis.setGranularity(1f);
//保證Y軸從0開始,不然會上移一點
leftAxis.setAxisMinimum(0f);
rightAxis.setAxisMinimum(0f);
rightAxis.setEnabled(false);
// xAxis.setDrawGridLines(false);//不繪製x軸網線
// leftAxis.setDrawGridLines(false);//不繪製Y周網線
}
/**
* 初始化曲線 每一個LineDataSet代表一條線
*
* @param lineDataSet
* @param color
* @param mode 折線圖是否填充
*/
private void initLineDataSet(LineDataSet lineDataSet, int color, boolean mode) {
lineDataSet.setColor(color);
lineDataSet.setCircleColor(color);
lineDataSet.setLineWidth(1f);
lineDataSet.setCircleRadius(3f);
//設定曲線值的圓點是實心還是空心
lineDataSet.setDrawCircleHole(true);
lineDataSet.setValueTextSize(9f);
//設定折線圖填充
lineDataSet.setDrawFilled(mode);//填充曲線下方的區域
lineDataSet.setFormLineWidth(1f);
lineDataSet.setFormSize(15.f);
//線模式為圓滑曲線(預設折線)
lineDataSet.setMode(LineDataSet.Mode.LINEAR);
}
/**
* 展示折線圖(一條)
*
* @param xAxisValues
* @param yAxisValues
* @param label
* @param color
*/
public void showLineChart(List<Float> xAxisValues, List<Float> yAxisValues, String label, int color) {
ArrayList<Entry> entries = new ArrayList<>();
for (int i = 0; i < xAxisValues.size(); i++) {
entries.add(new Entry(xAxisValues.get(i), yAxisValues.get(i)));
}
// 每一個LineDataSet代表一條線
LineDataSet lineDataSet = new LineDataSet(entries, label);
//線模式為圓滑曲線(預設折線)
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
//設定圓心半徑
lineDataSet.setCircleRadius(3f);
//設定曲線值的圓點是實心還是空心
lineDataSet.setDrawCircleHole(false);
initLineDataSet(lineDataSet, color, false);
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(lineDataSet);
LineData data = new LineData(dataSets);
//設定X軸的刻度數
xAxis.setLabelCount(xAxisValues.size());
lineChart.setData(data);
}
public void showLineChart(List<String> xValues,List<Float> yValues,int color){
ArrayList<Entry> entries = new ArrayList<>();
xAxis.setValueFormatter(new StringAxisValueFormatter(xValues));
for (int i = 0; i < xValues.size(); i++) {
entries.add(new Entry( i, yValues.get(i)));
}
// 每一個LineDataSet代表一條線
LineDataSet lineDataSet = new LineDataSet(entries, "折線test");
initLineDataSet(lineDataSet, color, false);
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(lineDataSet);
LineData data = new LineData(dataSets);
//設定X軸的刻度數
xAxis.setLabelCount(xValues.size());
lineChart.setData(data);
}
/**
* 展示線性圖(多條)
*
* @param xAxisValues
* @param yAxisValues 多條曲線Y軸資料集合的集合
* @param labels
* @param colors
*/
public void showLineChart(List<Float> xAxisValues, List<List<Float>> yAxisValues, List<String> labels, List<Integer> colors) {
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
for (int i = 0; i < yAxisValues.size(); i++) {
ArrayList<Entry> entries = new ArrayList<>();
for (int j = 0; j < yAxisValues.get(i).size(); j++) {
// if (j >= xAxisValues.size()) {
// j = xAxisValues.size() - 1;
// }
entries.add(new Entry(xAxisValues.get(j), yAxisValues.get(i).get(j)));
}
LineDataSet lineDataSet = new LineDataSet(entries, labels.get(i));
initLineDataSet(lineDataSet, colors.get(i), false);
dataSets.add(lineDataSet);
}
LineData data = new LineData(dataSets);
xAxis.setLabelCount(xAxisValues.size(), true);
lineChart.setData(data);
}
/**
* 設定Y軸值
*
* @param max
* @param min
* @param labelCount
*/
public void setYAxis(float max, float min, int labelCount) {
if (max < min) {
return;
}
leftAxis.setAxisMaximum(max);
leftAxis.setAxisMinimum(min);
leftAxis.setLabelCount(labelCount, false);
rightAxis.setAxisMaximum(max);
rightAxis.setAxisMinimum(min);
rightAxis.setLabelCount(labelCount, false);
lineChart.invalidate();
}
/**
* 設定X軸的值
*
* @param max
* @param min
* @param labelCount
*/
public void setXAxis(float max, float min, int labelCount) {
xAxis.setAxisMaximum(max);
xAxis.setAxisMinimum(min);
xAxis.setLabelCount(labelCount, true);
lineChart.invalidate();
}
/**
* 設定高限制線
*
* @param high
* @param name
*/
public void setHightLimitLine(float high, String name, int color) {
if (name == null) {
name = "高限制線";
}
LimitLine hightLimit = new LimitLine(high, name);
hightLimit.setLineWidth(2f);
hightLimit.setTextSize(10f);
hightLimit.setLineColor(color);
hightLimit.setTextColor(color);
leftAxis.addLimitLine(hightLimit);
lineChart.invalidate();
}
/**
* 設定低限制線
*
* @param low
* @param name
*/
public void setLowLimitLine(int low, String name) {
if (name == null) {
name = "低限制線";
}
LimitLine hightLimit = new LimitLine(low, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
leftAxis.addLimitLine(hightLimit);
lineChart.invalidate();
}
/**
* 設定描述資訊
*
* @param str
*/
public void setDescription(String str) {
Description description = new Description();
description.setText(str);
lineChart.setDescription(description);
lineChart.invalidate();
}
}
x軸資料轉換類程式碼就不貼了,柱狀圖上面有。
Activity中使用
/**
* 測試折線圖
*/
private void testLineChart() {
LineChartManager lineChartManager1 = new LineChartManager(lineChart1);
LineChartManager lineChartManager2 = new LineChartManager(lineChart2);
//設定x軸的資料
ArrayList<Float> xValues = new ArrayList<>();
for (int i = 0; i < 10; i++) {//10組資料
xValues.add((float) i);
}
//設定y軸的資料()
List<List<Float>> yValues = new ArrayList<>();
for (int i = 0; i < 4; i++) {
List<Float> yValue = new ArrayList<>();
for (int j = 0; j < 10; j++) {
yValue.add((float) (Math.random() * 80));
}
yValues.add(yValue);
}
//顏色集合
List<Integer> colors = new ArrayList<>();
colors.add(Color.GREEN);
colors.add(Color.BLUE);
colors.add(Color.RED);
colors.add(Color.CYAN);
//線的名字集合
List<String> names = new ArrayList<>();
names.add("折線一");
names.add("折線二");
names.add("折線三");
names.add("折線四");
//建立單條折線的圖表
lineChartManager1.showLineChart(xValues, yValues.get(0), names.get(0), colors.get(0));
lineChartManager1.setYAxis(100, 0, 11);
lineChartManager1.setDescription("溫度");
// lineChartManager1.setXAxis(10,0,xValues.size());
lineChartManager1.setHightLimitLine(70,"高溫報警",Color.RED);
//建立多條折線的圖表
// lineChartManager2.showLineChart(xValues, yValues, names, colors);
// lineChartManager2.setYAxis(100, 0, 11);
lineChartManager2.showLineChart(xValues, yValues, names, colors);
lineChartManager2.setYAxis(100, 0, 11);
lineChartManager2.setDescription("溫度");
}
組合圖
組合圖CombinedChart。這裡主要是折線圖和柱狀圖的組合形式
效果圖如下:
xml檔案
<com.github.mikephil.charting.charts.CombinedChart
android:id="@+id/combine_chart2"
android:layout_width="match_parent"
android:layout_height="250dp"/>
這裡也封裝了一個CombinedChart工具類,CombinedChartManager程式碼如下:
public class CombinedChartManager {
private CombinedChart mCombinedChart;
private YAxis leftAxis;
private YAxis rightAxis;
private XAxis xAxis;
public CombinedChartManager(CombinedChart combinedChart) {
this.mCombinedChart = combinedChart;
leftAxis = mCombinedChart.getAxisLeft();
rightAxis = mCombinedChart.getAxisRight();
xAxis = mCombinedChart.getXAxis();
}
/**
* 初始化Chart
*/
private void initChart() {
//不顯示描述內容
mCombinedChart.getDescription().setEnabled(false);
mCombinedChart.setDrawOrder(new CombinedChart.DrawOrder[]{
CombinedChart.DrawOrder.BAR,
CombinedChart.DrawOrder.LINE
});
mCombinedChart.setBackgroundColor(Color.WHITE);
mCombinedChart.setDrawGridBackground(false);
mCombinedChart.setDrawBarShadow(false);
mCombinedChart.setHighlightFullBarEnabled(false);
//顯示邊界
mCombinedChart.setDrawBorders(true);
//圖例說明
Legend legend = mCombinedChart.getLegend();
legend.setWordWrapEnabled(true);
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setDrawInside(false);
//Y軸設定
rightAxis.setDrawGridLines(false);
rightAxis.setAxisMinimum(0f);
leftAxis.setDrawGridLines(false);
leftAxis.setAxisMinimum(0f);
mCombinedChart.animateX(2000); // 立即執行的動畫,x軸
}
/**
* 設定X軸座標值
*
* @param xAxisValues x軸座標集合
*/
public void setXAxis(final List<String> xAxisValues) {
//設定X軸在底部
XAxis xAxis = mCombinedChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setGranularity(1f);
xAxis.setLabelCount(xAxisValues.size() - 1,false);
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return xAxisValues.get((int) value % xAxisValues.size());
}
});
mCombinedChart.invalidate();
}
/**
* 得到折線圖(一條)
*
* @param lineChartY 折線Y軸值
* @param lineName 折線圖名字
* @param lineColor 折線顏色
* @return
*/
private LineData getLineData(List<Float> lineChartY, String lineName, int lineColor) {
LineData lineData = new LineData();
ArrayList<Entry> yValue = new ArrayList<>();
for (int i = 0; i < lineChartY.size(); i++) {
yValue.add(new Entry(i, lineChartY.get(i)));
}
LineDataSet dataSet = new LineDataSet(yValue, lineName);
dataSet.setColor(lineColor);
dataSet.setCircleColor(lineColor);
dataSet.setValueTextColor(lineColor);
dataSet.setCircleSize(1);
//顯示值
dataSet.setDrawValues(true);
dataSet.setValueTextSize(10f);
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lineData.addDataSet(dataSet);
return lineData;
}
/**
* 得到折線圖(多條)
*
* @param lineChartYs 折線Y軸值
* @param lineNames 折線圖名字
* @param lineColors 折線顏色
* @return
*/
private LineData getLineData(List<List<Float>> lineChartYs, List<String> lineNames, List<Integer> lineColors) {
LineData lineData = new LineData();
for (int i = 0; i < lineChartYs.size(); i++) {
ArrayList<Entry> yValues = new ArrayList<>();
for (int j = 0; j < lineChartYs.get(i).size(); j++) {
yValues.add(new Entry(j, lineChartYs.get(i).get(j)));
}
LineDataSet dataSet = new LineDataSet(yValues, lineNames.get(i));
dataSet.setColor(lineColors.get(i));
dataSet.setCircleColor(lineColors.get(i));
dataSet.setValueTextColor(lineColors.get(i));
dataSet.setCircleSize(1);
dataSet.setDrawValues(true);
dataSet.setValueTextSize(10f);
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lineData.addDataSet(dataSet);
}
return lineData;
}
/**
* 得到柱狀圖
*
* @param barChartY Y軸值
* @param barName 柱狀圖名字
* @param barColor 柱狀圖顏色
* @return
*/
private BarData getBarData(List<Float> barChartY, String barName, int barColor) {
BarData barData = new BarData();
ArrayList<BarEntry> yValues = new ArrayList<>();
for (int i = 0; i < barChartY.size(); i++) {
yValues.add(new BarEntry(i, barChartY.get(i)));
}
BarDataSet barDataSet = new BarDataSet(yValues, barName);
barDataSet.setColor(barColor);
barDataSet.setValueTextSize(10f);
barDataSet.setValueTextColor(barColor);
barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
barData.addDataSet(barDataSet);
//以下是為了解決 柱狀圖 左右兩邊只顯示了一半的問題 根據實際情況 而定
xAxis.setAxisMinimum(-0.5f);
xAxis.setAxisMaximum((float) (barChartY.size()- 0.5));
return barData;
}
/**
* 得到柱狀圖(多條)
*
* @param barChartYs Y軸值
* @param barNames 柱狀圖名字
* @param barColors 柱狀圖顏色
* @return
*/
private BarData getBarData(List<List<Float>> barChartYs, List<String> barNames, List<Integer> barColors) {
List<IBarDataSet> lists = new ArrayList<>();
for (int i = 0; i < barChartYs.size(); i++) {
ArrayList<BarEntry> entries = new ArrayList<>();
for (int j = 0; j < barChartYs.get(i).size(); j++) {
entries.add(new BarEntry(j, barChartYs.get(i).get(j)));
}
BarDataSet barDataSet = new BarDataSet(entries, barNames.get(i));
barDataSet.setColor(barColors.get(i));
barDataSet.setValueTextColor(barColors.get(i));
barDataSet.setValueTextSize(10f);
barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lists.add(barDataSet);
}
BarData barData = new BarData(lists);
int amount = barChartYs.size(); //需要顯示柱狀圖的類別 數量
float groupSpace = 0.12f; //柱狀圖組之間的間距
float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet
// (0.2 + 0.02) * 4 + 0.12 = 1.00 即100% 按照百分百佈局
//柱狀圖寬度
barData.setBarWidth(barWidth);
//(起始點、柱狀圖組間距、柱狀圖之間間距)
barData.groupBars(0, groupSpace, barSpace);
return barData;
}
/**
* 顯示混合圖(柱狀圖+折線圖)
*
* @param xAxisValues X軸座標
* @param barChartY 柱狀圖Y軸值
* @param lineChartY 折線圖Y軸值
* @param barName 柱狀圖名字
* @param lineName 折線圖名字
* @param barColor 柱狀圖顏色
* @param lineColor 折線圖顏色
*/
public void showCombinedChart(
List<String> xAxisValues, List<Float> barChartY, List<Float> lineChartY
, String barName, String lineName, int barColor, int lineColor) {
initChart();
setXAxis(xAxisValues);
CombinedData combinedData = new CombinedData();
combinedData.setData(getBarData(barChartY, barName, barColor));
combinedData.setData(getLineData(lineChartY, lineName, lineColor));
mCombinedChart.setData(combinedData);
mCombinedChart.invalidate();
}
/**
* 顯示混合圖(柱狀圖+折線圖)
*
* @param xAxisValues X軸座標
* @param barChartYs 柱狀圖Y軸值
* @param lineChartYs 折線圖Y軸值
* @param barNames 柱狀圖名字
* @param lineNames 折線圖名字
* @param barColors 柱狀圖顏色
* @param lineColors 折線圖顏色
*/
public void showCombinedChart(
List<String> xAxisValues, List<List<Float>> barChartYs, List<List<Float>> lineChartYs,
List<String> barNames, List<String> lineNames, List<Integer> barColors, List<Integer> lineColors) {
initChart();
setXAxis(xAxisValues);
CombinedData combinedData = new CombinedData();
combinedData.setData(getBarData(barChartYs, barNames, barColors));
combinedData.setData(getLineData(lineChartYs, lineNames, lineColors));
mCombinedChart.setData(combinedData);
mCombinedChart.invalidate();
}
}
但是用到組合圖的時候,遇到一個問題,就是一個組合圖中柱狀圖可以設定group,但是對應的折線圖只有一個值,這個問題github上也有人發過相應的issues,作者PhilJay本人說在3.0的版本中已經解決,但是也沒看到例子。現在我採用的是一個比較蠢的方法,用幾個第一個圖的效果“拼”出所需的效果,假如你有其他更好的方法,或者如果有人會用所說的新屬性的話,煩請告訴我一聲,不勝感激。