用于在甘特图中更改子任务颜色的代码

我需要在甘特图中更改子任务的颜色。 我的示例基于GanttDemo2具有以下数据集和渲染器。 在不同的论坛中,我发现了一些与此主题相关的讨论,但我没有找到一个清晰简单的工作示例。 特别是,我可以改变任务的颜色,但我不知道如何提取子任务。

 private IntervalCategoryDataset createSampleDataset() { final TaskSeries s1 = new TaskSeries("Scheduled"); final Task t1 = new Task( "Design", date(1, Calendar.APRIL, 2001), date(1, Calendar.MAY, 2001)); t1.addSubtask(new Task("Design 1", date(1, Calendar.APRIL, 2001), date(15, Calendar.APRIL, 2001))); t1.addSubtask(new Task("Design 2", date(16, Calendar.APRIL, 2001), date(25, Calendar.APRIL, 2001))); t1.addSubtask(new Task("Design 3", date(26, Calendar.APRIL, 2001), date(1, Calendar.MAY, 2001))); s1.add(t1); final Task t2 = new Task( "Proposal", date(1, Calendar.JUNE, 2001), date(1, Calendar.JULY, 2001)); t2.addSubtask(new Task("Proposal 1", date(1, Calendar.JUNE, 2001), date(15, Calendar.JUNE, 2001))); t2.addSubtask(new Task("Proposal 2", date(16, Calendar.JUNE, 2001), date(25, Calendar.JUNE, 2001))); t2.addSubtask(new Task("Proposal 3", date(26, Calendar.JUNE, 2001), date(1, Calendar.JULY, 2001))); s1.add(t2); final TaskSeriesCollection collection = new TaskSeriesCollection(); collection.add(s1); return collection; } class MyRenderer extends GanttRenderer { private static final Color subtask1Color = Color.blue; private static final Color subtask2Color = Color.cyan; private static final Color subtask3Color = Color.green; private static final long serialVersionUID = 1L; public MyRenderer() { super(); } @Override public Paint getItemPaint(int row, int col) { System.out.println(row + " " + col + " " + super.getItemPaint(row, col)); if (row == 0) { return subtask1Color; } else if (row == 1) { return subtask2Color; } else if (row == 2) { return subtask3Color; } else { return super.getItemPaint(row, col); } } } 

getItemPaint()建议的,自定义渲染器可以查询模型以调整getItemPaint()返回的结果。 在此示例中,使用给定系列的默认颜色的不同饱和度的调色板来渲染子任务。 该方法假设渲染器进行两次传递; 应该注意记录依赖性。

GanttSubtaskDemo

 /** @see https://stackoverflow.com/questions/8938690 */ private static class MyRenderer extends GanttRenderer { private static final int PASS = 2; // assumes two passes private final List clut = new ArrayList(); private final TaskSeriesCollection model; private int row; private int col; private int index; public MyRenderer(TaskSeriesCollection model) { this.model = model; } @Override public Paint getItemPaint(int row, int col) { if (clut.isEmpty() || this.row != row || this.col != col) { initClut(row, col); this.row = row; this.col = col; index = 0; } int clutIndex = index++ / PASS; return clut.get(clutIndex); } private void initClut(int row, int col) { clut.clear(); Color c = (Color) super.getItemPaint(row, col); float[] a = new float[3]; Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), a); TaskSeries series = (TaskSeries) model.getRowKeys().get(row); List tasks = series.getTasks(); // unchecked int taskCount = tasks.get(col).getSubtaskCount(); taskCount = Math.max(1, taskCount); for (int i = 0; i < taskCount; i++) { clut.add(Color.getHSBColor(a[0], a[1] / i, a[2])); } } } 

或者,您可以扩展任务并使用线程局部变量来跟踪渲染器访问的最后一个项目:

 private ThreadLocal lastSubTask = new ThreadLocal(); ... private class MyTask extends Task { ... public Task getSubtask(int index) { lastSubTask.set(index); return super.getSubtask(index); } } ... private class MyRenderer extends GanttRenderer { ... public Paint getCompletePaint() { Integer index = lastSubTask.get(); return getColorForSubTask(index); } ... } 

这可能对jfreechart中的更改更具弹性。