概述
本示例用来展示dorado与JfreeChart的结合,用来展示JfreeChart的甘特图。除JFreeChart,本示例还采用了Cewolf,可以看知识点部分。本示例链接如下:
准备工作
步骤1:新建一工程gantt,并且配置好数据库,具体步骤参考3.1.2节。
步骤2:下载cewolf。下载链接如下:
步骤3:解压下载的cewolf-1.0-bin-src.zip,拷贝cewolf/lib文件夹下面的如下文件到您web工程的web-inf/lib目录下面:jfreechart-.jar、jcommon-.jar、commons-logging.jar、cewolf.jar、batik-xml.jar、batik-util.jar、batik-svggen.jar、batik-dom.jar、batik-awt-util.jar。
如果需要在基于mozilla的浏览器下面使用image maps的功能的话,必须拷贝/etc/overlib.js到web根目录下面。
另外,拷贝/etc/cewolf.tld拷贝到工程的web-inf里面。
步骤4:在web-inf的web.xml文件下面添加如下代码:
<servlet> <servlet-name>CewolfServlet</servlet-name> <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class> <!-- sets storage implementation --> <init-param> <param-name>storage</param-name> <param-value>de.laures.cewolf.storage.TransientSessionStorage</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CewolfServlet</servlet-name> <url-pattern>/cewolf/*</url-pattern> </servlet-mapping>
开发步骤
添加Dataset
步骤1:新建一文件夹,文件夹名为gantt。在gantt下面添加一Common ViewModel,文件名为GanttTreeGrid。
步骤2:添加一AutoSqlDataset,选择Project表,选择所有字段。AutoSqlDataset属性设置如下:
属性 | 值 |
---|---|
id | datasetProject |
originTable | PROJECT |
步骤3:为datasetProject添加一BaseMatchRule,属性设置如下:
属性 | 值 |
---|---|
level | 1 |
operator | = |
originField | PARENT_ID |
table | PROJECT |
value | :PARENT_ID |
escapeEnabled | true |
步骤4:为datasetProject添加一Parameter,属性设置如下:
属性 | 值 |
---|---|
name | PARENT_ID |
value | $null |
添加TreeGrid
步骤1:添加一TreeGrid,TreeGrid属性设置如下:
属性 | 值 |
---|---|
id | treegridProject |
dataset | datasetProject |
recursiveKeyFields | ID |
width | 100% |
height | 100% |
showHScrollBar | false |
treeColumn | TASK_NAME |
recursiveKeyParameters | PARENT_ID |
expandLevel | 1 |
fixedColumn | 1 |
步骤2:选中treegridProject,点击字段生成按钮。删除一些不用的字段,最终剩余字段如下:
步骤3:选中treegridProject的PROGRESS字段,为treegridProject的onCreateCellRenderer事件添加如下代码:
var bar = DoradoFactory.create("ProgressBar"); bar.style.width = "100%"; bar.style.height = "18"; bar.setTextPattern("\${position}%"); bar.setValue = function(value) { this.setPosition(parseInt(value)); }; return bar;
添加DatasetProducer
步骤1:添加一Simple Class,类名为GanttDataProducer,代码如下:
import java.util.Date; import java.util.List; import java.util.Map; import org.jfree.data.category.CategoryDataset; import org.jfree.data.gantt.Task; import org.jfree.data.gantt.TaskSeries; import org.jfree.data.gantt.TaskSeriesCollection; import org.jfree.data.time.SimpleTimePeriod; import com.bstek.dorado.data.db.DBStatement; import com.bstek.dorado.utils.variant.VariantSet; import de.laures.cewolf.DatasetProduceException; import de.laures.cewolf.DatasetProducer; import de.laures.cewolf.links.CategoryItemLinkGenerator; import de.laures.cewolf.tooltips.CategoryToolTipGenerator; public class GanttDataProducer implements DatasetProducer, CategoryItemLinkGenerator, CategoryToolTipGenerator { public String getProducerId() { // TODO Auto-generated method stub return null; } public boolean hasExpired(Map params, Date since) { // TODO Auto-generated method stub return false; } public Object produceDataset(Map params) throws DatasetProduceException { TaskSeriesCollection tc = new TaskSeriesCollection(); DBStatement stmt = new DBStatement(); stmt.setDataSource("doradosample"); String sql = "select * from project where parent_id is null"; stmt.setSql(sql); try { List ls = stmt.queryForList(); for (int i = 0; i < ls.size(); i++) { VariantSet vs = (VariantSet) ls.get(i); String task_name = vs.getString("task_name"); String id = vs.getString("id"); sql = "select * from project where parent_id=" + id + ""; stmt.setSql(sql); List list = stmt.queryForList(); TaskSeries ts = new TaskSeries(task_name); for (int j = 0; j < list.size(); j++) { VariantSet variantSet = (VariantSet) list.get(j); String sub_name = variantSet.getString("task_name"); id = variantSet.getString("id"); Date start_time = variantSet.getDate("start_time"); Date end_time = variantSet.getDate("end_time"); double progress = variantSet.getDouble("progress"); Task task = new Task(sub_name, new SimpleTimePeriod( start_time, end_time)); task.setPercentComplete(progress / 100); task.setDescription(sub_name + "-" + id); ts.add(task); } tc.add(ts); } } catch (Exception e) { e.printStackTrace(); throw new IllegalArgumentException("数据处理异常."); } finally { stmt.close(); } return tc; } public String generateLink(Object dataset, int series, Object category) { TaskSeriesCollection c = (TaskSeriesCollection) dataset; TaskSeries taskSeries = (TaskSeries) c.getRowKeys().get(series); List list = taskSeries.getTasks(); Task task = null; for (int i = 0; i < list.size(); i++) { task = (Task) list.get(i); if (task.getDescription().equals(category.toString())) { break; } } String name = task.getDescription(); String id = name.substring(name.indexOf("-") + 1, name.length()); StringBuffer sb = new StringBuffer(); sb.append("javascript:"); sb.append("var d=datasetProject;"); sb.append("var record = d.getFirstRecord();"); sb.append("while (record) {" + "var id=record.getValue('id');" + "if(id==" + id + "){" + "d.setCurrent(record);" + "break;" + "}" + "record = record.getNextRecord();" + "}"); return sb.toString(); } public String generateToolTip(CategoryDataset data, int series, int item) { TaskSeriesCollection c = (TaskSeriesCollection) data; TaskSeries taskSeries = (TaskSeries) c.getRowKeys().get(series); List list = taskSeries.getTasks(); return list.toString(); } }
步骤2:添加一Simple Class,类名为GanttPostProcess,代码如下:
import java.text.SimpleDateFormat; import java.util.Map; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickUnit; import org.jfree.chart.plot.CategoryPlot; import de.laures.cewolf.ChartPostProcessor; public class GanttPostProcess implements ChartPostProcessor { public void processChart(Object chart, Map params) { JFreeChart myChart = (JFreeChart) chart; CategoryPlot plot = myChart.getCategoryPlot(); DateAxis axis = (DateAxis) plot.getRangeAxis(); axis.setDateFormatOverride(new SimpleDateFormat("MM/dd")); axis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, 5, new SimpleDateFormat("dd"))); axis.setLowerMargin(0.02); CategoryAxis categoryAxis = plot.getDomainAxis(); categoryAxis.setLowerMargin(0.01); categoryAxis.setUpperMargin(0.01); categoryAxis.setCategoryLabelPositionOffset(0); categoryAxis.setCategoryMargin(0); categoryAxis.setFixedDimension(0); categoryAxis.setLabelAngle(0); } }
创建Jsp页面
为GanttTreeGrid生成Jsp页面后进行编辑,最后结果如下:
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib uri="http://www.bstek.com/dorado" prefix="d" %> <%@ taglib uri='/WEB-INF/cewolf.tld' prefix='cewolf' %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style> #idDIV{width:100%;height:100%;padding:2px;font-family:verdana,tahoma;font-size:12px ;line-height:17px;overflow:auto;} #idCodeDiv{width:100%;padding:4px;font-family:verdana,tahoma;margin:12px 0px 0px 0px;background-color:#EEEEEE;font-weight:bold;} </style> </head> <body style="margin: 0; overflow: hidden"> <d:View config="gantt.GanttTreeGrid"> <d:SplitPanel id="testsplitpanel" orientation="vertical" position="200" width="100%" height="100%" showButtons="true"> <d:TreeGrid id="treegridProject" /> <d:Splitter /> <div id="idDIV"> <jsp:useBean id="ganttPostProcess" class="gantt.GanttPostProcess"></jsp:useBean> <jsp:useBean id="toolTipClass" class="gantt.GanttDataProducer"></jsp:useBean> <cewolf:chart id="gantt" type="gantt"> <cewolf:chartpostprocessor id="ganttPostProcess" /> <cewolf:data> <cewolf:producer id="toolTipClass" /> </cewolf:data> </cewolf:chart> <cewolf:img chartid="gantt" renderer="/cewolf" width="1200" height="600"> <cewolf:map linkgeneratorid="toolTipClass" /> </cewolf:img> </div> </d:SplitPanel> </d:View> </body> </html>
查看运行效果
启动服务器后,运行效果如下:
点击甘特图上的节点,可以看到在DataTable中跳转到了相应的记录。
知识点
本节知识点主要在于JFreeChart与Cewolf的相关知识。关于JFreeChart,可以查看如下链接:
关于Cewolf,可以查看如下链接: