我已经厌倦了自己想出这个,并想知道这是一个已知的错误还是我对jfreechart库的误解。
我有两个小节,想要显示文字“你”和“Neighboorhood avg。”在每个小节的左上角。与它在第二张图像中的外观类似。
将标签位置放在水平条左上方的正确方法是什么?
以下是生成图片1的代码:
@RestController
public class JfreeCharCategoryAnnotationBug {
@RequestMapping(value = "bug", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity<StreamingResponseBody> getBarChartWithCategoryAnnotationBug(String title) {
DefaultCategoryDataset barDataSet = new DefaultCategoryDataset();
String youDataKey = "You";
String weDataKey = "Neightborhood Avg.";
Map<TextAttribute, Object> values2X = new HashMap<TextAttribute, Object>();
values2X.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
values2X.put(TextAttribute.SIZE, 20);
Font scaledFont = new Font("Arial Bold", Font.PLAIN, 20).deriveFont(values2X);
barDataSet.setValue(200, youDataKey, youDataKey);
barDataSet.setValue(2000, weDataKey, weDataKey);
JFreeChart barGraph = ChartFactory.createBarChart(null, "", "",
barDataSet, PlotOrientation.HORIZONTAL, true, false, false);
Color weSpendColor = new Color(40, 137, 0);
Color youSpendColor = new Color(48, 35, 174);
// plot manipulations
CategoryPlot plotModifier = barGraph.getCategoryPlot();
barGraph.setBorderVisible(false);
plotModifier.setOutlineVisible(false);
// remove space between axis and data area
plotModifier.setAxisOffset(new RectangleInsets(0.0, 0.0, 0.0, 0.0));
plotModifier.setInsets(new RectangleInsets(0, 0, 0, 0), true);
// Axis modifications
ValueAxis rangeAxis = (ValueAxis) plotModifier.getRangeAxis();
rangeAxis.setVisible(false);
rangeAxis.setAxisLineVisible(false);
CategoryAxis domainAxis = (CategoryAxis) plotModifier.getDomainAxis();
domainAxis.setVisible(false);
domainAxis.setAxisLineStroke(new BasicStroke(4));
domainAxis.setLabelFont(scaledFont);
// Actual data point manipulations
BarRenderer renderer = (BarRenderer) plotModifier.getRenderer();
renderer.setBarPainter(new StandardBarPainter());
renderer.setBaseItemLabelsVisible(true);
renderer.setDrawBarOutline(true);
renderer.setBaseItemLabelGenerator(new CategoryItemLabelGenerator() {
@Override
public String generateRowLabel(CategoryDataset dataset, int row) {
return dataset.getRowKey(row).toString();
}
@Override
public String generateLabel(CategoryDataset dataset, int row,
int column) {
Number value = dataset.getValue(row, column);
StringBuilder sb = new StringBuilder("$");
// return sb.append(format(value.longValue())).toString();
return sb.append(value.longValue()).toString();
}
@Override
public String generateColumnLabel(CategoryDataset dataset,
int column) {
return dataset.getColumnKey(column).toString();
}
});
renderer.setBaseItemLabelFont(scaledFont);
// Color time
renderer.setSeriesPaint(0, youSpendColor, true);
renderer.setSeriesPaint(1, weSpendColor, true);
renderer.setSeriesOutlinePaint(0, youSpendColor, true);
renderer.setSeriesOutlinePaint(1, weSpendColor, true);
domainAxis.setAxisLinePaint(Color.GREEN);
plotModifier.setBackgroundPaint(Color.WHITE);
// margins and offsets
renderer.setItemMargin(0);
// for item label i.e $1K
renderer.setItemLabelAnchorOffset(2);
plotModifier.getDomainAxis().setCategoryMargin(0.0);
// for space between the plot outline and the bar
plotModifier.getDomainAxis().setLowerMargin(0.30);
plotModifier.getDomainAxis().setUpperMargin(0.0);
plotModifier.getRangeAxis().setLowerMargin(0.0);
// brings back some of the item text
plotModifier.getRangeAxis().setUpperMargin(0.30);
// annotations
CategoryTextAnnotation we = new CategoryTextAnnotation(weDataKey,weDataKey, 0.0D);
CategoryTextAnnotation you = new CategoryTextAnnotation(youDataKey,youDataKey, 0.0D);
you.setFont(scaledFont);
we.setFont(scaledFont);
you.setPaint(new Color(135, 144, 153));
we.setPaint(new Color(135, 144, 153));
you.setCategoryAnchor(CategoryAnchor.START);
we.setCategoryAnchor(CategoryAnchor.START);
// possibly a jFreeChart bug Bottom_LEFT aligns first category's annotation to the position that TOP_LEFT should/does anchors the second category annotation
you.setTextAnchor(TextAnchor.TOP_LEFT);
we.setTextAnchor(TextAnchor.TOP_LEFT);
plotModifier.addAnnotation(you);
plotModifier.addAnnotation(we);
barGraph.removeLegend();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
// creating a chart with double the pixels for better rendering when client "auto layout" on mobile device
ChartUtilities.writeBufferedImageAsPNG(baos, barGraph.createBufferedImage(480,160, new ChartRenderingInfo()));
} catch (IOException e) {
//omitted
}
MultiValueMap<String, String> responseHeaders = new HttpHeaders();
responseHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE);
return new ResponseEntity<StreamingResponseBody>(
new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
baos.writeTo(outputStream);
}
}, responseHeaders, HttpStatus.OK);
}
}
以下是生成图像2的代码:
@RestController
public class JfreeCharCategoryAnnotationBug {
@RequestMapping(value = "bug", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity<StreamingResponseBody> getBarChartWithCategoryAnnotationBug(String title) {
DefaultCategoryDataset barDataSet = new DefaultCategoryDataset();
String youDataKey = "You";
String weDataKey = "Neightborhood Avg.";
Map<TextAttribute, Object> values2X = new HashMap<TextAttribute, Object>();
values2X.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
values2X.put(TextAttribute.SIZE, 20);
Font scaledFont = new Font("Arial Bold", Font.PLAIN, 20).deriveFont(values2X);
barDataSet.setValue(200, youDataKey, youDataKey);
barDataSet.setValue(2000, weDataKey, weDataKey);
JFreeChart barGraph = ChartFactory.createBarChart(null, "", "",
barDataSet, PlotOrientation.HORIZONTAL, true, false, false);
Color weSpendColor = new Color(40, 137, 0);
Color youSpendColor = new Color(48, 35, 174);
// plot manipulations
CategoryPlot plotModifier = barGraph.getCategoryPlot();
barGraph.setBorderVisible(false);
plotModifier.setOutlineVisible(false);
// remove space between axis and data area
plotModifier.setAxisOffset(new RectangleInsets(0.0, 0.0, 0.0, 0.0));
plotModifier.setInsets(new RectangleInsets(0, 0, 0, 0), true);
// Axis modifications
ValueAxis rangeAxis = (ValueAxis) plotModifier.getRangeAxis();
rangeAxis.setVisible(false);
rangeAxis.setAxisLineVisible(false);
CategoryAxis domainAxis = (CategoryAxis) plotModifier.getDomainAxis();
domainAxis.setVisible(false);
domainAxis.setAxisLineStroke(new BasicStroke(4));
domainAxis.setLabelFont(scaledFont);
// Actual data point manipulations
BarRenderer renderer = (BarRenderer) plotModifier.getRenderer();
renderer.setBarPainter(new StandardBarPainter());
renderer.setBaseItemLabelsVisible(true);
renderer.setDrawBarOutline(true);
renderer.setBaseItemLabelGenerator(new CategoryItemLabelGenerator() {
@Override
public String generateRowLabel(CategoryDataset dataset, int row) {
return dataset.getRowKey(row).toString();
}
@Override
public String generateLabel(CategoryDataset dataset, int row,
int column) {
Number value = dataset.getValue(row, column);
StringBuilder sb = new StringBuilder("$");
// return sb.append(format(value.longValue())).toString();
return sb.append(value.longValue()).toString();
}
@Override
public String generateColumnLabel(CategoryDataset dataset,
int column) {
return dataset.getColumnKey(column).toString();
}
});
renderer.setBaseItemLabelFont(scaledFont);
// Color time
renderer.setSeriesPaint(0, youSpendColor, true);
renderer.setSeriesPaint(1, weSpendColor, true);
renderer.setSeriesOutlinePaint(0, youSpendColor, true);
renderer.setSeriesOutlinePaint(1, weSpendColor, true);
domainAxis.setAxisLinePaint(Color.GREEN);
plotModifier.setBackgroundPaint(Color.WHITE);
// margins and offsets
renderer.setItemMargin(0);
// for item label i.e $1K
renderer.setItemLabelAnchorOffset(2);
plotModifier.getDomainAxis().setCategoryMargin(0.0);
// for space between the plot outline and the bar
plotModifier.getDomainAxis().setLowerMargin(0.30);
plotModifier.getDomainAxis().setUpperMargin(0.0);
plotModifier.getRangeAxis().setLowerMargin(0.0);
// brings back some of the item text
plotModifier.getRangeAxis().setUpperMargin(0.30);
// annotations
CategoryTextAnnotation we = new CategoryTextAnnotation(weDataKey,weDataKey, 0.0D);
CategoryTextAnnotation you = new CategoryTextAnnotation(youDataKey,youDataKey, 0.0D);
you.setFont(scaledFont);
we.setFont(scaledFont);
you.setPaint(new Color(135, 144, 153));
we.setPaint(new Color(135, 144, 153));
you.setCategoryAnchor(CategoryAnchor.START);
we.setCategoryAnchor(CategoryAnchor.START);
// possibly a jFreeChart bug Bottom_LEFT aligns first category's annotation to the position that TOP_LEFT should/does anchors the second category annotation
you.setTextAnchor(TextAnchor.BOTTOM_LEFT);
we.setTextAnchor(TextAnchor.TOP_LEFT);
plotModifier.addAnnotation(you);
plotModifier.addAnnotation(we);
barGraph.removeLegend();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
// creating a chart with double the pixels for better rendering when client "auto layout" on mobile device
ChartUtilities.writeBufferedImageAsPNG(baos, barGraph.createBufferedImage(480,160, new ChartRenderingInfo()));
} catch (IOException e) {
//omitted
}
MultiValueMap<String, String> responseHeaders = new HttpHeaders();
responseHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE);
return new ResponseEntity<StreamingResponseBody>(
new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
baos.writeTo(outputStream);
}
}, responseHeaders, HttpStatus.OK);
}
}