就像在以下示例中所做的那样,我希望图表域上的刻度线标签旋转45度,如下图所示: http://left.subtree.org/2007/08/14/rotate-labels-jfreechart/
不同之处在于,我想在带有数字轴的散点图上执行此操作。我在NumberAxis类中找不到与setCategoryLabelPositions()的等价物。
答案 0 :(得分:10)
给出的第一个答案是数字域轴。如果您有类别轴,则需要以下代码:
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
答案 1 :(得分:8)
方法setVerticalTickLabels()
可能是另一种选择。如果没有,我认为没有其他选择,只能覆盖refreshTicksHorizontal()
。另请参阅此example。
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);
}
}
答案 2 :(得分:4)
你必须看看超级班:Axis.setLabelAngle(rad)。
这是一个example。
编辑:上面没用,对不起。
我查看了org.jfreechart.chart.axis.NumberAxis.refreshTicksHorizontal的代码。实际上有一个角度设置为0.0(所有new NumberTick(...,0.0)
构造函数中的最后一个参数)。您可以创建NumberAxis的子类,该子类使用不同的角度(在构造函数中指定)覆盖方法refreshTicksHorizontal。
在绘制图形时,看起来总是调用refreshTicks,因此您不必担心它不会被调用。
/**
* 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;
}