【问题标题】:JFreeCharts Legend Text and Color Box Don't alignJFreeCharts 图例文本和颜色框不对齐
【发布时间】:2015-09-18 18:50:00
【问题描述】:

我正在使用 JFreeCharts 并创建一个堆叠条形图。我创建了一个图例,但是当我将图例的字体更改为 Calibri 9 号之类的字体时,文本未与彩色框垂直对齐。

图例如下所示:

文字没有与方框垂直对齐,就像下面有填充物一样。以下是我自定义图表的代码

public JFreeChart createStackedChart(final CategoryDataset categorydataset, String Title) throws DocumentException, IOException {
    final JFreeChart chart = ChartFactory.createStackedBarChart(
            Title, // chart title
            "", // domain axis label
            "", // range axis label
            categorydataset, // data
            PlotOrientation.VERTICAL, // the plot orientation
            true, // legend
            true, // tooltips
            false // urls
    );


    chart.setTitle(
            new org.jfree.chart.title.TextTitle(Title,
                    new java.awt.Font("Calibri", java.awt.Font.PLAIN, 12)
            ));
    int columnCount = categorydataset.getColumnCount();
    chart.setBackgroundPaint(Color.white);
    chart.getTitle().setPadding(10, 2, 10, 2);
    chart.setBorderVisible(true);
    chart.setBorderPaint(Color.lightGray);//akash change

    final CategoryPlot plot = chart.getCategoryPlot();
    plot.setBackgroundPaint(Color.white);

    plot.setDomainGridlinePaint(Color.lightGray);
    plot.setRangeGridlinePaint(Color.lightGray);
    plot.setDomainGridlineStroke(new BasicStroke(0.5f));
    plot.setRangeGridlineStroke(new BasicStroke(0.5f));
    plot.setOutlineVisible(true);
    plot.setOutlinePaint(Color.lightGray);
    plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0));

    final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
    rangeAxis.setTickLabelFont(new Font("Calibri", Font.PLAIN, 10));
    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    rangeAxis.setAutoRangeStickyZero(false);
    rangeAxis.setLowerMargin(0.0);

    rangeAxis.setTickLabelPaint(Color.black);
    rangeAxis.setTickMarkPaint(Color.lightGray);
    rangeAxis.setTickMarkStroke(new BasicStroke(0.3f));
    rangeAxis.setAxisLineStroke(new BasicStroke(0.3f));
    rangeAxis.setLowerBound(0.0f);

    rangeAxis.setAxisLinePaint(Color.lightGray);

    GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer();
    renderer.setDrawBarOutline(false);
    renderer.setBarPainter(new StandardBarPainter());

    Paint p1 = new GradientPaint(
            0.0f, 0.0f, new Color(0x22, 0x22, 0xFF), 0.0f, 0.0f, new Color(0x88, 0x88, 0xFF)
    );
    renderer.setSeriesPaint(0, p1);
    renderer.setSeriesPaint(4, p1);
    renderer.setSeriesPaint(8, p1);

    Paint p2 = new GradientPaint(
            0.0f, 0.0f, new Color(0x22, 0xFF, 0x22), 0.0f, 0.0f, new Color(0x88, 0xFF, 0x88)
    );
    renderer.setSeriesPaint(1, p2);
    renderer.setSeriesPaint(5, p2);
    renderer.setSeriesPaint(9, p2);

    Paint p3 = new GradientPaint(
            0.0f, 0.0f, new Color(0xFF, 0x22, 0x22), 0.0f, 0.0f, new Color(0xFF, 0x88, 0x88)
    );
    renderer.setSeriesPaint(2, p3);
    renderer.setSeriesPaint(6, p3);
    renderer.setSeriesPaint(10, p3);

    Paint p4 = new GradientPaint(
            0.0f, 0.0f, new Color(0xFF, 0xFF, 0x22), 0.0f, 0.0f, new Color(0xFF, 0xFF, 0x88)
    );
    renderer.setSeriesPaint(3, p4);
    renderer.setSeriesPaint(7, p4);
    renderer.setSeriesPaint(11, p4);
    renderer.setGradientPaintTransformer(
            new StandardGradientPaintTransformer(GradientPaintTransformType.HORIZONTAL)
    );

    final CategoryAxis domainAxis = plot.getDomainAxis();
    domainAxis.setTickLabelPaint(Color.black);
    domainAxis.setTickLabelFont(new Font("Calibri", Font.PLAIN, 10));
    Color transparent = new Color(0, 0, 0, 0);
    domainAxis.setAxisLinePaint(transparent);
    domainAxis.setTickMarkPaint(Color.darkGray);
    domainAxis.setTickMarkStroke(new BasicStroke(0.3f));
    domainAxis.setMaximumCategoryLabelWidthRatio(4f);

    if (columnCount == 2) {
        domainAxis.setCategoryMargin(.6);
        domainAxis.setLowerMargin(0.015);
        domainAxis.setUpperMargin(0.015);
    } else if (columnCount == 3) {
        domainAxis.setCategoryMargin(.35);
        domainAxis.setLowerMargin(0.15);
        domainAxis.setUpperMargin(0.15);
    } else {
        domainAxis.setCategoryMargin(.55);
        domainAxis.setLowerMargin(0.015);
        domainAxis.setUpperMargin(0.015);
    }

    LegendTitle legend = chart.getLegend();//akash change
    legend.setPosition(RectangleEdge.TOP);
    legend.setItemPaint(Color.black);
    chart.getLegend()
            .setFrame(BlockBorder.NONE);
    legend.setItemPaint(Color.GRAY);
    Font labelFont = new Font("Calibri", Font.PLAIN, 9);
    legend.setItemFont(labelFont);

    if (columnCount >= 5) {
        domainAxis.setCategoryLabelPositions(
                CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 4.0));
        chart.setPadding(new RectangleInsets(0, 5, 0, 5));
    } else {
        domainAxis.setCategoryLabelPositions(
                STANDARD);
    }
    plot.setDomainAxis(domainAxis);

    return chart;

}

重要的行包括我创建图例和更改字体大小的区域。再次感谢。

【问题讨论】:

    标签: java graph alignment jfreechart


    【解决方案1】:

    从这个完整的example 开始,我看到了预期的结果,如下图所示。请注意,相关的ChartFactory“应用默认的JFree 图表主题”,默认为Tahoma,也是一种无衬线字体。为方便起见,我夸大了尺寸,并且我还使用了deriveFont() 来仅更改尺寸。

    LegendTitle legend = chart.getLegend();
    …
    Font labelFont = legend.getItemFont().deriveFont(20f);
    legend.setItemFont(labelFont);
    

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Font;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    import javax.swing.JSlider;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.block.BlockBorder;
    import org.jfree.chart.plot.CategoryPlot;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.renderer.category.GroupedStackedBarRenderer;
    import org.jfree.chart.title.LegendTitle;
    import org.jfree.data.KeyToGroupMap;
    import org.jfree.data.category.CategoryDataset;
    import org.jfree.data.category.DefaultCategoryDataset;
    import org.jfree.chart.ui.ApplicationFrame;
    import org.jfree.chart.ui.RectangleEdge;
    
    /**
     * @see https://stackoverflow.com/a/17342522/230513
     */
    public class DomainTranslateDemo extends ApplicationFrame {
    
        private static class DemoPanel extends JPanel implements ChangeListener {
    
            private static final int SLIDER_INITIAL_VALUE = -42;
            private static final double INCREMENT = 1 / 10.0;
            private final JSlider slider;
            private GroupedStackedBarRenderer renderer;
    
            public DemoPanel() {
                super(new BorderLayout());
                final CategoryDataset dataset = createDataset();
                final JFreeChart chart = createChart(dataset);
                final ChartPanel chartPanel = new ChartPanel(chart) {
    
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(640, 360);
                    }
                };
                add(chartPanel);
    
                JPanel dashboard = new JPanel(new BorderLayout());
                dashboard.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
    
                this.slider = new JSlider(-50, 10, SLIDER_INITIAL_VALUE);
                this.slider.addChangeListener(this);
                dashboard.add(this.slider);
                add(dashboard, BorderLayout.SOUTH);
            }
    
            private CategoryDataset createDataset() {
                DefaultCategoryDataset result = new DefaultCategoryDataset();
                result.addValue(1.5, "5YEUR", "5Y");
                result.addValue(-1.5, "5YUSD", "5Y");
                result.addValue(0.5, "5Yx5YEUR", "5Yx5Y");
                result.addValue(-0.5, "5Yx5YUSD", "5Yx5Y");
                result.addValue(1.5, "10Yx5YEUR", "10Yx5Y");
                result.addValue(-1.5, "10Yx5YUSD", "10Yx5Y");
                result.addValue(1.5, "15Yx5YEUR", "15Yx5Y");
                result.addValue(-1.5, "15Yx5YUSD", "15Yx5Y");
                result.addValue(1.5, "20Yx5YEUR", "20Yx5Y");
                result.addValue(-1.5, "20Yx5YUSD", "20Yx5Y");
                result.addValue(1.5, "20Yx5YEUR", "25Yx5Y");
                result.addValue(-1.5, "20Yx5YUSD", "25Yx5Y");
                return result;
            }
    
            private JFreeChart createChart(final CategoryDataset dataset) {
    
                final JFreeChart chart = ChartFactory.createStackedBarChart(
                    "Max Bar Width", // chart title
                    "Category", // domain axis label
                    "Value", // range axis label
                    dataset, // data
                    PlotOrientation.VERTICAL, // the plot orientation
                    true, // legend
                    true, // tooltips
                    false // urls
                );
    
                LegendTitle legend = chart.getLegend();
                legend.setPosition(RectangleEdge.TOP);
                legend.setFrame(BlockBorder.NONE);
                Font labelFont = legend.getItemFont().deriveFont(20f);
                legend.setItemFont(labelFont);
    
                renderer = new GroupedStackedBarRenderer();
                KeyToGroupMap map = new KeyToGroupMap("G1");
                map.mapKeyToGroup("5YEUR", "G1");
                map.mapKeyToGroup("5YUSD", "G1");
                map.mapKeyToGroup("5Yx5YEUR", "G2");
                map.mapKeyToGroup("5Yx5YUSD", "G2");
                map.mapKeyToGroup("10Yx5YEUR", "G3");
                map.mapKeyToGroup("10Yx5YUSD", "G3");
                map.mapKeyToGroup("15Yx5YEUR", "G4");
                map.mapKeyToGroup("15Yx5YUSD", "G4");
                map.mapKeyToGroup("20Yx5YEUR", "G5");
                map.mapKeyToGroup("20Yx5YUSD", "G5");
                map.mapKeyToGroup("25Yx5YEUR", "G6");
                map.mapKeyToGroup("25Yx5YUSD", "G6");
                renderer.setSeriesToGroupMap(map);
                renderer.setItemMargin(SLIDER_INITIAL_VALUE * INCREMENT);
    
                CategoryPlot plot = (CategoryPlot) chart.getPlot();
                plot.setRenderer(renderer);
                return chart;
            }
    
            @Override
            public void stateChanged(ChangeEvent event) {
                int value = slider.getValue();
                renderer.setItemMargin(value * INCREMENT);
            }
        }
    
        public DomainTranslateDemo(String title) {
            super(title);
            setContentPane(new DemoPanel());
        }
    
        public static JPanel createDemoPanel() {
            return new DemoPanel();
        }
    
        public static void main(String[] args) {
            DomainTranslateDemo demo = new DomainTranslateDemo("Translate Demo");
            demo.pack();
            demo.setLocationRelativeTo(null);
            demo.setVisible(true);
        }
    }
    

    【讨论】:

    • 如果我把字体改成 Calibri,这还能用吗?
    • 对我有用;由于您在多个地方使用ChartTheme,您可能需要创建自己的ChartTheme
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    相关资源
    最近更新 更多