我正在尝试使用甘特图生成任务调度程序图表,但遇到了一些问题。 X 轴如何显示为数字而不是日期。 有没有办法编写一个函数 TaskWhatIWant(String , int ,int) 而不是 Task(String ,data,data) 来生成像甘特图这样的任务调度程序
或者有没有更好的方法来生成这样的任务调度图表 任何帮助将不胜感激。
package plugtest;
import java.awt.Color;
import java.awt.Dimension;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
public class GanttDemo extends ApplicationFrame
{
public GanttDemo(String s)
{
super(s);
JPanel jpanel = createDemoPanel();
jpanel.setPreferredSize(new Dimension(500, 270));
setContentPane(jpanel);
}
private static JFreeChart createChart(IntervalCategoryDataset intervalcategorydataset)
{
JFreeChart jfreechart = ChartFactory.createGanttChart("Gantt Chart Demo", "Task", "Date", intervalcategorydataset, true, true, false);
CategoryPlot categoryplot = (CategoryPlot)jfreechart.getPlot();
categoryplot.setRangePannable(true);
categoryplot.getDomainAxis().setMaximumCategoryLabelWidthRatio(10F);
CategoryItemRenderer categoryitemrenderer = categoryplot.getRenderer();
categoryitemrenderer.setSeriesPaint(0, Color.blue);
return jfreechart;
}
private static IntervalCategoryDataset createDataset()
{
TaskSeries taskseries = new TaskSeries("Scheduled");
/* which i want it to be
* **Task' task'=new Task'(String taskName, int start,int end);**
*/
Task task = new Task("task1", date(1, 3, 2001), date(5, 3, 2001));
task.setPercentComplete(1.0D);
taskseries.add(task);
Task task1 = new Task("task2", date(9, 3, 2001), date(11, 5, 2001));
taskseries.add(task1);
Task task2 = new Task("task3", date(10, 3, 2001), date(5, 4, 2001));
taskseries.add(task2);
TaskSeriesCollection taskseriescollection = new TaskSeriesCollection();
taskseriescollection.add(taskseries);
return taskseriescollection;
}
private static Date date(int i, int j, int k)
{
Calendar calendar = Calendar.getInstance();
calendar.set(k, j, i);
Date date1 = calendar.getTime();
return date1;
}
public static JPanel createDemoPanel()
{
JFreeChart jfreechart = createChart(createDataset());
ChartPanel chartpanel = new ChartPanel(jfreechart);
chartpanel.setMouseWheelEnabled(true);
return chartpanel;
}
public static void main(String args[])
{
GanttDemo ganttdemo = new GanttDemo("gantt demo");
ganttdemo.pack();
RefineryUtilities.centerFrameOnScreen(ganttdemo);
ganttdemo.setVisible(true);
}
}
感谢@Baz 的建议。
这是解决方案和演示
修改函数createGanttChart:
public static JFreeChart createGanttChart(String title,
String categoryAxisLabel,
String dateAxisLabel,
IntervalCategoryDataset dataset,
boolean legend,
boolean tooltips,
boolean urls) {
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
ValueAxis dateAxis = new NumberAxis(dateAxisLabel);//important,change axis from data to value
CategoryItemRenderer renderer = new GanttRenderer();
if (tooltips) {
renderer.setBaseToolTipGenerator(
(CategoryToolTipGenerator) new IntervalCategoryToolTipGenerator(
"{1}Schedule Time: {3}ms - {4}ms", NumberFormat .getNumberInstance()));
}
if (urls) {
renderer.setBaseItemURLGenerator(
new StandardCategoryURLGenerator());
}
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, dateAxis,
renderer);
plot.setOrientation(PlotOrientation.HORIZONTAL);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
plot, legend);
return chart;
}
}
修改类任务
package plugtest;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import org.jfree.data.time.SimpleTimePeriod;
import org.jfree.data.time.TimePeriod;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public class Task implements Cloneable, PublicCloneable, Serializable {
/** For serialization. */
private static final long serialVersionUID = 1094303785346988894L;
private String description;
private double start; //start Time
private double end; //end Time
public double getStart() {
return start;
}
public void setStart(double start) {
this.start = start;
}
public double getEnd() {
return end;
}
public void setEnd(double end) {
this.end = end;
}
/** The percent complete (<code>null</code> is permitted). */
private Double percentComplete;
/** Storage for the sub-tasks (if any). */
private List subtasks;
public Task(String description, double start , double end) {
if (description == null) {
throw new IllegalArgumentException("Null 'description' argument.");
}
this.description = description;
this.start=start;
this.end=end;
this.percentComplete = null;
this.subtasks = new java.util.ArrayList();
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
if (description == null) {
throw new IllegalArgumentException("Null 'description' argument.");
}
this.description = description;
}
public Double getPercentComplete() {
return this.percentComplete;
}
public void setPercentComplete(Double percent) {
this.percentComplete = percent;
}
public void setPercentComplete(double percent) {
setPercentComplete(new Double(percent));
}
public void addSubtask(Task subtask) {
if (subtask == null) {
throw new IllegalArgumentException("Null 'subtask' argument.");
}
this.subtasks.add(subtask);
}
public void removeSubtask(Task subtask) {
this.subtasks.remove(subtask);
}
public int getSubtaskCount() {
return this.subtasks.size();
}
public Task getSubtask(int index) {
return (Task) this.subtasks.get(index);
}
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof Task)) {
return false;
}
Task that = (Task) object;
if (!ObjectUtilities.equal(this.description, that.description)) {
return false;
}
if (!ObjectUtilities.equal(this.start, that.start)) {
return false;
}
if (!ObjectUtilities.equal(this.end, that.end)) {
return false;
}
if (!ObjectUtilities.equal(this.percentComplete,
that.percentComplete)) {
return false;
}
if (!ObjectUtilities.equal(this.subtasks, that.subtasks)) {
return false;
}
return true;
}
public Object clone() throws CloneNotSupportedException {
Task clone = (Task) super.clone();
return clone;
}
}
修改TaskSeriesCollection类中的函数getStartValue(Comparable,Comparable)、getEndValue(Comparable,Comparable)、getStartValue(Comparable,Comparable,int)、getEndValue(Comparable,Comparable,int)。
public Number getStartValue(Comparable rowKey, Comparable columnKey) {
Number result = null;
int row = getRowIndex(rowKey);
TaskSeries series = (TaskSeries) this.data.get(row);
Task task = series.get(columnKey.toString());
if (task != null) {
result = task.getStart(); //return the start time of task
}
return result;
}
public Number getEndValue(Comparable rowKey, Comparable columnKey) {
Number result = null;
int row = getRowIndex(rowKey);
TaskSeries series = (TaskSeries) this.data.get(row);
Task task = series.get(columnKey.toString());
if (task != null) {
result = task.getEnd(); //return the end time of task
}
return result;
}
public Number getStartValue(Comparable rowKey, Comparable columnKey,
int subinterval) {
Number result = null;
int row = getRowIndex(rowKey);
TaskSeries series = (TaskSeries) this.data.get(row);
Task task = series.get(columnKey.toString());
if (task != null) {
Task sub = task.getSubtask(subinterval);
if (sub != null) {
result = sub.getStart();
}
}
return result;
}
public Number getEndValue(Comparable rowKey, Comparable columnKey,
int subinterval) {
Number result = null;
int row = getRowIndex(rowKey);
TaskSeries series = (TaskSeries) this.data.get(row);
Task task = series.get(columnKey.toString());
if (task != null) {
Task sub = task.getSubtask(subinterval);
if (sub != null) {
result = sub.getEnd();
}
}
return result;
}
演示是:
private static IntervalCategoryDataset createDataset()
{
TaskSeries taskseries = new TaskSeries("Scheduled");
Task task = new Task("task1", 0, 100);// now task can be added from "double" to "double".
task.setPercentComplete(1.0D);
taskseries.add(task);
Task task1 = new Task("task2", 100, 300);
taskseries.add(task1);
Task task2 = new Task("task3",200, 270);
taskseries.add(task2);
TaskSeriesCollection taskseriescollection = new TaskSeriesCollection();
taskseriescollection.add(taskseries);
return taskseriescollection;
}
private static JFreeChart createChart(IntervalCategoryDataset intervalcategorydataset)
{
JFreeChart jfreechart = createGanttChart("Schedule Chart Demo", "Task", "Date", intervalcategorydataset, true, true, false);
CategoryPlot categoryplot = (CategoryPlot)jfreechart.getPlot();
categoryplot.setRangePannable(true);
categoryplot.getDomainAxis().setMaximumCategoryLabelWidthRatio(10F);
CategoryItemRenderer categoryitemrenderer = categoryplot.getRenderer();
categoryitemrenderer.setSeriesPaint(0, Color.red);
GanttRenderer ganttrenderer = (GanttRenderer)categoryplot.getRenderer();
ganttrenderer.setShadowVisible(false);
ganttrenderer.setBarPainter(new StandardBarPainter() );
ganttrenderer.setDrawBarOutline(false);
ganttrenderer.setAutoPopulateSeriesFillPaint(true);
return jfreechart;
}
public void createPartControl( Composite parent) {
JFreeChart chart = createChart(createDataset());
ChartComposite frame = new ChartComposite(parent, SWT.FILL, chart,
true);
frame.pack();
}
ChartFactory.createGanttChart(...)
的文档非常具体:
使用提供的属性以及需要的默认值创建甘特图。此方法返回的图表对象使用 CategoryPlot 实例作为绘图,使用 CategoryAxis 作为域轴,a DateAxis 作为范围轴, 以及 GanttRenderer 作为渲染器。
要解决您的问题,您必须“复制”此方法的功能,但根据您的要求进行修改(即使用不同的轴)。
您可以在第 914 行找到 createLineChart 的实现(例如)。
非常感谢您分享您的解决方案!
我为整数数据类型创建了类似的修改,它更短更清晰,因为您不需要修改库中的任何代码。
它的工作原理如下:我创建了一个新类
TaskNumeric
,它扩展了现有的 Task
,并对 createGanttChart
方法添加了修改,与您的类似。只需将这两个类添加到您的项目中,每当您调用 Task
时,请使用 TaskNumeric
代替。 ChartFactory
和自定义 GanttChartFactory
的计数相同。
这是
Task
扩展:
public class TaskNumeric extends Task {
public TaskNumeric(String description, long start, long end) {
super(description, new Date(start), new Date(end));
}
public static TaskNumeric duration(String description, long start, long duration) {
return new TaskNumeric(description, start, start + duration);
}
}
还有
ChartFactory
-mod:
public class GanttChartFactory extends ChartFactory {
protected static ChartTheme currentTheme = new StandardChartTheme("JFree");
public static JFreeChart createGanttChart(String title,
String categoryAxisLabel, String valueAxisLabel,
IntervalCategoryDataset dataset, boolean legend, boolean tooltips,
boolean urls) {
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
CategoryItemRenderer renderer = new GanttRenderer();
if (tooltips) {
renderer.setBaseToolTipGenerator(
new IntervalCategoryToolTipGenerator(
"{1}: {3} - {4}", NumberFormat.getNumberInstance()));
}
if (urls) {
renderer.setBaseItemURLGenerator(
new StandardCategoryURLGenerator());
}
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
renderer);
plot.setOrientation(PlotOrientation.HORIZONTAL);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
plot, legend);
currentTheme.apply(chart);
return chart;
}
}
演示:
public class GanttDemo extends ApplicationFrame {
public GanttDemo(String s) {
super(s);
JPanel jpanel = createDemoPanel();
jpanel.setPreferredSize(new Dimension(500, 270));
setContentPane(jpanel);
}
private static JFreeChart createChart(IntervalCategoryDataset dataset) {
final JFreeChart chart = GanttChartFactory.createGanttChart(
"Gantt Chart Demo", "Task", "Value", dataset, true, true, false);
return chart;
}
private static IntervalCategoryDataset createDataset() {
TaskSeries taskseries = new TaskSeries("Scheduled");
Task task = new TaskNumeric("task1", 0, 5);
task.setPercentComplete(1.0D);
taskseries.add(task);
Task task1 = new TaskNumeric("task2", 2,9);
taskseries.add(task1);
Task task2 = TaskNumeric.duration("task3", 6, 5);
taskseries.add(task2);
TaskSeriesCollection taskseriescollection = new TaskSeriesCollection();
taskseriescollection.add(taskseries);
return taskseriescollection;
}
public static JPanel createDemoPanel() {
JFreeChart jfreechart = createChart(createDataset());
ChartPanel chartpanel = new ChartPanel(jfreechart);
chartpanel.setMouseWheelEnabled(true);
return chartpanel;
}
public static void main(String args[]) {
GanttDemo ganttdemo = new GanttDemo("gantt demo");
ganttdemo.pack();
RefineryUtilities.centerFrameOnScreen(ganttdemo);
ganttdemo.setVisible(true);
}
}