美文网首页
基于MPAndroidChart库制作K线图

基于MPAndroidChart库制作K线图

作者: 不愿透露姓氏的许先生 | 来源:发表于2018-09-05 18:00 被阅读0次

最近制作一个炒币的app,类似于炒股的那种,网上资料很多很杂,最后使用github上面的MPAndroidChart库基本实现了功能。

一、介绍

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

image

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);         //不绘制右轴
    axisRight.setDrawLabels(false);      //不绘制右轴标签
    axisRight.setDrawGridLines(false);   //不绘制网格
    axisRight.setDrawAxisLine(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);//自适应最大最小值
    //自定义Y轴标签位置
    bcKl.setRendererLeftYAxis(new InBoundYAxisRenderer(bcKl.getViewPortHandler(), bcKl.getAxisLeft(),
       bcKl.getTransformer(YAxis.AxisDependency.LEFT)));
    //设置渲染器控制颜色、偏移,以及高亮
    bcKl.setRenderer(new OffsetBarRenderer(bcKl, bcKl.getAnimator(), bcKl.getViewPortHandler(), -0.5f)
       .setHighlightWidthSize(0.5f, CommentUtil.sp2px(this, 8)));
    
    //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);
    axisLeft1.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
           return value == 0 ? "" : value + "";
        }
    });
    
    //右Y轴
    YAxis axisRight1 = bcKl.getAxisRight();
    //axisRight1.setEnabled(false);         //不绘制右轴
    axisRight1.setDrawLabels(false);      //不绘制右轴标签
    axisRight1.setDrawGridLines(false);   //不绘制网格
    axisRight1.setDrawAxisLine(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、数据来源以及设置数据

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

相关文章

网友评论

      本文标题:基于MPAndroidChart库制作K线图

      本文链接:https://www.haomeiwen.com/subject/rxczwftx.html