股票K线图-JfreeChart版
http://blog.csdn.net/ami121/article/details/3953272
股票的K线图是所有Chart图中最复杂的一种,把一个K线图拆分开来我们可以发现,K线图的上半截实际上是由阴阳线(阴阳线可以表示开盘价,收盘价,最高价,最低价)、和若干条随时间变化的若干条均线组成;下半截则由与阴阳线对应的成交量柱形图和若干条随时间变化的成交量均线组成。如下图:
了解这一点之后,对照JFreeChart我们发现所有的单个Chart它都已经提供了,我们所需要做的就是把这些Chart进行组合,进而形成一张K线图。
股票中的阴阳线,我们可以用OHLCDataset(蜡烛图)来实现,均线可以用IntervalXYDataset来实现,对于与阴阳线对应的成交量的值我们同样可以用OHLCDataset来实现,只是在编程的时候注意些技艺就可以实现了。
表示阴阳线的(蜡烛图)OHLCDataset如下图:
表示均线的IntervalXYDataset图如下:
对于K线图的上半部分我们可以用JFreeChart中的蜡烛图与时间线图的叠加来完成,下半部分我们同样可以用JFreeChart中的蜡烛图与时间线图的叠加来完成。完成之后我们只需要将上下两部分Chart用CombinedDomainXYPlot进行组合,得到的结果就是我们想要的K线图。知道中明确了这些信息之后我们就可以动手来做JFreeChart版的K线图啦。
这里我们采用JFreeChart的最新版jfreechart-1.0.6来实现。为了方便我们把做好的K线图放到网页当中我们采用Applet来作为载体。同时为了不让Applet直接去访问数据库我们利用Bstek公司的J2EE前端展现产品Dorado5来在客户端为K线图的Applet传递数据,接下来我们就来一步一步实现我们的K线图JFreeChart版。
1) 构造一个为K线图提供数据的表,表结构如下 :
|
create table k_line_data( stock_name varchar(100),--股票名称 issue_date date,//日期 open_value double,//开盘价 high_value double,//最高价 low_value double,//最低价 close_value double,//收盘价 volume_value double,//成交量 avg5 double,//5日均价 avg10 double,//10日均价 avg20 double,20日均价 avg60 double,//60日均价 vol_avg5 double,//5日成交量均价 vol_avg10 double//10日成交量均价 ) |
接下来我们需要虚拟一些数据出来提供给K线图使用,我们用Dorado5展现的效果如下:
我们要实现的效果是在客户端通过Dorado5中的Dataset通过JS来调用Applet里的方法,为Applet里的K线图提供数据,这样做就避免了我们在Applet里直接去访问服务器端的数据库里的数据。
2) Applet代码如下:
|
package test.applet; import java.awt.Color; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.JApplet; import javax.swing.JPanel; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickUnit; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.block.BlockBorder; import org.jfree.chart.block.BlockContainer; import org.jfree.chart.block.BorderArrangement; import org.jfree.chart.labels.StandardXYToolTipGenerator; 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.XYLineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.data.general.Dataset; import org.jfree.data.time.Day; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.xy.DefaultHighLowDataset; import org.jfree.data.xy.IntervalXYDataset; import org.jfree.data.xy.OHLCDataset; import org.jfree.ui.HorizontalAlignment; import org.jfree.ui.RectangleEdge; public class TestApplet extends JApplet { List ls = new ArrayList();//定义一个用来保存数据的集合类List Map map = null;//用来表示一条记录 public TestApplet() {//将Chart在 Applet中显示 JPanel jpanel = createDemoPanel(); setContentPane(jpanel); } public void clearList(){//清空保存数据的集合类List ls.clear(); } private JFreeChart createCombinedChart() { Map m = createDatasetMap();//从数据对象里取出各种类型的对象,主要是用来表示均线的时间线(IntervalXYDataset)对象和用来表示阴阳线和成交量的蜡烛图对象(OHLCDataset) IntervalXYDataset avg_line5 = (IntervalXYDataset) m.get("avg_line5"); IntervalXYDataset avg_line10 = (IntervalXYDataset) m.get("avg_line10"); IntervalXYDataset avg_line20 = (IntervalXYDataset) m.get("avg_line20"); IntervalXYDataset avg_line60 = (IntervalXYDataset) m.get("avg_line60"); IntervalXYDataset vol_avg_line5 = (IntervalXYDataset) m .get("vol_avg_line5"); IntervalXYDataset vol_avg_line10 = (IntervalXYDataset) m .get("vol_avg_line10"); OHLCDataset k_line = (OHLCDataset) m.get("k_line"); OHLCDataset vol = (OHLCDataset) m.get("vol"); String stock_name = (String) m.get("stock_name"); //设置若干个时间线的Render,目的是用来让几条均线显示不同的颜色,和为时间线加上鼠标提示 XYLineAndShapeRenderer xyLineRender = new XYLineAndShapeRenderer(true, false); xyLineRender.setBaseToolTipGenerator(new StandardXYToolTipGenerator( "{0}: ({1}, {2})", new SimpleDateFormat("yyyy-MM-dd"), new DecimalFormat("0.00"))); xyLineRender.setSeriesPaint(0, Color.red); XYLineAndShapeRenderer xyLineRender1 = new XYLineAndShapeRenderer(true, false); xyLineRender1.setBaseToolTipGenerator(new StandardXYToolTipGenerator( "{0}: ({1}, {2})", new SimpleDateFormat("yyyy-MM-dd"), new DecimalFormat("0.00"))); xyLineRender1.setSeriesPaint(0, Color.BLACK); XYLineAndShapeRenderer xyLineRender2 = new XYLineAndShapeRenderer(true, false); xyLineRender1.setBaseToolTipGenerator(new StandardXYToolTipGenerator( "{0}: ({1}, {2})", new SimpleDateFormat("yyyy-MM-dd"), new DecimalFormat("0.00"))); xyLineRender1.setSeriesPaint(0, Color.blue); XYLineAndShapeRenderer xyLineRender3 = new XYLineAndShapeRenderer(true, false); xyLineRender1.setBaseToolTipGenerator(new StandardXYToolTipGenerator( "{0}: ({1}, {2})", new SimpleDateFormat("yyyy-MM-dd"), new DecimalFormat("0.00"))); xyLineRender1.setSeriesPaint(0, Color.darkGray); //定义K线图上半截显示的Plot XYPlot volPlot = new XYPlot(vol_avg_line5, null, new NumberAxis( "股票价格情况"), xyLineRender); //定义一个CandlestickRenderer给蜡烛图对象使用,目的是对蜡烛图对象的显示进行调整,这里主要是调整它显示的宽度并加上鼠标提示 CandlestickRenderer candlesRender = new CandlestickRenderer(); candlesRender.setCandleWidth(4D); candlesRender.setBaseToolTipGenerator(new StandardXYToolTipGenerator( "{0}: ({1}, {2})", new SimpleDateFormat("yyyy-MM-dd"), new DecimalFormat("0.00"))); //把其它的几个Dataset加到上半截要显示的Plot里,并同时设置它们所采用的Render,以形成一个叠加显示的效果 volPlot.setDataset(1, vol_avg_line10); volPlot.setRenderer(1, xyLineRender1); volPlot.setDataset(2, vol); volPlot.setRenderer(2, candlesRender); XYPlot candlePlot = new XYPlot(k_line, null, new NumberAxis( ""), candlesRender); candlePlot.setDataset(1, avg_line5); candlePlot.setRenderer(1, xyLineRender1); candlePlot.setDataset(2, avg_line10); candlePlot.setRenderer(2, xyLineRender2); candlePlot.setDataset(3, avg_line20); candlePlot.setRenderer(3, xyLineRender3); candlePlot.setDataset(4, avg_line60); candlePlot.setRenderer(4, xyLineRender); DateAxis dateaxis = new DateAxis("K线图"); dateaxis.setTickUnit(new DateTickUnit(1, 1, new SimpleDateFormat( "MM/yy")));//设置日期格式及显示日期的间隔 dateaxis.setLowerMargin(0.0D); dateaxis.setUpperMargin(0.02D); //定义一个复合类型的Plot,目的是为了把Chart的上半截和下半截结合起来,形成一张完整的K线图 CombinedDomainXYPlot combineXY = new CombinedDomainXYPlot(dateaxis); //把上下两个Plot都加到复合Plot里,并设置它们在图中所占的比重 combineXY.add(candlePlot, 3); combineXY.add(volPlot, 1); combineXY.setGap(8D); combineXY.setDomainGridlinesVisible(true); JFreeChart jfreechart = new JFreeChart(stock_name, JFreeChart.DEFAULT_TITLE_FONT, combineXY, false); jfreechart.setBackgroundPaint(Color.white); //为Chart图添加一个图例,这里我们可以定义需要显示的一些信息,及图例放置的位置,我们选择的顶部 LegendTitle legendtitle = new LegendTitle(candlePlot); BlockContainer blockcontainer = new BlockContainer( new BorderArrangement()); blockcontainer.setFrame(new BlockBorder(0.10000000000000001D, 0.10000000000000001D, 0.10000000000000001D, 0.10000000000000001D)); BlockContainer blockcontainer1 = legendtitle.getItemContainer(); blockcontainer1.setPadding(2D, 10D, 5D, 2D); blockcontainer.add(blockcontainer1); legendtitle.setWrapper(blockcontainer); legendtitle.setPosition(RectangleEdge.TOP); legendtitle.setHorizontalAlignment(HorizontalAlignment.CENTER); jfreechart.addSubtitle(legendtitle); return jfreechart; } ///该方法主要是为WEB端的JS调用,定义一个新的Map,插入一行空的记录 public void insertRecord() { map = new HashMap(); } ///该方法主要是为WEB端的JS调用,为当前记录设置值 public void setValue(String key, String value) { map.put(key, value); } ///该方法主要是为WEB端的JS调用,把当前记录添加到记录集List里 public void postRecord() { ls.add(map); } public Map createDatasetMap() { //从每一行记录里取出特定值,用来开成各种类型的均线和阴阳线图 Map m = new HashMap(); TimeSeries avg_lin5 = new TimeSeries("5日均线", org.jfree.data.time.Day.class); TimeSeries avg_lin10 = new TimeSeries("10日均线", org.jfree.data.time.Day.class); TimeSeries avg_lin20 = new TimeSeries("20日均线", org.jfree.data.time.Day.class); TimeSeries avg_lin60 = new TimeSeries("60日均线", org.jfree.data.time.Day.class); TimeSeries vol_avg_lin5 = new TimeSeries( "5日成交量均线", org.jfree.data.time.Day.class); TimeSeries vol_avg_lin10 = new TimeSeries( "10日成交量均线", org.jfree.data.time.Day.class); int count = ls.size(); Date adate[] = new Date[count]; double high[] = new double[count]; double low[] = new double[count]; double close[] = new double[count]; double open[] = new double[count]; double volume[] = new double[count]; Date adate1[] = new Date[count]; double high1[] = new double[count]; double low1[] = new double[count]; double close1[] = new double[count]; double open1[] = new double[count]; double volume1[] = new double[count]; String stock_name = null; Calendar cal = Calendar.getInstance(); for (int j = 0; j < ls.size(); j++) { Map vMap = (Map) ls.get(j); stock_name = (String) vMap.get("stock_name"); Date issue_date = new Date(Long.parseLong(vMap.get("issue_date") .toString())); double open_value = Double.parseDouble(vMap.get("open_value") .toString()); double high_value = Double.parseDouble(vMap.get("high_value") .toString()); double low_value = Double.parseDouble(vMap.get("low_value") .toString()); double close_value = Double.parseDouble(vMap.get("close_value") .toString()); double avg5 = Double.parseDouble(vMap.get("avg5").toString()); double avg10 = Double.parseDouble(vMap.get("avg10").toString()); double avg20 = Double.parseDouble(vMap.get("avg20").toString()); double avg60 = Double.parseDouble(vMap.get("avg60").toString()); double volume_value = Double.parseDouble(vMap.get("volume_value") .toString()); double vol_avg5 = Double.parseDouble(vMap.get("vol_avg5") .toString()); double vol_avg10 = Double.parseDouble(vMap.get("vol_avg10") .toString()); cal.setTime(issue_date); if (avg5 > 0.0D) avg_lin5.addOrUpdate(new Day(cal.get(5), cal.get(2) + 1, cal.get(1)), avg5); if (avg10 > 0.0D) avg_lin10.addOrUpdate(new Day(cal.get(5), cal.get(2) + 1, cal.get(1)), avg10); if (avg20 > 0.0D) avg_lin20.addOrUpdate(new Day(cal.get(5), cal.get(2) + 1, cal.get(1)), avg20); if (avg60 > 0.0D) avg_lin60.addOrUpdate(new Day(cal.get(5), cal.get(2) + 1, cal.get(1)), avg60); if (vol_avg5 > 0.0D) vol_avg_lin5.addOrUpdate( new Day(cal.get(5), cal.get(2) + 1, cal.get(1)), vol_avg5); if (vol_avg10 > 0.0D) vol_avg_lin10.addOrUpdate(new Day(cal.get(5), cal.get(2) + 1, cal .get(1)), vol_avg10); adate[j] = issue_date; high[j] = high_value; low[j] = low_value; close[j] = close_value; open[j] = open_value; volume[j] = 0.0D; adate1[j] = issue_date; high1[j] = 0.0D; low1[j] = 0.0D; close1[j] = 0.0D; open1[j] = 0.0D; //这里是我们用蜡烛图来构造与阴阳线对应的成交量图,我们主要是通过判断开盘价与收盘价相比较的值来决定到底是在表示成交量的蜡烛图的开盘价设置值还是收盘价设置值,设置之前我们把它们全部都设置为0 if (open_value < close_value) close1[j] = volume_value; else open1[j] = volume_value; volume1[j] = 0.0D; } DefaultHighLowDataset k_line = new DefaultHighLowDataset("", adate, high, low, close, open, volume); DefaultHighLowDataset vol = new DefaultHighLowDataset( "", adate1, high1, low1, close1, open1, volume1); //把各种类型的图表对象放到Map里,以为其它方法提供使用 m.put("k_line", k_line); m.put("vol", vol); m.put("stock_name", stock_name); m.put("avg_line5", new TimeSeriesCollection(avg_lin5)); m.put("avg_line10", new TimeSeriesCollection(avg_lin10)); m.put("avg_line20", new TimeSeriesCollection(avg_lin20)); m.put("avg_line60", new TimeSeriesCollection(avg_lin60)); m.put("vol_avg_line5", new TimeSeriesCollection(vol_avg_lin5)); m.put("vol_avg_line10", new TimeSeriesCollection(vol_avg_lin10)); return m; } //该方法主要是为WEB端的JS调用,用来动态改变K线图 public void changeApplet() { Map m = createDatasetMap(); IntervalXYDataset avg_line5 = (IntervalXYDataset) m.get("avg_line5"); IntervalXYDataset avg_line10 = (IntervalXYDataset) m.get("avg_line10"); IntervalXYDataset avg_line20 = (IntervalXYDataset) m.get("avg_line20"); IntervalXYDataset avg_line60 = (IntervalXYDataset) m.get("avg_line60"); IntervalXYDataset vol_avg_line5 = (IntervalXYDataset) m .get("vol_avg_line5"); IntervalXYDataset vol_avg_line10 = (IntervalXYDataset) m .get("vol_avg_line10"); OHLCDataset k_line = (OHLCDataset) m.get("k_line"); OHLCDataset vol = (OHLCDataset) m.get("vol"); ChartPanel panel = (ChartPanel) getContentPane(); JFreeChart chart = panel.getChart(); CombinedDomainXYPlot plot = (CombinedDomainXYPlot) chart.getPlot(); List list=plot.getSubplots(); XYPlot candlePlot = (XYPlot)list.get(0); candlePlot.setDataset(0, k_line); candlePlot.setDataset(1, avg_line5); candlePlot.setDataset(2, avg_line10); candlePlot.setDataset(3, avg_line20); candlePlot.setDataset(4, avg_line60); XYPlot volPlot = (XYPlot)list.get(1); volPlot.setDataset(0,vol); volPlot.setDataset(1,vol_avg_line5); volPlot.setDataset(2,vol); volPlot.setDataset(3,vol_avg_line10); repaint(); } public JPanel createDemoPanel() { JFreeChart jfreechart = createCombinedChart(); return new ChartPanel(jfreechart); } } |
接下来我们需要将该Applet放入JSP里,JSP代码如下:
|
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib uri="http://www.bstek.com/dorado" prefix="d" %> <html> <head> <title></title> </head> <body> <d:View config="test.applet.TestView"> <d:DataTable id="table1" /> <d:Button id="buttonAdd" /> <d:Button id="buttonDel" /> <APPLET name="klineApplet" CODE="test.applet.TestApplet" archive="/k-line/source/jcommon-1.0.10.jar,/k-line/source/jfreechart-1.0.6.jar" codebase="/k-line/source/" width="100%" height="600" MAYSCRIPT> </APPLET> </d:View> </body> </html> |
同时,我们还要写一段JS来调用Applet,并为Applet里的K线图填充数据,JS函数如下:
|
function changeKLine(){ var applet=document.klineApplet; var record = datasetStock.getFirstRecord(); var start=new Date(); applet.clearList(); while (record) { applet.insertRecord(); var stock_name=record.getValue("stock_name"); applet.setValue("stock_name",stock_name); var issue_date=record.getValue("issue_date").getTime(); applet.setValue("issue_date",issue_date); var open_value=record.getValue("open_value"); applet.setValue("open_value",open_value); var high_value=record.getValue("high_value"); applet.setValue("high_value",high_value); var low_value=record.getValue("low_value"); applet.setValue("low_value",low_value); var close_value=record.getValue("close_value"); applet.setValue("close_value",close_value); var volume_value=record.getValue("volume_value"); applet.setValue("volume_value",volume_value); var avg5=record.getValue("avg5"); applet.setValue("avg5",avg5); var avg10=record.getValue("avg10"); applet.setValue("avg10",avg10); var avg20=record.getValue("avg20"); applet.setValue("avg20",avg20); var avg60=record.getValue("avg60"); applet.setValue("avg60",avg60); var vol_avg5=record.getValue("vol_avg5"); applet.setValue("vol_avg5",vol_avg5); var vol_avg10=record.getValue("vol_avg5"); applet.setValue("vol_avg10",vol_avg10); record = record.getNextRecord(); applet.postRecord(); } applet.changeApplet(); } |
同时,我们要在Dorado5的View里Dataset不同的事件里调用该JS函数,View的源代码如下:
|
<?xml version="1.0" encoding="UTF-8"?> <view> <Datasets> <Dataset id="datasetStock" type="Wrapper" wrappedType="AutoSql" dataSource="doradosample" originTable="K_LINE_DATA" pageSize="0"> <Joins /> <Fields> <Field name="STOCK_NAME" originField="STOCK_NAME" table="K_LINE_DATA" dataType="string" group="false" label="股票名称"> <Properties /> <Validator type="Required" /> </Field> <Field name="ISSUE_DATE" originField="ISSUE_DATE" table="K_LINE_DATA" dataType="date" group="false" label="时间"> <Properties /> <Validator type="Required" /> </Field> <Field name="OPEN_VALUE" originField="OPEN_VALUE" table="K_LINE_DATA" dataType="double" group="false" label="开盘价" defaultValue="0"> <Properties /> <Validator type="Required" /> </Field> <Field name="HIGH_VALUE" originField="HIGH_VALUE" table="K_LINE_DATA" dataType="double" group="false" label="最高价" defaultValue="0"> <Properties /> <Validator type="Required" /> </Field> <Field name="LOW_VALUE" originField="LOW_VALUE" table="K_LINE_DATA" dataType="double" group="false" label="最低价" defaultValue="0"> <Properties /> <Validator type="Required" /> </Field> <Field name="CLOSE_VALUE" originField="CLOSE_VALUE" table="K_LINE_DATA" dataType="double" group="false" label="收盘价" defaultValue="0"> <Properties /> <Validator type="Required" /> </Field> <Field name="VOLUME_VALUE" originField="VOLUME_VALUE" table="K_LINE_DATA" dataType="double" group="false" label="成交量" defaultValue="0"> <Properties /> <Validator type="Required" /> </Field> <Field name="AVG5" originField="AVG5" table="K_LINE_DATA" dataType="double" group="false" label="五日均价" defaultValue="0"> <Properties /> </Field> <Field name="AVG10" originField="AVG10" table="K_LINE_DATA" dataType="double" group="false" label="十日均价" defaultValue="0"> <Properties /> </Field> <Field name="AVG20" originField="AVG20" table="K_LINE_DATA" dataType="double" group="false" label="二十日均价" defaultValue="0"> <Properties /> </Field> <Field name="AVG60" originField="AVG60" table="K_LINE_DATA" dataType="double" group="false" label="六十日均价" defaultValue="0"> <Properties /> </Field> <Field name="VOL_AVG5" originField="VOL_AVG5" table="K_LINE_DATA" dataType="double" group="false" label="成交量五日均价" defaultValue="0"> <Properties /> </Field> <Field name="VOL_AVG10" originField="VOL_AVG10" table="K_LINE_DATA" dataType="double" group="false" label="成交量十日均价" defaultValue="0"> <Properties /> </Field> </Fields> <MatchRules /> <SortRules /> <MasterLink /> <Parameters /> <Properties /> <Events> <Event name="afterDelete">changeKLine()</Event> <Event name="afterPost">changeKLine()</Event> </Events> </Dataset> </Datasets> <Controls> <Control id="table1" type="DataTable" dataset="datasetStock" height="500" width="100%"> <Column name="STOCK_NAME" field="STOCK_NAME" /> <Column name="ISSUE_DATE" field="ISSUE_DATE" /> <Column name="OPEN_VALUE" field="OPEN_VALUE" /> <Column name="HIGH_VALUE" field="HIGH_VALUE" /> <Column name="LOW_VALUE" field="LOW_VALUE" /> <Column name="CLOSE_VALUE" field="CLOSE_VALUE" /> <Column name="VOLUME_VALUE" field="VOLUME_VALUE" /> <Column name="AVG5" field="AVG5" /> <Column name="AVG10" field="AVG10" /> <Column name="AVG20" field="AVG20" /> <Column name="AVG60" field="AVG60" /> <Column name="VOL_AVG5" field="VOL_AVG5" /> <Column name="VOL_AVG10" field="VOL_AVG10" /> </Control> <Control id="buttonAdd" type="Button" value=" 添加一条记录 "> <Events> <Event name="onClick">datasetStock.insertRecord();</Event> </Events> </Control> <Control id="buttonDel" type="Button" value=" 删除当前记录 "> <Events> <Event name="onClick">datasetStock.deleteRecord();</Event> </Events> </Control> </Controls> <Properties /> <Events> <Event name="functions">function changeKLine(){ var applet=document.klineApplet; var record = datasetStock.getFirstRecord(); var start=new Date(); applet.clearList(); while (record) { applet.insertRecord(); var stock_name=record.getValue("stock_name"); applet.setValue("stock_name",stock_name); var issue_date=record.getValue("issue_date").getTime(); applet.setValue("issue_date",issue_date); var open_value=record.getValue("open_value"); applet.setValue("open_value",open_value); var high_value=record.getValue("high_value"); applet.setValue("high_value",high_value); var low_value=record.getValue("low_value"); applet.setValue("low_value",low_value); var close_value=record.getValue("close_value"); applet.setValue("close_value",close_value); var volume_value=record.getValue("volume_value"); applet.setValue("volume_value",volume_value); var avg5=record.getValue("avg5"); applet.setValue("avg5",avg5); var avg10=record.getValue("avg10"); applet.setValue("avg10",avg10); var avg20=record.getValue("avg20"); applet.setValue("avg20",avg20); var avg60=record.getValue("avg60"); applet.setValue("avg60",avg60); var vol_avg5=record.getValue("vol_avg5"); applet.setValue("vol_avg5",vol_avg5); var vol_avg10=record.getValue("vol_avg5"); applet.setValue("vol_avg10",vol_avg10); record = record.getNextRecord(); applet.postRecord(); } applet.changeApplet(); }</Event> <Event name="onLoad">changeKLine()</Event> </Events> </view> |
启动工程,浏览我们的JSP,我们看到如下效果:
这时我们可以尝试对Dorado5表格中的任一数据做修改,我们发现在下面的Applet里的K线图也会做相应的变化,而且这一变化是在页面没有刷新的情况下实现的。
- 顶
股票K线图-JfreeChart版的更多相关文章
- 利用JFreeChart绘制股票K线图完整解决方案
http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...
- IOS 股票K线图、分时图
IOS 股票K线图.分时图,网上开源项目很少,质量也是参差不齐:偶尔搜索到看似有希望的文章,点进去,还是个标题党:深受毒害.经过一段时间的探索,终于在开源基础上完成了自己的股票K线图.分时图: 先放出 ...
- 基于Echarts的股票K线图展示
发布时间:2018-10-31 技术:javascript+html5+canvas 概述 基于echarts的股票K线图展示,只需引用单个插件,通过简单配置,导入数据,即可实现炫酷复杂的K线 ...
- Highstock生成股票K线图
在线演示 本地下载 使用HightStock生成股票K线图例子.
- WPF中使用amCharts绘制股票K线图
原文:WPF中使用amCharts绘制股票K线图 本想自己用GDI绘图, 通过数据直接绘制一张蜡柱图, 但觉得这样子的功能比较少, 所以到网上搜索一些能画出K线图的控件. 发现DynamicDataD ...
- PHP使用HighChart生成股票K线图详解
本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群: 281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...
- python pandas 画图、显示中文、股票K线图
目录: 1.pandas官方画图链接 2.标记图中数据点 3.画图显示中文 4.画股票K线图 5.matplotlib基本用法 6.format输出 6.format输出例子 eps_range=[0 ...
- YYStock开源----iOS股票K线绘制第二版
新的股票绘制粗来啦,欢迎围观star的说(*^__^*) 嘻嘻-- 捏合功能也准备完善了 Github:https://github.com/yate1996/YYStock 长按分时图+五档图 分时 ...
- C#下如何用NPlot绘制期货股票K线图(2):读取数据文件让K线图自动更新
[内容介绍]上一篇介绍了K线图的基本绘制方法,但很不完善,本篇增加了它直接读取数据的功能,这对于金融市场的数据量大且又需要动态刷新功能的实现很重要. [实现方法] 1.需要一个数据文件,这里用的是直接 ...
随机推荐
- 关于:1.指针与对象;2.深浅拷贝(复制);3.可变与不可变对象;4.copy与mutableCopy的一些理解
最近对深浅拷贝(复制)做了一些研究,在此将自己的理解写下来,希望对大家有所帮助.本人尚处在摸索阶段,希望各位予以指正. 本文包括如下方向的探索: 1.指针与对象: 2.深/浅拷贝(复制): 3.可变/ ...
- Struts2 Spring3 Hibernate3 集成xml版本
Struts2 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互 ...
- isset()和empty()的区别
form表单的数据提交过来 如果用isset() if(isset($_GET)){ .....} '' '0' 0 返回 true 不够严谨 empty() '' '0' 0 显示返回false 比 ...
- Python第二天课程
创建列表的方式 list= [XX,XX] 或 list1 = list()使用list方法,将字符串或元祖创建为列表 列表名[其实位置:结束位置] 取列表中的特定元素 >>> na ...
- phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接。
phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接.您应该检查配置文件中的主机.用户名和密码,并确认这些信息与 MySQL 服务器管理员所给出的信息一致. 错误产生原因: 修改了 ...
- Solr搜索技术
Solr搜索技术 今日大纲 回顾上一天的内容: 倒排索引 lucene和solr的关系 lucene api的使用 CRUD 文档.字段.目录对象(类).索引写入器类.索引写入器配置类.IK分词器 查 ...
- USACO 2.3 Cow Pedigrees
Cow Pedigrees Silviu Ganceanu -- 2003 Farmer John is considering purchasing a new herd of cows. In t ...
- 第八十八节,html5+css3pc端固定布局,搜索区,插入大图,搜索框
html5+css3pc端固定布局,搜索区,插入大图,搜索框 设置一个div作为搜索区域 1.宽度为百分之百 2.最小宽度为1263,因为要考虑到手机,等小屏幕缩小后宽度会自适应,导致破坏布局,将最小 ...
- Struts2-3.struts.xml的action可以简写
如果只是跳转到某个页面的话,可以这样写 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE s ...
- Struts2-2.了解struts.xml>package>action>result的name属性
result决定跳转到哪个视图(jsp),可以预设值有多个. <?xml version="1.0" encoding="UTF-8" ?> < ...