基於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);

      if (tlKl.getSelectedTabPosition() == 0) {
          combinedData.removeDataSet(candleSet);                      //分時圖時移除蠟燭圖
          combinedData.setData(new LineData(lineSetMin));             //分時線
      } else {
          combinedData.setData(new CandleData(candleSet));            //蠟燭圖
          combinedData.setData(new LineData(lineSet5, lineSet10, lineSet30));    //5分線 10分線 30分線
      }

      ccKl.setData(combinedData);
      float xMax = xValues.size() - 0.5F;       //默認X軸最大值是 xValues.size() - 1
      ccKl.getXAxis().setAxisMaximum(xMax);     //使最後一個顯示完整

      barSet.setValues(barValues);
      BarData barData = new BarData(barSet);
      barData.setBarWidth(1 - candleSet.getBarSpace() * 2);//使Candle和Bar寬度一致
      bcKl.setData(barData);
      bcKl.getXAxis().setAxisMaximum(xMax + (-0.5f));//保持邊緣對齊
      ccKl.setVisibleXRange(52, 52);//設置顯示X軸個數的上下限,豎屏固定52個
      bcKl.setVisibleXRange(52, 52);
      
 }

四、源碼下載

github: https://github.com/xkdaq/KoinChart
coding: https://coding.net/u/xkdaq/p/KoinChart/git (最新代碼在coding上)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章