`
androidrlj
  • 浏览: 3688 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

转:利用JFreeChart绘制股票K线图完整解决方案

阅读更多
转:利用JFreeChart绘制股票K线图完整解决方案
          因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上搜索发现,以自己最熟悉的两门语言为例,其中有PHP版的开源JPGraph画图程序和JAVA版的JFreeChart画图工具包,jpgraph用过一段时间,但是发现,其中图形细节方面处理的不够细腻和精致,最后转向使用jfreechart,这是国外一个开源的图形绘制的java包,里面的画图功能也相当的强大,更主要的利用java强大的面向对象的功能,可以进行很多方面的定制和修改。

         网上有很多人在询问如何使用jfreechart来绘制股票K线图,通过阅读其中的一些例子来看,大多比较的凌乱,没有给出一个符合中国股票市场的K线图实例,因为中国的股票市场K线图的颜色表示与国外存在一点差异,也有很多人遇到了如何去掉周六,周日这类不存在交易的日期,网上没有一个很满意的答案,通过实践,本人整理出一个完整的实例,给出完整的注释,只要在eclipse中配置好相应的classpath,甚至不要修改就可以运行,得到一个包含日K线和日成交量的组合图,希望给大家提供一点帮助,同时也希望大家能够一起交流,改进和挖掘更多的功能!

          在进行源代码讲解之前,有必要将本人所领悟到的一些关于jfreechart的概念讲述下,jfreechart工具基本上把一个图形分成了几个逻辑部分。

      1.首先是整个的画布对象(chart),画布就相当与一个大的容器,包含一些图形元素,比如为一张白纸
      2.然后是画图区域对象(plot),就是实际图形所占据的区域,比如为白纸上的一个长方形
      3.然后是图形所需要两条轴对象(axis),比如为白纸上的两条轴线
      4.最后是如何进行图像的绘制对象(render),比如为一只画图的笔
      5.除开上面的这些对象,还有一个最主要的就是通过必须的数据集(dataset)来生成图形了
至于一些具体的对象细节,就只好请各位去阅读相关的API文档了,在这里就不详细的说明
package chart;
import java.awt.Color;//颜色系统
import java.text.SimpleDateFormat;//时间格式
import java.awt.Paint;//画笔系统
import org.jfree.data.time.*;
import org.jfree.data.time.Day;
import org.jfree.data.time.ohlc.OHLCSeries;
import org.jfree.data.time.ohlc.OHLCSeriesCollection;
import org.jfree.chart.renderer.xy.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.*;

public class KLineCombineChart {

public static void main(String[] args) {
     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
     double highValue = Double.MIN_VALUE;//设置K线数据当中的最大值
     double minValue = Double.MAX_VALUE;//设置K线数据当中的最小值
     double high2Value = Double.MIN_VALUE;//设置成交量的最大值
     double min2Value = Double.MAX_VALUE;//设置成交量的最低值
     OHLCSeries series = new OHLCSeries("");//高开低收数据序列,股票K线图的四个数据,依次是开,高,低,收
     series.add(new Day(28, 9, 2007), 9.2, 9.58, 9.16, 9.34);
     series.add(new Day(27, 9, 2007), 8.9, 9.06, 8.83, 8.96);
     series.add(new Day(26, 9, 2007), 9.0, 9.1, 8.82, 9.04);
     series.add(new Day(25, 9, 2007), 9.25, 9.33, 8.88, 9.00);
     series.add(new Day(24, 9, 2007), 9.05, 9.50, 8.91, 9.25);
     series.add(new Day(21, 9, 2007), 8.68, 9.05, 8.40, 9.00);
     series.add(new Day(20, 9, 2007), 8.68, 8.95, 8.50, 8.69);
     series.add(new Day(19, 9, 2007), 8.80, 8.94, 8.50, 8.66);
     series.add(new Day(18, 9, 2007), 8.88, 9.17, 8.69, 8.80);
     series.add(new Day(17, 9, 2007), 8.26, 8.98, 8.15, 8.89);
     series.add(new Day(14, 9, 2007), 8.44, 8.45, 8.13, 8.33);
     series.add(new Day(13, 9, 2007), 8.13, 8.46, 7.97, 8.42);
     series.add(new Day(12, 9, 2007), 8.2, 8.4, 7.81, 8.13);
     series.add(new Day(11, 9, 2007), 9.0, 9.0, 8.1, 8.24);
     series.add(new Day(10, 9, 2007), 8.6, 9.03, 8.40, 8.95);
     series.add(new Day(7, 9, 2007), 8.89, 9.04, 8.70, 8.73);
     series.add(new Day(6, 9, 2007), 8.4, 9.08, 8.33, 8.88);
     series.add(new Day(5, 9, 2007), 8.2, 8.74, 8.17, 8.36);
     series.add(new Day(4, 9, 2007), 7.7, 8.46, 7.67, 8.27);
     series.add(new Day(3, 9, 2007), 7.5, 7.8, 7.48, 7.69);
     series.add(new Day(31, 8, 2007), 7.4, 7.6, 7.28, 7.43);
     series.add(new Day(30, 8, 2007), 7.42, 7.56, 7.31, 7.40);
     series.add(new Day(29, 8, 2007), 7.42, 7.66, 7.22, 7.33);
     series.add(new Day(28, 8, 2007), 7.31, 7.70, 7.15, 7.56);
     series.add(new Day(27, 8, 2007), 7.05, 7.46, 7.02, 7.41);
     series.add(new Day(24, 8, 2007), 7.05, 7.09, 6.90, 6.99);
     series.add(new Day(23, 8, 2007), 7.12, 7.16, 7.00, 7.03);
     series.add(new Day(22, 8, 2007), 6.96, 7.15, 6.93, 7.11);
     series.add(new Day(21, 8, 2007), 7.10, 7.15, 7.02, 7.07);
     series.add(new Day(20, 8, 2007), 7.02, 7.19, 6.94, 7.14);
     final OHLCSeriesCollection seriesCollection = new OHLCSeriesCollection();//保留K线数据的数据集,必须申明为final,后面要在匿名内部类里面用到
     seriesCollection.addSeries(series);
     TimeSeries series2=new TimeSeries("");//对应时间成交量数据
     series2.add(new Day(28, 9, 2007), 260659400/100);
     series2.add(new Day(27, 9, 2007), 119701900/100);
     series2.add(new Day(26, 9, 2007), 109719000/100);
     series2.add(new Day(25, 9, 2007), 178492400/100);
     series2.add(new Day(24, 9, 2007), 269978500/100);
     series2.add(new Day(21, 9, 2007), 361042300/100);
     series2.add(new Day(20, 9, 2007), 173912600/100);
     series2.add(new Day(19, 9, 2007), 154622600/100);
     series2.add(new Day(18, 9, 2007), 200661600/100);
     series2.add(new Day(17, 9, 2007), 312799600/100);
     series2.add(new Day(14, 9, 2007), 141652900/100);
     series2.add(new Day(13, 9, 2007), 221260400/100);
     series2.add(new Day(12, 9, 2007), 274795400/100);
     series2.add(new Day(11, 9, 2007), 289287300/100);
     series2.add(new Day(10, 9, 2007), 289063600/100);
     series2.add(new Day(7, 9, 2007), 351575300/100);
     series2.add(new Day(6, 9, 2007), 451357300/100);
     series2.add(new Day(5, 9, 2007), 442421200/100);
     series2.add(new Day(4, 9, 2007), 671942600/100);
     series2.add(new Day(3, 9, 2007), 349647800/100);
     series2.add(new Day(31, 8, 2007), 225339300/100);
     series2.add(new Day(30, 8, 2007), 160048200/100);
     series2.add(new Day(29, 8, 2007), 247341700/100);
     series2.add(new Day(28, 8, 2007), 394975400/100);
     series2.add(new Day(27, 8, 2007), 475797500/100);
     series2.add(new Day(24, 8, 2007), 297679500/100);
     series2.add(new Day(23, 8, 2007), 191760600/100);
     series2.add(new Day(22, 8, 2007), 232570200/100);
     series2.add(new Day(21, 8, 2007), 215693200/100);
     series2.add(new Day(20, 8, 2007), 200287500/100);
     TimeSeriesCollection timeSeriesCollection=new TimeSeriesCollection();//保留成交量数据的集合
     timeSeriesCollection.addSeries(series2);
 
     //获取K线数据的最高值和最低值
     int seriesCount = seriesCollection.getSeriesCount();//一共有多少个序列,目前为一个
     for (int i = 0; i < seriesCount; i++) {
      int itemCount = seriesCollection.getItemCount(i);//每一个序列有多少个数据项
      for (int j = 0; j < itemCount; j++) {
       if (highValue < seriesCollection.getHighValue(i, j)) {//取第i个序列中的第j个数据项的最大值
        highValue = seriesCollection.getHighValue(i, j);
       }
       if (minValue > seriesCollection.getLowValue(i, j)) {//取第i个序列中的第j个数据项的最小值
        minValue = seriesCollection.getLowValue(i, j);
       }
      }

     }
     //获取最高值和最低值
     int seriesCount2 = timeSeriesCollection.getSeriesCount();//一共有多少个序列,目前为一个
     for (int i = 0; i < seriesCount2; i++) {
      int itemCount = timeSeriesCollection.getItemCount(i);//每一个序列有多少个数据项
      for (int j = 0; j < itemCount; j++) {
       if (high2Value < timeSeriesCollection.getYValue(i,j)) {//取第i个序列中的第j个数据项的值
        high2Value = timeSeriesCollection.getYValue(i,j);
       }
       if (min2Value > timeSeriesCollection.getYValue(i, j)) {//取第i个序列中的第j个数据项的值
        min2Value = timeSeriesCollection.getYValue(i, j);
       }
      }

     }
     final CandlestickRenderer candlestickRender=new CandlestickRenderer();//设置K线图的画图器,必须申明为final,后面要在匿名内部类里面用到
     candlestickRender.setUseOutlinePaint(true); //设置是否使用自定义的边框线,程序自带的边框线的颜色不符合中国股票市场的习惯
     candlestickRender.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_AVERAGE);//设置如何对K线图的宽度进行设定
     candlestickRender.setAutoWidthGap(0.001);//设置各个K线图之间的间隔
     candlestickRender.setUpPaint(Color.RED);//设置股票上涨的K线图颜色
     candlestickRender.setDownPaint(Color.GREEN);//设置股票下跌的K线图颜色
     DateAxis x1Axis=new DateAxis();//设置x轴,也就是时间轴
     x1Axis.setAutoRange(false);//设置不采用自动设置时间范围
     try{
      x1Axis.setRange(dateFormat.parse("2007-08-20"),dateFormat.parse("2007-09-29"));//设置时间范围,注意时间的最大值要比已有的时间最大值要多一天
     }catch(Exception e){
      e.printStackTrace();
     }
     x1Axis.setTimeline(SegmentedTimeline.newMondayThroughFridayTimeline());//设置时间线显示的规则,用这个方法就摒除掉了周六和周日这些没有交易的日期(很多人都不知道有此方法),使图形看上去连续
     x1Axis.setAutoTickUnitSelection(false);//设置不采用自动选择刻度值
     x1Axis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);//设置标记的位置
     x1Axis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());//设置标准的时间刻度单位
     x1Axis.setTickUnit(new DateTickUnit(DateTickUnit.DAY,7));//设置时间刻度的间隔,一般以周为单位
     x1Axis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));//设置显示时间的格式
     NumberAxis y1Axis=new NumberAxis();//设定y轴,就是数字轴
     y1Axis.setAutoRange(false);//不不使用自动设定范围
     y1Axis.setRange(minValue*0.9, highValue*1.1);//设定y轴值的范围,比最低值要低一些,比最大值要大一些,这样图形看起来会美观些
     y1Axis.setTickUnit(new NumberTickUnit((highValue*1.1-minValue*0.9)/10));//设置刻度显示的密度
     XYPlot plot1=new XYPlot(seriesCollection,x1Axis,y1Axis,candlestickRender);//设置画图区域对象
 
     XYBarRenderer xyBarRender=new XYBarRenderer(){
     private static final long serialVersionUID = 1L;//为了避免出现警告消息,特设定此值
     public Paint getItemPaint(int i, int j){//匿名内部类用来处理当日的成交量柱形图的颜色与K线图的颜色保持一致
       if(seriesCollection.getCloseValue(i,j)>seriesCollection.getOpenValue(i,j)){//收盘价高于开盘价,股票上涨,选用股票上涨的颜色
        return candlestickRender.getUpPaint();
       }else{
        return candlestickRender.getDownPaint();
       }
     }};
     xyBarRender.setMargin(0.1);//设置柱形图之间的间隔
     NumberAxis y2Axis=new NumberAxis();//设置Y轴,为数值,后面的设置,参考上面的y轴设置
     y2Axis.setAutoRange(false);
     y2Axis.setRange(min2Value*0.9, high2Value*1.1);
     y2Axis.setTickUnit(new NumberTickUnit((high2Value*1.1-min2Value*0.9)/4));
     XYPlot plot2=new XYPlot(timeSeriesCollection,null,y2Axis,xyBarRender);//建立第二个画图区域对象,主要此时的x轴设为了null值,因为要与第一个画图区域对象共享x轴
     CombinedDomainXYPlot combineddomainxyplot = new CombinedDomainXYPlot(x1Axis);//建立一个恰当的联合图形区域对象,以x轴为共享轴
     combineddomainxyplot.add(plot1, 2);//添加图形区域对象,后面的数字是计算这个区域对象应该占据多大的区域2/3
        combineddomainxyplot.add(plot2, 1);//添加图形区域对象,后面的数字是计算这个区域对象应该占据多大的区域1/3
        combineddomainxyplot.setGap(10);//设置两个图形区域对象之间的间隔空间
        JFreeChart chart = new JFreeChart("中国联通", JFreeChart.DEFAULT_TITLE_FONT, combineddomainxyplot, false);
        ChartFrame frame = new ChartFrame("中国联通股票", chart);
     frame.pack();
     frame.setVisible(true);
}

}

为了能够保证K线图的上影线和下影线能够和K线图本身的颜色保持一致,找了很多的方法设置都不成功,可以说目前暂不提供单独绘制K线边框颜色的方法,所以,经过本人的实验,对其中的源代码进行了下修改,具体修改的地方是在下载回来的文件目中source\org\jfree\chart\renderer\xy\CandlestickRenderer.java文件,将
Paint p = getItemPaint(series, item);
           Paint outlinePaint = null;
           outlinePaint = getItemOutlinePaint(series, item);
}

修改为如下的代码,这样就会保证K线图的上影线和下影线能够和K线图本身的颜色保持一致,符合中国股票市场K线图形颜色的习惯:
Paint p = getItemPaint(series, item);
           Paint outlinePaint = null;
           if (this.useOutlinePaint) {
            if(yClose>yOpen){
             if (this.upPaint != null) {
              outlinePaint=this.upPaint;
                   }
                   else {
                    outlinePaint=p;
                   }
            }else{
             if (this.downPaint != null) {
              outlinePaint=this.downPaint;
                   }
                   else {
                    outlinePaint=p;
                   }
            }
           }

chart.setBackgroundPaint(Color.white);//设置曲线图背景色

XYPlot plot = (XYPlot) chart.getPlot();
XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)plot.getRenderer();
plot.setBackgroundPaint(Color.white));//设置网格背景颜色
plot.setDomainGridlinePaint(Color.pink);//设置网格竖线颜色
plot.setRangeGridlinePaint(Color.pink);//设置网格横线颜色
plot.setAxisOffset(new RectangleInsets(0D, 0D, 0D, 10D));//设置曲线图与xy轴的距离,即曲线与xy轴贴近的距离
xylineandshaperenderer.setBaseShapesVisible(true);//设置曲线是否显示数据点

分享到:
评论

相关推荐

    基于JFreeChart的股票交易K线图停牌日期缺口优化完整解决方案

    总的来说,这个解决方案利用JFreeChart库解决了股票K线图在遇到停牌日期时出现的缺口问题,提升了图表的可读性和分析效率。通过对CSV数据的处理、插值或标记方法的应用,以及JFreeChart的强大功能,我们可以得到连续...

    JFreeChart 股票K线图创建过程

    JFreeChart 是一个强大的 Java 图表库,它允许开发者创建各种复杂的图表,包括股票市场中常见的K线图。在金融领域,K线图(也称为日本蜡烛图)是一种常用的技术分析工具,用于展示价格走势。本文将详细介绍如何使用 ...

    JFREECHART画K线图

    K线图的实例哦,这个好点,那个我乱改拉``

    jfreechart绘制的风速风向玫瑰图

    jfreechart绘制的风速风向玫瑰图 jfreechart是Java中一个流行的图表库,它提供了许多种类的图表,包括柱状图、折线图、饼图、雷达图等。本文主要介绍如何使用jfreechart绘制风速风向玫瑰图。 首先,了解jfreechart...

    java利用jfreechart绘制excel.pdf

    Java 利用 JFreeChart 绘制 Excel 图表 JFreeChart 是一个流行的 Java 图表库,它提供了丰富的图表绘制功能,包括柱状图、饼状图、折线图等。在本文中,我们将使用 JFreeChart 库来生成 Excel 图表。 标题:Java ...

    jfreechart 绘制横向立体柱状图

    利用jfreechart绘制的横向立体柱状图,横坐标是数值,纵坐标是数据分类,需要提前引入jfreechart包文件到工程里,才不会报错

    java利用jfreechart绘制excel参考.pdf

    Java 利用 JFreeChart 绘制 Excel 参考 JFreeChart 是一个流行的 Java 图表库,能够生成各种类型的图表,包括折线图、柱状图、饼状图等。下面是使用 JFreeChart 库绘制 Excel 图表的相关知识点: 导包 为了使用 ...

    jfreechart绘制折线图(平面和3D)

    在本主题中,我们将深入探讨如何使用JFreeChart来绘制平面和3D的折线图。 首先,让我们了解折线图的基本概念。折线图是一种用直线段连接一系列数据点的图表,常用于展示数据随时间的变化趋势。在平面折线图中,x轴...

    jfreechart ajax 实时 股票图 表盘图

    JFreeChart是一个强大的Java图表库,它能够生成各种类型的高质量图表,包括折线图、柱状图、饼图、散点图、甘特图以及股票图等。在金融领域,JFreeChart常用于创建实时的股票图表,展示股票的价格波动和交易量变化。...

    jfreechart绘制的立体柱状图(正负纵坐标)

    利用jfreechart绘制的立体柱状图,可以实现正负纵坐标显示,需要提前下载jfreechart.jar文件,否则我的类会报错,也即是要配置运行环境

    使用JFREECHART画K线图实例

    没啥说的...比较有用

    转:报表插件JFreeChart的使用

    2. **支持的图表类型**:JFreeChart支持多种图表类型,包括折线图、柱状图、饼图、散点图、甘特图、雷达图、热力图等,能够满足大多数数据可视化的需求。 3. **使用方法**:创建图表通常涉及以下几个步骤:初始化...

    jfreechart雷达图

    在本篇中,我们将深入探讨如何利用JFreeChart来制作雷达图(也称为蜘蛛图或星形图),并理解其相关知识点。 1. **JFreeChart简介** JFreeChart是一个开源项目,其目标是提供一个可以免费使用的高质量图表API。它...

    JFreeChart图表绘制源码

    JFreeChart是JAVA平台上的一个开放的图表绘制类库。它完全使用JAVA语言编写,是为applications, applets, servlets 以及JSP等使用所设计。JFreeChart可生成饼图(pie charts)、柱状图(bar charts)、 散点图...

    JFreeChart画图 饼状图 单组柱状图 多组柱状图 堆积柱状图 折线图

    JFreeChart 饼状图 柱状图 柱状图 堆积柱状图 折线图 这个是我特地开发的一个用JFreeChart开发的用来画图的项目,已经开发成形了各种项目的各种需求的项目,并且自己可以拓展,根据需求修改代码,完成项目的需要。 ...

    jfreechart 生成折线图,饼图,柱状图,堆栈柱状图

    JFreeChart 是一个开源的Java库,用于生成高质量的2D图表,如折线图、饼图、柱状图和堆栈柱状图等。它广泛应用于数据分析、报告和应用程序中,提供丰富的自定义选项来满足各种视觉需求。在本项目中,你将找到能够...

    java+jfreechart 做股票日线数据查看系统

    标题中的“java+jfreechart 做股票日线数据查看系统”表明这是一个使用Java编程语言,结合JFreeChart库来实现的项目,主要用于展示股票的日线数据,即每日的开盘价、收盘价、最高价、最低价以及交易量等关键信息。...

    JFreeChart画雷达图

    **正文** JFreeChart是一款强大的Java图形库,它允许开发者创建各种复杂的图表,包括我们这里关注的雷达图(也...无论你是为了分析还是报告,都能利用JFreeChart轻松创建出符合需求的雷达图,清晰地展示多维度数据。

    利用JfreeChart开发包绘制图表.pdf

    ### 利用JfreeChart开发包绘制图表 #### 概述 随着信息技术的快速发展,各行各业积累了大量的数据。尽管数据能够精确地反映事实,但其直观性不足,这限制了人们快速理解和吸收信息的能力。因此,将这些数据转换为...

    applet_+_JfreeChart_实现曲线走势图

    若要在Web应用中展示动态图表,可以考虑使用基于JavaScript的库,如D3.js、Highcharts或者ECharts,它们提供了更现代、更安全的解决方案。 综上所述,结合Applet和JFreeChart实现曲线走势图是一项涉及Web客户端编程...

Global site tag (gtag.js) - Google Analytics