1. 程式人生 > >基於MPAndroidChart庫製作K線圖(一) —— 基礎圖

基於MPAndroidChart庫製作K線圖(一) —— 基礎圖

目錄
基於MPAndroidChart庫製作K線圖(一) ­­­­­­­­­­­­—— 基礎圖
基於MPAndroidChart庫製作K線圖(二) ­­­­­­­­­­­­—— 自定義x、y軸
基於MPAndroidChart庫製作K線圖(三) ­­­­­­­­­­­­—— 手勢高亮聯動


最近製作一個炒幣的app,類似於炒股的那種,網上資料很多很雜,最後使用github上面的MPAndroidChart庫基本實現了功能。

一、介紹

MPAndroidChart庫:https://github.com/PhilJay/MPAndroidChart

1.1支援圖形

  • Line Chart 折線圖
  • Bar Chart 直方圖
  • Pie Chart 餅圖
  • Bubble Chart 氣泡圖
  • Candle Stick Chart 蠟燭圖(用於展示金融資料時常稱為K線圖)
  • Radar Chart 雷達圖
  • Cubic Line Chart 立方折線圖
  • Stacked Bar Chart 堆積圖

1.2MPAndroid使用

  • Project level build.gradle
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
  • App level build.gradle
dependencies {
    implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
}

二、基礎實現效果圖

三、核心程式碼

3.1、初始化表格

主要的一些屬性均已寫註釋,部分註釋可能有所偏差,具體以MPAndroidChart原始碼註釋為準

private void initChart() {
	//K線
	ccKl.setNoDataTextColor(getResources().getColor(R.color.gray8B)
);//無資料時提示文字的顏色 ccKl.setDescription(null);//取消描述 ccKl.getLegend().setEnabled(false);//取消圖例 ccKl.setDragDecelerationEnabled(false);//不允許甩動慣性滑動 和moveView方法有衝突 設定為false ccKl.setMinOffset(0);//設定外邊緣偏移量 ccKl.setExtraBottomOffset(6);//設定底部外邊緣偏移量 便於顯示X軸 ccKl.setScaleEnabled(false);//不可縮放 ccKl.setAutoScaleMinMaxEnabled(true);//自適應最大最小值 ccKl.setDrawOrder(new CombinedChart.DrawOrder[]{CombinedChart.DrawOrder.CANDLE, CombinedChart.DrawOrder.LINE}); //繪製順序,先繪製條形再繪製條線 //K線 x軸 XAxis xac = ccKl.getXAxis(); xac.setPosition(XAxis.XAxisPosition.BOTTOM); xac.setGridColor(getResources().getColor(R.color.black3B));//網格線顏色 xac.setTextColor(getResources().getColor(R.color.gray8B));//標籤顏色 xac.setTextSize(8);//標籤字型大小 xac.setAxisLineColor(getResources().getColor(R.color.black3B));//軸線顏色 xac.disableAxisLineDashedLine();//取消軸線虛線設定 xac.setAvoidFirstLastClipping(true);//避免首尾端標籤被裁剪 xac.setLabelCount(5, true);//強制顯示2個標籤 //K線 左Y軸 YAxis axisLeft = ccKl.getAxisLeft(); axisLeft.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART); //標籤顯示在內側;OUTSIDE_CHART外側 axisLeft.setGridColor(getResources().getColor(R.color.black3B)); //網格顏色 axisLeft.setTextColor(getResources().getColor(R.color.gray8B)); //文字顏色 axisLeft.setTextSize(8); //文字大小 axisLeft.setLabelCount(5, true); //label個數,強制設定標籤計數 axisLeft.enableGridDashedLine(5, 4, 0);//橫向網格線設定為虛線 //K線 右Y軸 YAxis axisRight = ccKl.getAxisRight(); axisRight.setEnabled(false); //不繪製右軸 //蠟燭圖 candleSet = new CandleDataSet(new ArrayList<CandleEntry>(), "Kline"); candleSet.setAxisDependency(YAxis.AxisDependency.LEFT); candleSet.setDrawHorizontalHighlightIndicator(false); candleSet.setHighlightLineWidth(0.5f); candleSet.setHighLightColor(getResources().getColor(R.color.brown)); candleSet.setShadowWidth(0.7f); candleSet.setIncreasingColor(getResources().getColor(R.color.redEB)); //上漲設定為紅色 candleSet.setIncreasingPaintStyle(Paint.Style.FILL); //fill:實心填充 stroke:空心描邊 fill_and_stroke 填充描邊 candleSet.setDecreasingColor(getResources().getColor(R.color.green4C));//下跌設定為綠色 candleSet.setDecreasingPaintStyle(Paint.Style.FILL); //fill:實心填充 stroke:空心描邊 fill_and_stroke 填充描邊 candleSet.setNeutralColor(getResources().getColor(R.color.redEB)); candleSet.setShadowColorSameAsCandle(true); candleSet.setDrawValues(false); candleSet.setHighlightEnabled(false); //5分均線 lineSet5 = new LineDataSet(new ArrayList<Entry>(), "MA5"); lineSet5.setAxisDependency(YAxis.AxisDependency.LEFT); lineSet5.setColor(getResources().getColor(R.color.purple)); lineSet5.setDrawCircles(false); lineSet5.setDrawValues(false); lineSet5.setHighlightEnabled(false); //10分均線 lineSet10 = new LineDataSet(new ArrayList<Entry>(), "MA10"); lineSet10.setAxisDependency(YAxis.AxisDependency.LEFT); lineSet10.setColor(getResources().getColor(R.color.yellow)); lineSet10.setDrawCircles(false); lineSet10.setDrawValues(false); lineSet10.setHighlightEnabled(false); //30分均線 lineSet30 = new LineDataSet(new ArrayList<Entry>(), "MA30"); lineSet30.setAxisDependency(YAxis.AxisDependency.LEFT); lineSet30.setColor(getResources().getColor(R.color.white)); lineSet30.setDrawCircles(false); lineSet30.setDrawValues(false); lineSet30.setHighlightEnabled(false); //分時線 lineSetMin = new LineDataSet(new ArrayList<Entry>(), "Minutes"); lineSetMin.setAxisDependency(YAxis.AxisDependency.LEFT); lineSetMin.setColor(Color.WHITE); lineSetMin.setDrawCircles(false); lineSetMin.setDrawValues(false); lineSetMin.setDrawFilled(true); lineSetMin.setHighlightEnabled(false); lineSetMin.setFillColor(getResources().getColor(R.color.gray8B)); lineSetMin.setFillAlpha(60); //成交量 bcKl.setNoDataTextColor(getResources().getColor(R.color.gray8B)); bcKl.setDescription(null); bcKl.getLegend().setEnabled(false); bcKl.setDragDecelerationEnabled(false); //不允許甩動慣性滑動 bcKl.setMinOffset(0); //設定外邊緣偏移量 bcKl.setScaleEnabled(false);//不可縮放 bcKl.setAutoScaleMinMaxEnabled(true);//自適應最大最小值 //x軸 XAxis xAxis = bcKl.getXAxis(); xAxis.setEnabled(false); //左Y軸 YAxis axisLeft1 = bcKl.getAxisLeft(); axisLeft1.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);//標籤顯示在內側 axisLeft1.setDrawAxisLine(false); axisLeft1.setGridColor(getResources().getColor(R.color.black3B)); axisLeft1.setTextColor(getResources().getColor(R.color.gray8B)); axisLeft1.setTextSize(8); axisLeft1.setLabelCount(2, true); axisLeft1.setAxisMinimum(0); //右Y軸 YAxis axisRight1 = bcKl.getAxisRight(); axisRight1.setEnabled(false); //不繪製右軸 //柱狀圖 barSet = new BarDataSet(new ArrayList<BarEntry>(), "VOL"); barSet.setHighLightColor(getResources().getColor(R.color.brown)); barSet.setColors(getResources().getColor(R.color.redEB), getResources().getColor(R.color.green4C)); barSet.setDrawValues(false); barSet.setHighlightEnabled(false); }

3.2、資料來源以及設定資料

簡要描述:

  • 獲取k線資料

請求URL:

  • https://openapi.dragonex.io/api/v1/market/kline/

請求方式:

  • GET

引數:

欄位名 資料型別 說明
symbol_id int 交易對ID
st int 起始時間,從當前時間開始時可不傳或傳0,否則傳unix時間戳(納秒)
direction int 查詢方向:1-從起始時間往後查,2-從起始時間往前查,預設2
count int 查詢條數,最大100,預設10
kline_type int k線型別:1-1min線, 2-5min線, 3-15min線, 4-30min線, 5-60min線, 6-1day線.預設1

返回示例

返回值data資訊:

欄位名 資料型別 說明
columns [] 下述列表每個位置的資料代表的意義
list [] kline資料

list資訊:

欄位名 資料型別 說明
amount string 交易額
close_price string 收盤價
max_price string 最高價
min_price string 最低價
open_price string 開盤價
pre_close_price string 上一個收盤價
timestamp int 秒級時間戳
usdt_amount string 對應的USDT交易額
volume string 交易量
{
    "ok": true,
    "code": 1,
    "msg": "",
    "data": {
        "columns": [
            "amount",
            "close_price",
            "max_price",
            "min_price",
            "open_price",
            "pre_close_price",
            "timestamp",
            "usdt_amount",
            "volume"
        ],
        "lists": [
            [
                "28413.7359",
                "289.0131",
                "290.7236",
                "288.9502",
                "289.9977",
                "0.0000",
                1536075900,
                "28413.7359",
                "98.0704"
            ],
            [
                "17430.8759",
                "289.1027",
                "290.3000",
                "288.9529",
                "289.0229",
                "0.0000",
                1536076800,
                "17430.8759",
                "60.3029"
            ],
            ......
            [
                "3812.4130",
                "254.9381",
                "255.6408",
                "254.9335",
                "254.9436",
                "0.0000",
                1536165000,
                "3812.4130",
                "14.9540"
            ]
        ]
    }
}

  • 設定資料
private void configData() {
      
      if (combinedData == null) {
          combinedData = new CombinedData();
      }
      xValues.clear();
      List<CandleEntry> candleValues = candleSet.getValues();
      candleValues.clear();
      List<Entry> ma5Values = lineSet5.getValues();
      ma5Values.clear();
      List<Entry> ma10Values = lineSet10.getValues();
      ma10Values.clear();
      List<Entry> ma30Values = lineSet30.getValues();
      ma30Values.clear();
      List<Entry> minValues = lineSetMin.getValues();
      minValues.clear();
      List<BarEntry> barValues = barSet.getValues();
      barValues.clear();
      for (int i = 0; i < dataList.size(); i++) {
          List<String> k = dataList.get(i);
          Date d = new Date(Long.parseLong(k.get(6)) * 1000);     //6.毫秒
          String x = sdf.format(d);                               //顯示日期
          if (xValues.containsValue(x)) {                         //x重複
              dataList.remove(i);
              i--;
          } else {
              xValues.put(i, x);
              float open = Float.parseFloat(k.get(4));            //4.open
              float close = Float.parseFloat(k.get(1));           //1.close
              candleValues.add(new CandleEntry(i, Float.parseFloat(k.get(2)), Float.parseFloat(k.get(3)), open, close, x)); //2.max  3.min
              minValues.add(new Entry(i, close, x));
              barValues.add(new BarEntry(i, Float.parseFloat(k.get(8)), close >= open ? 0 : 1));  //8.volume交易量
              if (i >= 4) {
                  ma5Values.add(new Entry(i, getMA(i, 5)));
                  if (i >= 9) {
                      ma10Values.add(new Entry(i, getMA(i, 10)));
                      if (i >= 29) {
                          ma30Values.add(new Entry(i, getMA(i, 30)));
                      }
                  }
              }
          }
      }
      candleSet.setValues(candleValues);
      lineSet5.setValues(ma5Values);
      lineSet10.setValues(ma10Values);
      lineSet30.setValues(ma30Values);
      lineSetMin.setValues(minValues);