Код для изменения цвета подзадач в диаграмме Ганта - PullRequest
1 голос
/ 20 января 2012

Мне нужно изменить цвет подзадач на диаграмме Ганта .Мой пример основан на 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 ]

4 голосов
/ 21 января 2012

Как предложено здесь , пользовательский рендер может запросить модель, чтобы обусловить результат, возвращаемый 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<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]));
        }
    }
}
0 голосов
/ 06 августа 2013

Или вы можете расширить задачу и использовать локальную переменную потока, чтобы отслеживать последний элемент, к которому обращается средство визуализации:

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.

...