Text labels inside jfree Gantt chart bars

有些话、适合烂在心里 提交于 2019-12-17 20:28:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!