如何在JFreeChart中的数轴的域上旋转刻度标记?

就像在下面的例子中所做的那样,我希望图表域上的刻度标记旋转45度,如下图所示: http : //left.subtree.org/2007/08/14/rotate -labels-jfreechart的/

不同的是,我想在一个数字轴的散点图上做这个。 我无法在NumberAxis类中find与setCategoryLabelPositions()等效的内容。

setVerticalTickLabels()方法可能是一种替代方法。 如果没有,我没有看到任何select,只能覆盖refreshTicksHorizontal() 。 另见这个例子 。

在这里输入图像描述

 import java.awt.Color; import java.awt.Dimension; import java.util.*; import org.jfree.chart.*; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.ApplicationFrame; import org.jfree.ui.RefineryUtilities; /** * @see https://stackoverflow.com/questions/7208657 * @see https://stackoverflow.com/questions/7071057 */ public class ScatterTickLabels extends ApplicationFrame { public ScatterTickLabels(String s) { super(s); final ChartPanel chartPanel = createDemoPanel(); chartPanel.setPreferredSize(new Dimension(640, 480)); this.add(chartPanel); } public static ChartPanel createDemoPanel() { JFreeChart jfreechart = ChartFactory.createScatterPlot( "Scatter Plot Demo", "X", "Y", samplexydataset(), PlotOrientation.VERTICAL, true, true, false); XYPlot xyPlot = (XYPlot) jfreechart.getPlot(); xyPlot.setDomainCrosshairVisible(true); xyPlot.setRangeCrosshairVisible(true); XYItemRenderer renderer = xyPlot.getRenderer(); renderer.setSeriesPaint(0, Color.blue); NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); domain.setVerticalTickLabels(true); return new ChartPanel(jfreechart); } private static XYDataset samplexydataset() { int cols = 20; int rows = 20; XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); XYSeries series = new XYSeries("Random"); Random rand = new Random(); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { double x = rand.nextGaussian(); double y = rand.nextGaussian(); series.add(x, y); } } xySeriesCollection.addSeries(series); return xySeriesCollection; } public static void main(String args[]) { ScatterTickLabels demo = new ScatterTickLabels("Scatter Plot Demo"); demo.pack(); RefineryUtilities.centerFrameOnScreen(demo); demo.setVisible(true); } } 

给出的第一个答案是数值域轴。 如果你有一个类别轴,你需要这个代码:

 CategoryAxis domainAxis = plot.getDomainAxis(); domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90); 

你必须看看超类: Axis.setLabelAngle(rad) 。

这里是一个例子 。

编辑 :上面没有用,对不起。

我查看了org.jfreechart.chart.axis.NumberAxis.refreshTicksHorizo​​ntal的代码。 实际上有一个angular度设置为0.0(所有new NumberTick(...,0.0)构造函数中的最后一个参数)。 你可以创build一个NumberAxis的子类来覆盖方法refreshTicksHorizo​​ntal,使用不同的angular度(在你的构造函数中指定)。

看起来refreshTicks在绘制graphics时总是被调用,所以你不必担心它没有被调用。

 /** * Calculates the positions of the tick labels for the axis, storing the * results in the tick label list (ready for drawing). * * @param g2 the graphics device. * @param dataArea the area in which the data should be drawn. * @param edge the location of the axis. * * @return A list of ticks. */ protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) { List result = new java.util.ArrayList(); Font tickLabelFont = getTickLabelFont(); g2.setFont(tickLabelFont); if (isAutoTickUnitSelection()) { selectAutoTickUnit(g2, dataArea, edge); } TickUnit tu = getTickUnit(); double size = tu.getSize(); int count = calculateVisibleTickCount(); double lowestTickValue = calculateLowestVisibleTickValue(); if (count <= ValueAxis.MAXIMUM_TICK_COUNT) { int minorTickSpaces = getMinorTickCount(); if (minorTickSpaces <= 0) { minorTickSpaces = tu.getMinorTickCount(); } for (int minorTick = 1; minorTick < minorTickSpaces; minorTick++) { double minorTickValue = lowestTickValue - size * minorTick / minorTickSpaces; if (getRange().contains(minorTickValue)){ result.add(new NumberTick(TickType.MINOR, minorTickValue, "", TextAnchor.TOP_CENTER, TextAnchor.CENTER, 0.0)); } } for (int i = 0; i < count; i++) { double currentTickValue = lowestTickValue + (i * size); String tickLabel; NumberFormat formatter = getNumberFormatOverride(); if (formatter != null) { tickLabel = formatter.format(currentTickValue); } else { tickLabel = getTickUnit().valueToString(currentTickValue); } TextAnchor anchor = null; TextAnchor rotationAnchor = null; double angle = 0.0; if (isVerticalTickLabels()) { anchor = TextAnchor.CENTER_RIGHT; rotationAnchor = TextAnchor.CENTER_RIGHT; if (edge == RectangleEdge.TOP) { angle = Math.PI / 2.0; } else { angle = -Math.PI / 2.0; } } else { if (edge == RectangleEdge.TOP) { anchor = TextAnchor.BOTTOM_CENTER; rotationAnchor = TextAnchor.BOTTOM_CENTER; } else { anchor = TextAnchor.TOP_CENTER; rotationAnchor = TextAnchor.TOP_CENTER; } } Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle); result.add(tick); double nextTickValue = lowestTickValue + ((i + 1)* size); for (int minorTick = 1; minorTick < minorTickSpaces; minorTick++) { double minorTickValue = currentTickValue + (nextTickValue - currentTickValue) * minorTick / minorTickSpaces; if (getRange().contains(minorTickValue)){ result.add(new NumberTick(TickType.MINOR, minorTickValue, "", TextAnchor.TOP_CENTER, TextAnchor.CENTER, 0.0)); } } } } return result; }