Symbolaxis上的JFreechart多线标签或其他对齐图表的方式

时间:2012-11-01 09:19:54

标签: label jfreechart axis multiline

我有很多图表,每个图表都在不同的JInternalFrame中:

enter image description here

但水平轴应与同一点(可能是红线)对齐。问题是,标签的空间是由jFreechart自动设置的。

所以我试图找到多线勾选标签的解决方案。我发现了这个:

  int optionsCount = state.getStatusOptions().toArray().length;
  String[] grade = new String[optionsCount + 1];
  grade[0] = "";
  for (int x = 1; x < optionsCount + 1; x++) {

         //grade[x] ="blaa"+x;//state.getStatusOptions().get(x - 1);
         //grade[x]="1.line\n2.line\n3.line";
           grade[x] = newLineString(state.getStatusOptions().get(x - 1), 5);
  }
  // grade[1]="1.line\n2.line";



  SymbolAxis rangeAxis;

  rangeAxis = new SymbolAxis("", grade){

                        @Override
                        protected Rectangle2D getLabelEnclosure(Graphics2D g2, RectangleEdge edge) {
                             Rectangle2D l = super.getLabelEnclosure(g2, edge);
                            l.setRect(l.getX(),l.getY(),l.getWidth()*0.5,l.getHeight());
                            return l;
                        }



             @Override
             protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge) {
                 AxisState state = new AxisState(cursor);

                 if (isAxisLineVisible()) {
                     drawAxisLine(g2, cursor, dataArea, edge);
                 }

                 double ol = getTickMarkOutsideLength();
                 double il = getTickMarkInsideLength();

                 List ticks = refreshTicks(g2, state, dataArea, edge);
                 state.setTicks(ticks);
                 g2.setFont(getTickLabelFont());
                 Iterator iterator = ticks.iterator();

                 // remember the max number of lines used in any label
                 int maxLinesUsed = 0;

                 while (iterator.hasNext()) {
                     ValueTick tick = (ValueTick) iterator.next();
                     if (isTickLabelsVisible()) {
                         g2.setPaint(getTickLabelPaint());
                         float[] anchorPoint = calculateAnchorPoint(tick, cursor, dataArea, edge);


                         g2.draw(plotArea);
                         g2.setPaint(Color.green);
                         g2.draw(dataArea);
                         g2.setPaint(getTickLabelPaint());
                         // split by "\n" and draw text in a new line for each result
                         String tickText = tick.getText();
                         int line = 1;
                         for (String tickTextLine : tickText.split("\n")) {
                             float x = anchorPoint[0];
                             // one row down...
                             float y = anchorPoint[1] + line * g2.getFont().getSize();
                             TextUtilities.drawRotatedString(tickTextLine, g2, x, y, tick.getTextAnchor(), tick.getAngle(), tick
                                     .getRotationAnchor());
                             line++;
                         }
                         // if we used more lines than any time before remember it
                         if (line > maxLinesUsed) {
                             maxLinesUsed = line;
                         }
                     }

                     if (isTickMarksVisible() && tick.getTickType().equals(TickType.MAJOR)) {
                         float xx = (float) valueToJava2D(tick.getValue(), dataArea, edge);
                         Line2D mark = null;
                         g2.setStroke(getTickMarkStroke());
                         g2.setPaint(getTickMarkPaint());
                         if (edge == RectangleEdge.LEFT) {
                             mark = new Line2D.Double(cursor - ol, xx, cursor + il, xx);
                         } else if (edge == RectangleEdge.RIGHT) {
                             mark = new Line2D.Double(cursor + ol, xx, cursor - il, xx);
                         } else if (edge == RectangleEdge.TOP) {
                             mark = new Line2D.Double(xx, cursor - ol, xx, cursor + il);
                         } else if (edge == RectangleEdge.BOTTOM) {
                             mark = new Line2D.Double(xx, cursor + ol, xx, cursor - il);
                         }
                         g2.draw(mark);
                     }
                 }

                 // need to work out the space used by the tick labels...
                 // so we can update the cursor...
                 // patched using maxLinesUsed => we need more space because of multiple lines
                 double used = 0.0;
                 if (isTickLabelsVisible()) {
                     if (edge == RectangleEdge.LEFT) {
                         used += findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels()) * maxLinesUsed;
                         state.cursorLeft(used);
                     } else if (edge == RectangleEdge.RIGHT) {
                         used = findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels()) * maxLinesUsed;
                         state.cursorRight(used);
                     } else if (edge == RectangleEdge.TOP) {
                         used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels()) * maxLinesUsed;
                         state.cursorUp(used);
                     } else if (edge == RectangleEdge.BOTTOM) {
                         used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels()) * maxLinesUsed;
                         state.cursorDown(used);
                     }
                 }

                 return state;


             }

         };

如上图所示,新的线功能有效,但标签的间距不起作用。我试图覆盖getLabelEnclosure方法,但它的给定字符串只是“”。

有没有人知道我的问题的解决方案。多线或其他方式来对齐图表?

谢谢!

1 个答案:

答案 0 :(得分:0)

覆盖reserveSpace函数,并在计算高度的位置用您需要的行数修改它:

Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
if (RectangleEdge.isTopOrBottom(edge)) {
    double labelHeight = labelEnclosure.getHeight();
    space.add(labelHeight + **YOUR_NUMBER_OF_ROWS** * tickLabelHeight, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
    double labelWidth = labelEnclosure.getWidth();
    space.add(labelWidth + tickLabelWidth, edge);
}

return space;