MPAndroidChart是Android平臺上一款強大易用的圖表庫竖幔,支持線狀圖板乙、柱狀圖、散點圖等八種圖表類型和縮放赏枚、拖動(平移)亡驰、選擇等手勢晓猛,還支持動畫和高亮等功能饿幅。但是別人給好的功能畢竟只能滿足一般功能,一個程序員最基本的能力就應(yīng)該是根據(jù)需求做出自定義的功能了戒职,這里我對MPAndroidChart進(jìn)行一些改造栗恩,MPAndroidChart只能在節(jié)點繪制圓形,現(xiàn)在要給它加上繪制叉號的功能洪燥。另外磕秤,本來MPAndroidChart的背景只能設(shè)置整個一大塊背景乳乌,現(xiàn)在我加上了按行設(shè)置背景色的功能。
效果如圖:
節(jié)點的細(xì)節(jié)部分:
功能實現(xiàn)
繼承LineChart
自定義LineChart的第一步是要繼承LineChart市咆,實現(xiàn)其構(gòu)造方法汉操。然后重寫onDraw方法,在onDraw方法中,再繪制背景蒙兰,繪制叉號磷瘤,繪制圖表。這里要注意繪制的順序搜变,從下到上采缚,一層層疊加。
/**
* 重寫onDraw方法挠他,注意繪制順序扳抽,先繪制背景色,再繪制叉號殖侵,最后繪制圖表
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
drawBgColor(canvas);
drawCross(canvas);
super.onDraw(canvas);
Log.i(TAG, "onDraw");
}
畫背景
為了讓代碼看起來更直觀贸呢,我先創(chuàng)建了一個類BgColor,其中包含start拢军,stop和color三個屬性贮尉。
/**
* Created by xiaoniu on 2017/4/10.
* BgColor是設(shè)置背景的單位,創(chuàng)建時需要傳入起點和終點的值,還有要設(shè)置的顏色
* 如要把縱坐標(biāo)20-40的背景設(shè)為紅色朴沿,就新建一個BgColor
* new BgColor(20猜谚,40,Color.RED)
*/
public class BgColor {
/**
* @param start 起始點
* @param stop 結(jié)束點
* @param color 顏色
*/
public BgColor( float start, float stop,int color) {
this.start = stop;
this.stop = start;
this.color = color;
}
private float start;
private float stop;
private int color;
public float getStart() {
return start;
}
public void setStart(float start) {
this.start = start;
}
public float getStop() {
return stop;
}
public void setStop(float stop) {
this.stop = stop;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
}
三個屬性分別對應(yīng)起始點赌渣,結(jié)束點和顏色魏铅。然后將自己需要設(shè)置的背景都放到一個List中。
/**
* 分段背景設(shè)置
* @return 每條背景的組合
*/
private ArrayList<BgColor> getBg() {
ArrayList<BgColor> bgList = new ArrayList<>();
bgList.add(new BgColor(10, 20, Color.YELLOW));//參數(shù)信息:縱坐標(biāo)從0到20設(shè)置顏色為黃色
bgList.add(new BgColor(20, 40, 0xFF00FF00));//支持16進(jìn)制顏色
bgList.add(new BgColor(40, 70, Color.BLUE));
bgList.add(new BgColor(70, 80, Color.RED));
return bgList;
}
別忘了給圖表設(shè)置繪制背景的屬性坚芜,之后再把數(shù)據(jù)傳給圖表览芳。
//給表格背景添加顏色
mChart.setDrawBgColor(true);
//設(shè)置背景顏色的屬性
mChart.setBgColor(getBg());
而在自定義LineChart的drawBgColor方法中,就是從List中取出每個BgColor鸿竖,獲得其start和stop沧竟,再根據(jù)MPAndroidChart提供的能夠?qū)D表上的值轉(zhuǎn)換為像素坐標(biāo)點的方法getPixelForValues,得到需要繪制背景的左下角和右上角的坐標(biāo)缚忧,用canvas畫矩形就可以了悟泵。
private void drawBgColor(Canvas canvas) {
if (enableDrawBgColor) {
if (!bgList.isEmpty()) {
Paint paint = new Paint();
for (BgColor r : bgList
) {
MPPointD pStart = this.getPixelForValues(this.getXChartMin(), r.getStart(), YAxis.AxisDependency.LEFT);//左下角
MPPointD pStop = this.getPixelForValues(this.getXChartMax(), r.getStop(), YAxis.AxisDependency.LEFT);//右上角
paint.setColor(r.getColor());
canvas.drawRect(new RectF((float) pStart.x, (float) pStart.y, (float) pStop.x, (float) pStop.y), paint);
}
}else {
Log.i(TAG, "No BgColor to Draw");
}
}
}
畫叉號
畫叉號之前要得到節(jié)點的數(shù)據(jù),同樣是利用getPixelForValues將圖表上的值轉(zhuǎn)化為像素坐標(biāo)點
private void drawCross(Canvas canvas) {
if (enableDrawCross) {
if (this.getData() != null) {
LineDataSet set = (LineDataSet) this.getData().getDataSetByIndex(0);
list = set.getValues();
set.setDrawCircles(false);
LineData data = new LineData(set);
this.setData(data);
for (Entry e : list
) {
MPPointD p = this.getPixelForValues(e.getX(), e.getY(), YAxis.AxisDependency.LEFT);
drawNode(canvas, (float) p.x, (float) p.y);
}
}else{
Log.i(TAG, "No Data to Draw");
}
}
}
畫叉號就是繪制兩個互相垂直的直線糕非,有了像素坐標(biāo)點和canvas也就很簡單了。
private void drawNode(Canvas canvas, float x, float y) {
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(crossWidth);
canvas.drawLine(x - crossLength / 2, y - crossLength / 2, x + crossLength / 2, y + crossLength / 2, paint);
canvas.drawLine(x - crossLength / 2, y + crossLength / 2, x + crossLength / 2, y - crossLength / 2, paint);
}
END
細(xì)節(jié)比較粗糙朽肥,以后再完善,歡迎評論交流衡招。
最后附上github代碼:https://github.com/xiaoniu/CrossNodeLineChart