如何使用JfreeChart将CategoryTextAnnotation锚定在水平条的左上角

时间:2017-02-10 22:23:53

标签: java jfreechart

我已经厌倦了自己想出这个,并想知道这是一个已知的错误还是我对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);
    }


}

With different TextAnchor]

enter image description here

0 个答案:

没有答案