接上文Android开发之基于MPAndroidChart实现股票K线图(二),实现了最基本的K线图效果后,接下来要做的事便是引入移动平均线。
1 介绍
移动平均线(Moving Average,简称MA),它是将某一段时间的收盘价之和除以该周期。 比如日线MA5指5天内的收盘价除以5 。通常情况下,日K线图和平均线放在同一张图里分析,最简单的分析思路就是 比较证券价格移动平均线与证券自身价格的关系。当证券价格上涨,高于其移动平均线,则产生购买信号。当证券价格下跌,低于其移动平均线,则产生出售信号。
在每日K线图上常出现的是5日均线(MA5)、10日均线(MA10)、20日均线(MA20)三种。
2 代码思路
现在的需求就是 使用MPAndroidChart在画出日K线图和移动平均线,也就是说 要在同一个坐标系下,同时画出K线图(CandleStickChart
)和折线图(LineChart
)。而框架提供了一个强大的CombinedChart
让我们去绘制这种组合图形。
public class CombinedChart
This chart class allows the combination of lines, bars, scatter and candle data all displayed in one chart area.
CombinedChart
和CandleStickChart
以及LineChart
的使用方式差不多。都是通过chart.setData()
方法将数据以及相关设置传递到图表中并展示出来。
public class CombinedChart{
......
public void setData(CombinedData data)
}
那么关键就是如何去构建这个CombinedData
实例。
public Class CombinedData{
......
void setData(BarData data)
void setData(BubbleData data)
void setData(CandleData data)
void setData(LineData data)
void setData(ScatterData data)
}
可以发现,CombinedData
可以通过简单的setData方法来设置我们在CombinedChart
中要显示的图表数据。
那么,代码流程如下:
- 构建好
CandleData
以及LineData
- 通过
CombinedData.setData(CandleData data)
和CombinedData.setData(LineData data)
完成组合图中的数据模型构建 - 最后通过
CombinedChart.setData(CombinedData data)
便轻松绘制出日K线图+移动平均线的股票价格图表!
3 核心代码
First of all,在Activity的布局中中加入CombinedChart
:
- 构建CandleData
private CandleData generateCandleData() {
List candleEntries = Model.getCandleEntries();
CandleDataSet set = new CandleDataSet(candleEntries, "");
set.setAxisDependency(YAxis.AxisDependency.LEFT);
set.setShadowWidth(0.7f);
set.setDecreasingColor(Color.RED);
set.setDecreasingPaintStyle(Paint.Style.FILL);
set.setIncreasingColor(Color.GREEN);
set.setIncreasingPaintStyle(Paint.Style.STROKE);
set.setNeutralColor(Color.RED);
set.setShadowColorSameAsCandle(true);
set.setHighlightLineWidth(0.5f);
set.setHighLightColor(Color.WHITE);
set.setDrawValues(false);
CandleData candleData = new CandleData(xVals);
candleData.addDataSet(set);
return candleData;
}```
2. 指定数据、线颜色、标签生成LineDataSet
private LineDataSet generateLineDataSet(List
LineDataSet set = new LineDataSet(entries, label);
set.setColor(color);
set.setLineWidth(1f);
set.setDrawCubic(true);//圆滑曲线
set.setDrawCircles(false);
set.setDrawCircleHole(false);
set.setDrawValues(false);
set.setHighlightEnabled(false);
set.setAxisDependency(YAxis.AxisDependency.LEFT);
return set;
}
3. 构建LineData:MA5\MA10\MA20三条折线图对应不同的数据和折线颜色(这些通过LineDataSet指定),所以传入一个LineDataSet数组来构建LineData
private LineData generateMultiLineData(LineDataSet... lineDataSets) {
List
for (int i = 0; i < lineDataSets.length; i++) {
dataSets.add(lineDataSets[i]);
}
LineData data = new LineData(xVals, dataSets);
return data;
}```
- 构建CombineData
private void loadChartData() {
mChart.resetTracking();
candleEntries = Model.getCandleEntries();//模拟获取日K图数据集合
itemcount = candleEntries.size();
List stockBeans = Model.getData();
xVals = new ArrayList<>();//X轴坐标集合
for (int i = 0; i < itemcount; i++) {
xVals.add(stockBeans.get(i).getDate());
}
CombinedData combinedData = new CombinedData(xVals);
/*k line*/
candleData = generateCandleData();
combinedData.setData(candleData);//加入K线图数据
/*ma5*/
ArrayList ma5Entries = new ArrayList();
for (int index = 0; index < itemcount; index++) {
ma5Entries.add(new Entry(stockBeans.get(index).getMa5(), index));
}
/*ma10*/
ArrayList ma10Entries = new ArrayList();
for (int index = 0; index < itemcount; index++) {
ma10Entries.add(new Entry(stockBeans.get(index).getMa10(), index));
}
/*ma20*/
ArrayList ma20Entries = new ArrayList();
for (int index = 0; index < itemcount; index++) {
ma20Entries.add(new Entry(stockBeans.get(index).getMa20(), index));
}
lineData = generateMultiLineData(//包含三种折线图的LineData
generateLineDataSet(ma5Entries, colorMa5, "ma5"),
generateLineDataSet(ma10Entries, colorMa10, "ma10"),
generateLineDataSet(ma20Entries, colorMa20, "ma20"));
combinedData.setData(lineData);//加入MA5\MA10\MA20三种折线图数据
}
- 大功告成
做完以上的数据初始化工作以后,只剩最后一步,更新CombinedChart:
mChart.setData(combinedData);//当前屏幕会显示所有的数据
mChart.animateX(1500);
4 总结
强大的MPAndroidChart库 支持绘制多种图表,不同的Chart
之间的设置方法基本一致,setData()
万变不离其宗。
5 Demo源码
github_KLineChartDemo