KChart for Android ;股票k线图
- 支持macd,kdj,rsi,boll多种指标切换,支持横竖屏切换,支持长按,缩放,滑动,fling事件等。
<com.github.tifezh.kchartlib.chart.KChartView
android:id="@+id/kchart_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
</com.github.tifezh.kchartlib.chart.KChartView>
<com.github.tifezh.kchartlib.chart.KChartView
android:id="@+id/kchart_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:kc_text_size="@dimen/chart_text_size"
app:kc_text_color="#787878"
app:kc_line_width="@dimen/chart_line_width"
app:kc_background_color="#FFF"
app:kc_selected_line_color="#B1B2B6"
app:kc_selected_line_width="1dp"
app:kc_grid_line_color="#d0d0d0"
app:kc_grid_line_width="0.5dp"
app:kc_point_width="6dp"
app:kc_macd_width="4dp"
app:kc_dif_color="@color/chart_ma5"
app:kc_dea_color="@color/chart_ma10"
app:kc_macd_color="@color/chart_ma20"
app:kc_k_color="@color/chart_ma5"
app:kc_d_color="@color/chart_ma10"
app:kc_j_color="@color/chart_ma20"
app:kc_rsi1_color="@color/chart_ma5"
app:kc_rsi2_color="@color/chart_ma10"
app:kc_ris3_color="@color/chart_ma20"
app:kc_up_color="@color/chart_ma5"
app:kc_mb_color="@color/chart_ma10"
app:kc_dn_color="@color/chart_ma20"
app:kc_ma5_color="@color/chart_ma5"
app:kc_ma10_color="@color/chart_ma10"
app:kc_ma20_color="@color/chart_ma20"
app:kc_candle_line_width="1dp"
app:kc_candle_width="4dp"
app:kc_selector_background_color="#c8d0d0d0"
app:kc_selector_text_size="@dimen/chart_selector_text_size"
app:kc_tab_text_color="@color/tab_light_text_color_selector"
app:kc_tab_indicator_color="#4473b1"
app:kc_tab_background_color="#fff"
app:kc_candle_solid="false">
</com.github.tifezh.kchartlib.chart.KChartView>
public class KLineEntity implements KLineImpl {
public String getDatetime() {
return Date;
}
public float getOpenPrice() {
return Open;
}
public float getHighPrice() {
return High;
}
public float getLowPrice() {
return Low;
}
public float getClosePrice() {
return Close;
}
public float getMA5Price() {
return MA5Price;
}
public float getMA10Price() {
return MA10Price;
}
public float getMA20Price() {
return MA20Price;
}
public float getDea() {
return dea;
}
public float getDif() {
return dif;
}
public float getMacd() {
return macd;
}
public float getK() {
return k;
}
public float getD() {
return d;
}
public float getJ() {
return j;
}
public float getRsi1() {
return rsi1;
}
public float getRsi2() {
return rsi2;
}
public float getRsi3() {
return rsi3;
}
public float getUp() {
return up;
}
public float getMb() {
return mb;
}
public float getDn() {
return dn;
}
public String Date;
public float Open;
public float High;
public float Low;
public float Close;
public float Volume;
public float MA5Price;
public float MA10Price;
public float MA20Price;
public float dea;
public float dif;
public float macd;
public float k;
public float d;
public float j;
public float rsi1;
public float rsi2;
public float rsi3;
public float up;
public float mb;
public float dn;
}
public class KChartAdapter extends BaseKChartAdapter {
private List<KLineEntity> datas = new ArrayList<>();
public KChartAdapter() {
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}
@Override
public Date getDate(int position) {
try {
String s = datas.get(position).Date;
String[] split = s.split("/");
Date date = new Date();
date.setYear(Integer.parseInt(split[0]) - 1900);
date.setMonth(Integer.parseInt(split[1]) - 1);
date.setDate(Integer.parseInt(split[2]));
return date;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 向头部添加数据
*/
public void addHeaderData(List<KLineEntity> data) {
if (data != null && !data.isEmpty()) {
datas.addAll(data);
notifyDataSetChanged();
}
}
/**
* 向尾部添加数据
*/
public void addFooterData(List<KLineEntity> data) {
if (data != null && !data.isEmpty()) {
datas.addAll(0, data);
notifyDataSetChanged();
}
}
/**
* 改变某个点的值
* @param position 索引值
*/
public void changeItem(int position,KLineEntity data)
{
datas.set(position,data);
notifyDataSetChanged();
}
}
mKChartView.showLoading();
new Thread(new Runnable() {
@Override
public void run() {
final List<KLineEntity> data = DataRequest.getALL(ExampleActivity.this);
runOnUiThread(new Runnable() {
@Override
public void run() {
//追加数据
mAdapter.addFooterData(data);
//开始动画
mKChartView.startAnimation();
//刷新完成
mKChartView.refreshEnd();
}
});
}
}).start();
- 定义kdj中的值
public interface KDJImpl {
public float getK();
public float getD();
public float getJ();
}
- 实现IChartDraw接口
public class KDJDraw implements IChartDraw<KDJImpl> {
private Paint mKPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mDPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mJPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public KDJDraw(BaseKChartView view) {
}
@Override
public void drawTranslated(@Nullable KDJImpl lastPoint, @NonNull KDJImpl curPoint, float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKChartView view, int position) {
view.drawChildLine(canvas, mKPaint, lastX, lastPoint.getK(), curX, curPoint.getK());
view.drawChildLine(canvas, mDPaint, lastX, lastPoint.getD(), curX, curPoint.getD());
view.drawChildLine(canvas, mJPaint, lastX, lastPoint.getJ(), curX, curPoint.getJ());
}
@Override
public void drawText(@NonNull Canvas canvas, @NonNull BaseKChartView view, int position, float x, float y) {
String text = "";
KDJImpl point = (KDJImpl) view.getItem(position);
text = "K:" + view.formatValue(point.getK()) + " ";
canvas.drawText(text, x, y, mKPaint);
x += mKPaint.measureText(text);
text = "D:" + view.formatValue(point.getD()) + " ";
canvas.drawText(text, x, y, mDPaint);
x += mDPaint.measureText(text);
text = "J:" + view.formatValue(point.getJ()) + " ";
canvas.drawText(text, x, y, mJPaint);
}
@Override
public float getMaxValue(KDJImpl point) {
return Math.max(point.getK(), Math.max(point.getD(), point.getJ()));
}
@Override
public float getMinValue(KDJImpl point) {
return Math.min(point.getK(), Math.min(point.getD(), point.getJ()));
}
/**
* 设置K颜色
*/
public void setKColor(int color) {
mKPaint.setColor(color);
}
/**
* 设置D颜色
*/
public void setDColor(int color) {
mDPaint.setColor(color);
}
/**
* 设置J颜色
*/
public void setJColor(int color) {
mJPaint.setColor(color);
}
/**
* 设置曲线宽度
*/
public void setLineWidth(float width)
{
mKPaint.setStrokeWidth(width);
mDPaint.setStrokeWidth(width);
mJPaint.setStrokeWidth(width);
}
/**
* 设置文字大小
*/
public void setTextSize(float textSize)
{
mKPaint.setTextSize(textSize);
mDPaint.setTextSize(textSize);
mJPaint.setTextSize(textSize);
}
}
- 添加kdj指标
mKChartView.addChildDraw("KDJ", mKDJDraw);
- 重写 drawTranslated(在此方法中绘画的会滑动和缩放) 方法 ,如下所示:
@Override
public void drawTranslated(@Nullable MACDImpl lastPoint, @NonNull MACDImpl curPoint, float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKChartView view, int position) {
drawMACD(canvas, view, curX, curPoint.getMacd());
view.drawChildLine(canvas, mDIFPaint, lastX, lastPoint.getDea(), curX, curPoint.getDea());
view.drawChildLine(canvas, mDEAPaint, lastX, lastPoint.getDif(), curX, curPoint.getDif());
}
/**
* 画macd
* @param canvas
* @param x
* @param macd
*/
private void drawMACD(Canvas canvas, BaseKChartView view, float x, float macd) {
float macdy = view.getChildY(macd);
float r = mMACDWidth / 2;
float zeroy=view.getChildY(0);
if (macd > 0) {
canvas.drawRect(x - r, macdy, x + r, zeroy, mRedPaint);
} else {
canvas.drawRect(x - r, zeroy, x + r, macdy, mGreenPaint);
}
}