JAVA 用JFreeChart绘制K线图急!急!急!!求高手!

    技术2022-05-18  17

    package com;

    import java.awt.Color;import java.awt.GradientPaint;import java.awt.Paint;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.InputEvent;import java.awt.event.KeyEvent;import java.io.BufferedReader;

    import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import java.text.DateFormat;import java.text.DecimalFormat;import java.text.FieldPosition;import java.text.NumberFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Collections;import java.util.Date;import java.util.List;import java.util.StringTokenizer;

    import javax.swing.*;

    import org.jfree.chart.ChartFrame;import org.jfree.chart.ChartPanel;import org.jfree.chart.JFreeChart;import org.jfree.chart.LegendItem;import org.jfree.chart.LegendItemCollection;import org.jfree.chart.axis.DateAxis;import org.jfree.chart.axis.DateTickMarkPosition;import org.jfree.chart.axis.DateTickUnit;import org.jfree.chart.axis.DateTickUnitType;import org.jfree.chart.axis.NumberAxis;import org.jfree.chart.axis.SegmentedTimeline;import org.jfree.chart.plot.CombinedDomainXYPlot;import org.jfree.chart.plot.Plot;import org.jfree.chart.plot.XYPlot;import org.jfree.chart.renderer.xy.CandlestickRenderer;import org.jfree.chart.renderer.xy.XYBarRenderer;import org.jfree.chart.renderer.xy.XYSplineRenderer;import org.jfree.data.time.MovingAverage;import org.jfree.data.xy.AbstractIntervalXYDataset;import org.jfree.data.xy.DefaultOHLCDataset;import org.jfree.data.xy.IntervalXYDataset;import org.jfree.data.xy.OHLCDataItem;import org.jfree.data.xy.OHLCDataset;import org.jfree.data.xy.XYDataset;

    public class CandlestickVolume { static ChartPanel charPanel = null; private static final Color COLOR_close = new Color(41, 36, 33);// 收盘价颜色 象牙黑 private static final Color COLOR_MA5 = new Color(138, 43, 226);// 5日均线颜色 紫 private static final Color COLOR_MA10 = new Color(30, 144, 255);// 10日均线颜色 蓝 private static final Color COLOR_MA15 = new Color(255, 165, 0);// 15日均线颜色                 // 土黄 private static final Color COLOR_MA20 = new Color(255, 0, 255);// 20日均线颜色                 // 深红 private static final Color COLOR_MA30 = new Color(240, 230, 140);// 30日均线颜色                  // 黄褐 private static final Color COLOR_MA60 = new Color(0, 0, 128);// 60日均线颜色                 // 藏青 private static final Color COLOR_MA120 = new Color(34, 193, 34);// 120日均线颜色                 // 森林绿 private static final Color COLOR_MAVOL5 = new Color(138, 43, 226);// 5日均线颜色                  // 金黄 private static final Color COLOR_MAVOL10 = new Color(255, 0, 0);// 10日均线颜色 红 private static int W_P = 3;// 价格宽度 private static int W_V = 1;// 成交量宽度 private static int WIDTH = 900; private static int HEIGHT = 600; private static int P_H = (int) (HEIGHT * (1.0 * W_P / (W_P + W_V)));// 价格高度 private static int V_H = (int) (HEIGHT * (1.0 * W_V / (W_P + W_V)));// 成交量高度 private static Color upColor = Color.RED.brighter();// 股票上涨的颜色 亮红色 收盘价大于开盘价 private static Color downColor = Color.GREEN.brighter();// 股票下跌的颜色 亮绿色               // 开盘价小于收盘价

     public static void main(String[] args) {

      JFreeChart chart = buildChart();// 建表  ChartFrame chartFrame = new ChartFrame("股票行情分析图", chart);  charPanel = chartFrame.getChartPanel();  // 创建菜单栏  JMenuBar mnb = new JMenuBar();  // 创建菜单  /* 1 */JMenu mnuSystem = new JMenu("系统(S)");  /* 2 */JMenu mnuSystem1 = new JMenu("工具(T)");  // 创建菜单项  JMenuItem mniCopy = new JMenuItem("复制");  mniCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK));//设置快捷键Ctrl+C  mniCopy.addActionListener(new MyListener());      JMenuItem mniSaveas = new JMenuItem("另存为");  mniSaveas.addActionListener(new MyListener());   JMenuItem mniPrint = new JMenuItem("打印");  mniPrint.addActionListener(new MyListener());      JMenuItem mniEditChartProperties = new JMenuItem("属性");  mniEditChartProperties.addActionListener(new MyListener());   // 将菜单项添加到菜单中  mnuSystem.add(mniCopy);  mnuSystem.add(mniSaveas);  mnuSystem.addSeparator();  mnuSystem.add(mniPrint);  mnuSystem.addSeparator();  mnuSystem1.add(mniEditChartProperties );  // 将菜单添加到菜单栏中  /* 1 */mnb.add(mnuSystem);  /* 1 */mnb.add(mnuSystem1);    // 将菜单栏挂靠在框架上  chartFrame.setJMenuBar(mnb);  chartFrame.setSize(WIDTH, HEIGHT);// 设置尺寸  chartFrame.setVisible(true);// 设置为可见 } public static JFreeChart buildChart() {  // X共用轴  DateAxis domainAxis = new DateAxis();// 设置区域轴(即为X轴) 也就是 时间轴  // 设置时间线显示的规则,用这个方法就摒除掉了周六和周日这些没有交易的日期,使图形看上去连续  domainAxis.setTimeline(SegmentedTimeline    .newMondayThroughFridayTimeline());// SegmentedTimeline为分割时间线的意思  domainAxis.setAutoTickUnitSelection(false);// 设置不采用自动选择刻度值  domainAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);// 设置日期标签的位置                 // (需要将AutoTickUnitSelection设false)  domainAxis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());// 设置标准的时间刻度单位  // 数据轴的数据标签(可以只显示整数标签,需要将AutoTickUnitSelection设false)  //domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 1));//  // 设置时间刻度的间隔,一般以日为单位  domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 7));// 设置时间刻度的间隔,一般以周为单位   //domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 30));  // 设置时间刻度的间隔,一般以月为单位  domainAxis.setDateFormatOverride(new SimpleDateFormat("MM-dd"));// 设置显示时间的格式                  // 即用简单的时间显示格式(月-天)取代所要设置的时间显示格式  domainAxis.setLowerMargin(0.02D);// 下跌范围  domainAxis.setUpperMargin(0.02D);// 上涨范围  // 价格区(Plot)  // Y坐标轴  NumberAxis priceAxis = new NumberAxis() {// Y坐标轴(共用) 设置价格轴(即为Y轴)为数字轴   private static final long serialVersionUID = -8962863563900391155L;

       @Override   // 取代   public Paint getTickLabelPaint() {// 绘画 获取作记号的绘画标记    return Color.BLACK;   }

       @Override   public NumberFormat getNumberFormatOverride() {// 设定数据显示格式    return new DecimalFormat("0.00");   }

       @Override   public boolean getAutoRangeIncludesZero() {// 不自动包含0价格区    return false;   }  };  // priceAxis.Y轴  // 价格图区(共用区)ss

      XYPlot pricePlot = new XYPlot(null, domainAxis, priceAxis, null);  // 数据1  final OHLCDataset priceDataset = getPriceDataSet("000001");// MSFT  // 烛行图设定  CandlestickRenderer priceRenderer = new CandlestickRenderer();  priceRenderer.setSeriesPaint(0, Color.black);// 蜡烛框架颜色  priceRenderer.setDrawVolume(true);// 画成交量  priceRenderer.setUpPaint(upColor); // 上涨  priceRenderer.setDownPaint(downColor);// 下跌  // 收盘价的线  // 1天的priceDataset  XYDataset xyDataset1 = createAverageDataset(priceDataset, 1, 0);// 获取数据源  XYSplineRenderer xyRender1 = new XYSplineRenderer() {//创建一个新的渲染器指定的精度   private static final long serialVersionUID = 1859309003413288563L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_close;   }  };  // 均价图设定  // 5天均价  XYDataset xyDataset5 = createAverageDataset(priceDataset, 5, 0);// 获取数据源  XYSplineRenderer xyRender5 = new XYSplineRenderer() {   private static final long serialVersionUID = 1859309003413288563L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA5;   }  };  // 10天均价  XYDataset xyDataset10 = createAverageDataset(priceDataset, 10, 0);  XYSplineRenderer xyRender10 = new XYSplineRenderer() {   private static final long serialVersionUID = 1664318080312451661L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA10;   }  };  // 15天均价  XYDataset xyDataset15 = createAverageDataset(priceDataset, 15, 0);  XYSplineRenderer xyRender15 = new XYSplineRenderer() {   private static final long serialVersionUID = 5338323939520574140L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA15;   }  };  // 20天均价  XYDataset xyDataset20 = createAverageDataset(priceDataset, 20, 0);  XYSplineRenderer xyRender20 = new XYSplineRenderer() {   private static final long serialVersionUID = 2041484824762200102L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA20;   }  };

      // 30天均价  XYDataset xyDataset30 = createAverageDataset(priceDataset, 30, 0);  XYSplineRenderer xyRender30 = new XYSplineRenderer() {   private static final long serialVersionUID = 2041484824762200102L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA30;   }  };  // 60天均价  XYDataset xyDataset60 = createAverageDataset(priceDataset, 60, 0);  XYSplineRenderer xyRender60 = new XYSplineRenderer() {   private static final long serialVersionUID = 2041484824762200102L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA60;   }  };  // 120天均价  XYDataset xyDataset120 = createAverageDataset(priceDataset, 120, 0);  XYSplineRenderer xyRender120 = new XYSplineRenderer() {   private static final long serialVersionUID = 2041484824762200102L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MA120;   }  };  Paint gradientP = new GradientPaint(0, 0, new Color(252, 252, 200), 0,    P_H, new Color(252, 252, 252));// 画 价格梯度 渐变色 下至上(100,170,200)  Paint gradientV = new GradientPaint(0, 0, new Color(252, 252, 252), 0,    V_H, new Color(200, 150, 130));// 画 成交量梯度 渐变色 上(189,252,201)至下  pricePlot.setDataset(0, priceDataset);  pricePlot.setRenderer(0, priceRenderer);  pricePlot.setDataset(1, xyDataset5);  pricePlot.setRenderer(1, xyRender5);  pricePlot.setDataset(2, xyDataset10);  pricePlot.setRenderer(2, xyRender10);  pricePlot.setDataset(3, xyDataset15);  pricePlot.setRenderer(3, xyRender15);  pricePlot.setDataset(4, xyDataset20);  pricePlot.setRenderer(4, xyRender20);  pricePlot.setDataset(5, xyDataset30);  pricePlot.setRenderer(5, xyRender30);  pricePlot.setDataset(6, xyDataset60);  pricePlot.setRenderer(6, xyRender60);  pricePlot.setDataset(7, xyDataset120);  pricePlot.setRenderer(7, xyRender120);  pricePlot.setDataset(8, xyDataset1);  pricePlot.setRenderer(8, xyRender1);  pricePlot.setBackgroundPaint(gradientP);// 背景 渐变色  // 交易量区(Plot)  // IntervalXYDataset volumeDataset = getVolumeDataset(priceDataset,24L *  // 60 * 60 * 1000);  XYDataset volumeDataset = getVolumeDataset(priceDataset,    24L * 60 * 60 * 1000);  // Each bar is 24 hours wide(每条为24小时宽).XY数据间隔设置  // PS:在24后加一个L表示24为长整型  NumberAxis volumeAxis = new NumberAxis() {   private static final long serialVersionUID = -4910537548590143802L;

       @Override   public NumberFormat getNumberFormatOverride() {// 设定显示格式    return new DecimalFormat("0.00E00") {     private static final long serialVersionUID = 8224078094493778288L;

         @Override     public StringBuffer format(double number,       StringBuffer result, FieldPosition fieldPosition) {// 缓冲                    // 表示      String sb = super.format(number, result, fieldPosition)        .toString();      String[] ctx = sb.split("E");// 上下文 分割成“E”              // ctx=Context上下文      String first = ctx[0];      String second = ctx[1];      double fValue = Double.valueOf(first);      int sValue = Integer.valueOf(second);      if (fValue <= 0.001d) {       return new StringBuffer("0");      }      int tcount = 0;// 计数      String suffix = "";// 后缀/词尾      if (sValue < 3) {       tcount = sValue;       suffix = "";      } else if (sValue < 6) {       tcount = sValue - 3;       suffix = "K";      } else if (sValue < 9) {       tcount = sValue - 6;       suffix = "M";      } else if (sValue < 12) {       tcount = sValue - 9;       suffix = "G";      } else if (sValue < 15) {       tcount = sValue - 12;       suffix = "T";      } else {       return new StringBuffer("NaN");// 规范定义:NaN不等于任何数包括自己;float和doule存在特殊的值NaN      }      String symbol = "";// 记号      if (tcount == 0) {       symbol = "0.00";      } else if (tcount == 1) {       symbol = "00.0";      } else if (tcount == 2) {       symbol = "000";      }      DecimalFormat format = new DecimalFormat(symbol);// 小数的表示

          return new StringBuffer(format.format(fValue        * Math.pow(10, tcount))).append(suffix);// 缓冲表示                  // 表示为数学形式的计数.附上后缀     }    };   }

       @Override   public Paint getTickLabelPaint() {    return Color.black;   }  };  // XYPlot pricePlot = new XYPlot(null, domainAxis, priceAxis, null);    XYBarRenderer volumeRenderer = new XYBarRenderer() {   private static final long serialVersionUID = -4237832644518701189L;

    //   @Override      public Paint getSeriesPaint(int series) {        return Color.blue.brighter();  }   

      };// 实例化一个类{}类后加;

      // volumePlot区域  XYPlot volumePlot = new XYPlot(volumeDataset, null, volumeAxis,    volumeRenderer);  // XYPlot plot2=new  // XYPlot(timeSeriesCollection,null,y2Axis,xyBarRender);  volumePlot.setBackgroundPaint(gradientV);// 背景颜色为渐变色

      // 5天均量价  XYDataset xyDatasetVOL5 = createAverageDataset(volumeDataset, 5, 0);  XYSplineRenderer xyRenderVOL5 = new XYSplineRenderer() {   private static final long serialVersionUID = 2041484824762200102L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MAVOL5;   }  };  // 10天均量价  XYDataset xyDatasetVOL10 = createAverageDataset(volumeDataset, 10, 0);  XYSplineRenderer xyRenderVOL10 = new XYSplineRenderer() {   private static final long serialVersionUID = 2041484824762200102L;

       @Override   public Boolean getSeriesShapesVisible(int series) {    return false;   }

       @Override   public Paint getSeriesPaint(int series) {    return COLOR_MAVOL10;   }  };  volumePlot.setDataset(0, volumeDataset);  volumePlot.setRenderer(0, volumeRenderer);  volumePlot.setDataset(1, xyDatasetVOL5);  volumePlot.setRenderer(1, xyRenderVOL5);  volumePlot.setDataset(2, xyDatasetVOL10);  volumePlot.setRenderer(2, xyRenderVOL10);  // 把各个区统一起来  CombinedDomainXYPlot mainPlot = new CombinedDomainXYPlot(domainAxis);  mainPlot.add(pricePlot, 2);  mainPlot.add(volumePlot, 1);  mainPlot.setGap(5.0d);// 设定各区之间的间隔  // 自定义图例  LegendItemCollection legendItemCollection = createLegendItems();  mainPlot.setFixedLegendItems(legendItemCollection);

      return new JFreeChart("深发展A", null, mainPlot, true); }

     // 自定义图例 private static LegendItemCollection createLegendItems() {  LegendItemCollection legenditemcollection1 = new LegendItemCollection();  LegendItem legenditem1 = new LegendItem("MA5", "-", "5日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA5);  LegendItem legenditem2 = new LegendItem("MA10", "-", "10日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA10);  LegendItem legenditem3 = new LegendItem("MA15", "-", "15日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA15);  LegendItem legenditem4 = new LegendItem("MA20", "-", "20日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA20);  LegendItem legenditem5 = new LegendItem("MA30", "-", "30日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA30);  LegendItem legenditem6 = new LegendItem("MA60", "-", "60日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA60);  LegendItem legenditem7 = new LegendItem("MA120", "-", "120日均价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MA120);  LegendItem legenditem8 = new LegendItem("close", "-", "收盘线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_close);  LegendItem legenditem11 = new LegendItem("MAVOL5", "-", "5日均量价线", null,    Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MAVOL5);  LegendItem legenditem12 = new LegendItem("MAVOL10", "-", "10日均量价线",    null, Plot.DEFAULT_LEGEND_ITEM_BOX, COLOR_MAVOL10);

      legenditemcollection1.add(legenditem1);  legenditemcollection1.add(legenditem2);  legenditemcollection1.add(legenditem3);  legenditemcollection1.add(legenditem4);  legenditemcollection1.add(legenditem5);  legenditemcollection1.add(legenditem6);  legenditemcollection1.add(legenditem7);  legenditemcollection1.add(legenditem8);  legenditemcollection1.add(legenditem11);  legenditemcollection1.add(legenditem12);

      return legenditemcollection1;// 插图条的采集

     }

     protected static OHLCDataset getPriceDataSet(String symbol) {  List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>();  try {//   String strUrl = "http://ichart.finance.yahoo.com/table.csv?s="//     + symbol + "&a=8&b=1&c=2009&d=12&e=30&f=2009&ignore=.csv";//   URL url = new URL(strUrl);//   BufferedReader in = new BufferedReader(new InputStreamReader(url                   //     .openStream()));    BufferedReader in = new BufferedReader(new FileReader("c://SZ000001.TXT"));   DateFormat df = new SimpleDateFormat("y-M-d");   String inputLine;   in.readLine();   while ((inputLine = in.readLine()) != null) {    StringTokenizer st = new StringTokenizer(inputLine, ",");    Date date = df.parse(st.nextToken());    double open = Double.parseDouble(st.nextToken());//nextToken() 用于返回下一个匹配的字段    double high = Double.parseDouble(st.nextToken());    double low = Double.parseDouble(st.nextToken());    double close = Double.parseDouble(st.nextToken());    double volume = Double.parseDouble(st.nextToken());    // double adjClose = Double.parseDouble( st.nextToken() );    OHLCDataItem item = new OHLCDataItem(date, open, high, low,      close, volume);//数据条的显示    dataItems.add(item);   }   in.close();  } catch (Exception e) {   e.printStackTrace();  }  Collections.reverse(dataItems);  OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems    .size()]);  return new DefaultOHLCDataset("", data); }

     protected static IntervalXYDataset getVolumeDataset( // XY数据源间隔 获取成交量数据源   final OHLCDataset priceDataset, final long barWidthInMilliseconds) {  return new AbstractIntervalXYDataset() {   private static final long serialVersionUID = 2289539752052175826L;

       public int getSeriesCount() {    return priceDataset.getSeriesCount();   }

       @SuppressWarnings("unchecked")   public Comparable getSeriesKey(int series) {    return priceDataset.getSeriesKey(series) + "-Volume";   }

       public int getItemCount(int series) {    return priceDataset.getItemCount(series);   }

       public Number getX(int series, int item) {    return priceDataset.getX(series, item);   }

       public Number getY(int series, int item) {    return priceDataset.getVolume(series, item);   }

       public Number getStartX(int series, int item) {    return priceDataset.getX(series, item).doubleValue()      - barWidthInMilliseconds / 2;   }

       public Number getEndX(int series, int item) {    return priceDataset.getX(series, item).doubleValue()      + barWidthInMilliseconds / 2;   }   public Number getStartY(int series, int item) {    return new Double(0.0d);   }

       public Number getEndY(int series, int item) {    return priceDataset.getVolume(series, item);   }  }; }

     /**  * 转化为N日均线  *   * @param day  * @return  */ private static XYDataset createAverageDataset(final XYDataset source,   final int day, final int daySkip) {  XYDataset xyDataset = MovingAverage.createMovingAverage(source, day    + "日均线", 24L * 60 * 60 * 1000 * day, // day天为一个周期    24L * 60 * 60 * 1000 * daySkip); // 最开始的daySkip天跳过  return xyDataset; }

    }class MyListener implements ActionListener{

     public void actionPerformed(ActionEvent e) {  // System.out.println(e.getActionCommand());  CandlestickVolume panel = new CandlestickVolume();  if ("另存为".equals(e.getActionCommand())) {      try {    panel.charPanel.doSaveAs();   } catch (IOException e1) {    // TODO Auto-generated catch block    e1.printStackTrace();   }  }else if ("复制".equals(e.getActionCommand())) {       panel.charPanel.doCopy();  }else if ("打印".equals(e.getActionCommand())) {      panel.charPanel.createChartPrintJob(); }else if("属性".equals(e.getActionCommand())){  panel.charPanel.doEditChartProperties(); } } }

     当代码  String strUrl = "http://ichart.finance.yahoo.com/table.csv?s="//     + symbol + "&a=8&b=1&c=2009&d=12&e=30&f=2009&ignore=.csv";//   URL url = new URL(strUrl);//   BufferedReader in = new BufferedReader(new InputStreamReader(url                   //     .openStream()));

    修改成BufferedReader in = new BufferedReader(new FileReader("c://SZ000001.TXT"));的时候显示出来的图的折线没掉了,也就是没有了均线!!求高手帮忙修改!!

    如何修改折线?

    final OHLCDataset priceDataset = getPriceDataSet("000001");  //"000001"这个为TXT的文件名称

    求高手帮忙


    最新回复(0)