问题
I have a simple Gantt chart here, that consists of a number of Tasks just like that:
TaskSeries s1 = new TaskSeries("Planned Tasks");
Task newTask = new Task("Task" +
String.valueOf(taskIndex),
new
SimpleTimePeriod(currentTime,
currentTime +
(int) distributionTime)
);
s1.add(newTask)
final TaskSeriesCollection collection = new TaskSeriesCollection();
collection.add(s1);
JFreeChart chart = ChartFactory.createGanttChart(
"Distribution ",
"Task",
"Time",
collection,
true,
true,
false
);
Is there a way to write something INSIDE each bar, representing a task? For example, if the task is made up of a two subtasks, is it possible to mark them with labels, so their names would be seen on a plot? Thanks in advance!
回答1:
To add a a lable inside each item set the setBaseItemLabelGenerator
in this case I'm using a IntervalCategoryItemLabelGenerator
but you can implement you own by extending CategoryItemLabelGenerator
.
Use this code:
CategoryPlot plot = (CategoryPlot) chart.getPlot();
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setBaseItemLabelGenerator( new IntervalCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
renderer.setBaseItemLabelPaint(Color.BLACK);
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
ItemLabelAnchor.INSIDE6, TextAnchor.BOTTOM_CENTER));
You shold then get this: b
To customise the lables implement CategoryItemLabelGenerator
renderer.setBaseItemLabelGenerator( new CategoryItemLabelGenerator(){
@Override
public String generateRowLabel(CategoryDataset dataset, int row) {
return "Your Row Text " + row;
}
@Override
public String generateColumnLabel(CategoryDataset dataset, int column) {
return "Your Column Text " + column;
}
@Override
public String generateLabel(CategoryDataset dataset, int row, int column) {
return "Your Label Text " + row + "," + column;
}
});
In this example generateLabel
controls the lable in the bar, CategoryDataset
, row
and column
can be used to determine which bar you are labelling
回答2:
Eventually i found the solution for this issue. Post it here maybe it will help some one else.
The problem is that in the exisiting drawTasks function in GanttRenderer don't have code for displaying labels. So we have to extend the GanttRenderer class with our new drawTasks function:
public class MyGanttRenderer extends GanttRenderer {
private transient Paint completePaint;
private transient Paint incompletePaint;
private double startPercent;
private double endPercent;
public MyGanttRenderer() {
super();
setIncludeBaseInRange(false);
this.completePaint = Color.green;
this.incompletePaint = Color.red;
this.startPercent = 0.35;
this.endPercent = 0.65;
}
protected void drawTasks(Graphics2D g2,
CategoryItemRendererState state,
Rectangle2D dataArea,
CategoryPlot plot,
CategoryAxis domainAxis,
ValueAxis rangeAxis,
GanttCategoryDataset dataset,
int row,
int column) {
int count = dataset.getSubIntervalCount(row, column);
if (count == 0) {
drawTask(g2, state, dataArea, plot, domainAxis, rangeAxis,
dataset, row, column);
}
for (int subinterval = 0; subinterval < count; subinterval++) {
RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
// value 0
Number value0 = dataset.getStartValue(row, column, subinterval);
if (value0 == null) {
return;
}
double translatedValue0 = rangeAxis.valueToJava2D(
value0.doubleValue(), dataArea, rangeAxisLocation);
// value 1
Number value1 = dataset.getEndValue(row, column, subinterval);
if (value1 == null) {
return;
}
double translatedValue1 = rangeAxis.valueToJava2D(
value1.doubleValue(), dataArea, rangeAxisLocation);
if (translatedValue1 < translatedValue0) {
double temp = translatedValue1;
translatedValue1 = translatedValue0;
translatedValue0 = temp;
}
double rectStart = calculateBarW0(plot, plot.getOrientation(),
dataArea, domainAxis, state, row, column);
double rectLength = Math.abs(translatedValue1 - translatedValue0);
double rectBreadth = state.getBarWidth();
// DRAW THE BARS...
Rectangle2D bar = null;
if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
bar = new Rectangle2D.Double(translatedValue0, rectStart,
rectLength, rectBreadth);
}
else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
bar = new Rectangle2D.Double(rectStart, translatedValue0,
rectBreadth, rectLength);
}
Rectangle2D completeBar = null;
Rectangle2D incompleteBar = null;
Number percent = dataset.getPercentComplete(row, column,
subinterval);
double start = getStartPercent();
double end = getEndPercent();
if (percent != null) {
double p = percent.doubleValue();
if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
completeBar = new Rectangle2D.Double(translatedValue0,
rectStart + start * rectBreadth, rectLength * p,
rectBreadth * (end - start));
incompleteBar = new Rectangle2D.Double(translatedValue0
+ rectLength * p, rectStart + start * rectBreadth,
rectLength * (1 - p), rectBreadth * (end - start));
}
else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
completeBar = new Rectangle2D.Double(rectStart + start
* rectBreadth, translatedValue0 + rectLength
* (1 - p), rectBreadth * (end - start),
rectLength * p);
incompleteBar = new Rectangle2D.Double(rectStart + start
* rectBreadth, translatedValue0, rectBreadth
* (end - start), rectLength * (1 - p));
}
}
Paint seriesPaint = getItemPaint(row, column);
g2.setPaint(seriesPaint);
g2.fill(bar);
if (completeBar != null) {
g2.setPaint(getCompletePaint());
g2.fill(completeBar);
}
if (incompleteBar != null) {
g2.setPaint(getIncompletePaint());
g2.fill(incompleteBar);
}
if (isDrawBarOutline()
&& state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
g2.setStroke(getItemStroke(row, column));
g2.setPaint(getItemOutlinePaint(row, column));
g2.draw(bar);
}
CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
if (generator != null && isItemLabelVisible(row, column)) {
drawItemLabel(g2, dataset, row, column, plot, generator, bar, false);
}
// collect entity and tool tip information...
if (state.getInfo() != null) {
EntityCollection entities = state.getEntityCollection();
if (entities != null) {
String tip = null;
if (getToolTipGenerator(row, column) != null) {
tip = getToolTipGenerator(row, column).generateToolTip(
dataset, row, column);
}
String url = null;
if (getItemURLGenerator(row, column) != null) {
url = getItemURLGenerator(row, column).generateURL(
dataset, row, column);
}
CategoryItemEntity entity = new CategoryItemEntity(
bar, tip, url, dataset, dataset.getRowKey(row),
dataset.getColumnKey(column));
entities.add(entity);
}
}
}
}
}
And to display labels on each bar (including subtask) just do the following:
CategoryPlot plot = (CategoryPlot) chart.getPlot();
MyGanttRenderer renderer = new MyGanttRenderer();
plot.setRenderer(renderer);
renderer.setBaseItemLabelGenerator(new CategoryItemLabelGenerator() {
public String generateLabel(CategoryDataset dataSet, int series, int categories) {
/* your code to get the label */
return label;
}
public String generateColumnLabel(CategoryDataset dataset, int categories) {
return dataset.getColumnKey(categories).toString();
}
public String generateRowLabel(CategoryDataset dataset, int series) {
return dataset.getRowKey(series).toString();
}
});
renderer.setBaseItemLabelsVisible(true);
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE9, TextAnchor.CENTER_LEFT));
And this is it. Hope it will useful for some one.
来源:https://stackoverflow.com/questions/11307070/text-labels-inside-jfree-gantt-chart-bars