KChartView

Project Url: tifezh/KChartView
Introduction: KChart for Android ;股票 k 线图
More: Author   ReportBugs   
Tags:

KChart for Android ;股票 k 线图

效果预览

  • 支持 macd,kdj,rsi,boll 多种指标切换,支持横竖屏切换,支持长按,缩放,滑动,fling 事件等。

  • 支持自定义样式

配置及使用

xml 简单配置
<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>
xml 中配置示例
<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>
数据实体继承 IKLine 类 获取各个指标的值
public class KLineEntity implements KLine {

    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();
更多使用方法请下载 demo 查看

扩展性

添加其他指数 以添加 kdj 指标为例
  • 定义 kdj 中的值 ```java public interface IKDJ {

    /**

    • K 值 */ float getK();

      /**

    • D 值 */ float getD();

      /**

    • J 值 */ float getJ();

}

* 实现 IChartDraw 接口
```java
public class KDJDraw implements IChartDraw<IKDJ> {

    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 IKDJ lastPoint, @NonNull IKDJ 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 = "";
        IKDJ point = (IKDJ) 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(IKDJ point) {
        return Math.max(point.getK(), Math.max(point.getD(), point.getJ()));
    }

    @Override
    public float getMinValue(IKDJ 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);
    
    自定义画线,画柱体 以 macd 为例
  • 重写 drawTranslated(在此方法中绘画的会滑动和缩放) 方法 ,如下所示:
    @Override
    public void drawTranslated(@Nullable IMACD lastPoint, @NonNull IMACD 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);
      }
    }
    

License

Copyright 2018 tifezh

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools