Dorado 5 : 12.4.JfreeChart图表-甘特图 (T22)

概述

本示例用来展示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,可以查看如下链接: