Код для изменения цвета подзадач в диаграмме Ганта
Мне нужно изменить цвет подзадач в диаграмме Ганта. Мой пример основан на 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);
}
}
}
2 ответа
Как предлагается здесь, пользовательский рендер может запросить модель, чтобы обусловить результат, возвращаемый getItemPaint()
, В этом примере подзадачи отображаются с использованием палитры с различной насыщенностью цвета по умолчанию для данной серии. Подход предполагает, что средство визуализации делает два прохода; некоторая осторожность должна быть уделена документированию зависимости.
/** @see https://stackru.com/questions/8938690 */
private static class MyRenderer extends GanttRenderer {
private static final int PASS = 2; // assumes two passes
private final List<Color> clut = new ArrayList<Color>();
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<Task> 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<Integer> lastSubTask = new ThreadLocal<Integer>();
...
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.