无法更改极坐标图中的图例形状和字体

Unable to change legend shape and font in polar plot

我正在尝试使用 jfreechart 极坐标图在 java 中创建天空图。 一切正常。但是我无法更改各种系列图例标记及其大小。

这是我的代码示例:

public class Skyplot {
       private JFrame plotFrame = null;

       public static void main (String[] args){
           Skyplot sp = new Skyplot();
           sp.display();
       }

       public Skyplot(){
       }

       public void display(){
           javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    plot(); 
                }
            });
       }

       private void plot(){
           // create and set up the window
           plotFrame = new JFrame("Visualizer");
           plotFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
           //Display the window.
           plotFrame.pack();
           plotFrame.setVisible(true);
           plotFrame.setLocation(500, 500);
           plotFrame.setSize(1200, 900);

           // set up the content pane
           Container C = plotFrame.getContentPane();

           Plotter pl = new Plotter();
           pl.setBorder(BorderFactory.createRaisedBevelBorder());
           pl.setBackground(Color.WHITE);

           C.setLayout(new GridLayout(1, 1));
           C.add(pl);  
       }


       private class Plotter extends JPanel {
           private static final long serialVersionUID = 1L;

           public Plotter(){ 
               XYDataset dataset = getXYDataset();

               final ChartPanel chartPanel = createChartPanel(dataset);
               this.add(chartPanel, BorderLayout.CENTER);
           }

           private ChartPanel createChartPanel(XYDataset dataset) {
               // Create chart
               JFreeChart chart = ChartFactory.createPolarChart("Skyplot", dataset, true, true, false);

               PolarPlot polPlot = (PolarPlot) chart.getPlot();
               polPlot.setRadiusMinorGridlinesVisible(false);
               polPlot.setBackgroundPaint(Color.WHITE);
               polPlot.setRadiusGridlinePaint(Color.DARK_GRAY);
               polPlot.setAngleGridlinePaint(Color.BLACK);

               DefaultPolarItemRenderer renderer = (DefaultPolarItemRenderer) polPlot.getRenderer();
               renderer.setBaseLegendShape(new Rectangle(15,15));
               Font legend_font = new Font("Verdana", Font.PLAIN, 24);
               renderer.setBaseLegendTextFont(legend_font);

               NumberAxis rangeAxis = (NumberAxis) polPlot.getAxis();
               rangeAxis.setTickUnit(new NumberTickUnit(10.0));
               rangeAxis.setMinorTickMarksVisible(false);
               rangeAxis.setRange(0.0, 90.0);
               rangeAxis.setInverted(true);


               return new ChartPanel(chart){
                   @Override
                   public Dimension getPreferredSize() {
                       double H = plotFrame.getHeight()*0.9;
                       double W = plotFrame.getWidth()*0.9;
                       return new Dimension((int)W, (int)H);
                   }
               };
           }

           private XYDataset getXYDataset() {
               XYSeriesCollection dataset = new XYSeriesCollection();

              XYSeries g01= new XYSeries("G01");
              series.add(35, 45);
              dataset.addSeries(g01);

              XYSeries g02= new XYSeries("G02");
              series.add(105, 73);
              dataset.addSeries(g01);

              XYSeries g03= new XYSeries("G03");
              series.add(264, 15);
              dataset.addSeries(g03);

              return dataset;
           }

       }

    }

知道为什么它不起作用吗? 我在渲染器上做错了什么吗? 任何帮助,将不胜感激。谢谢。

丢失的部分似乎是在告诉父 AbstractRenderersetShapesVisible()

renderer.setShapesVisible(true);

I want to make all shapes rectangle and the text inside the legend larger.

要协调图表和图例中的颜色和形状,请使用自定义 DrawingSupplier, as suggested here。确切的细节将取决于您的用例,但基本方法是覆盖 DefaultDrawingSupplier 方法 getNextPaint()getNextShape() 以便它们 return 您选择的颜色和形状。

要使图例文本更大,请更新图表的 LegendTitle,如下图所示。

LegendTitle title = chart.getLegend();
title.setItemFont(new Font(Font.SERIF, Font.BOLD, 24));

更新后:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/** @see  */
public class Skyplot {

    private JFrame plotFrame = null;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Skyplot()::plot);
    }

    private void plot() {
        plotFrame = new JFrame("Visualizer");
        plotFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        plotFrame.add(new Plotter());
        plotFrame.pack();
        plotFrame.setLocationRelativeTo(null);
        plotFrame.setVisible(true);
    }

    private static final class Plotter extends JPanel {

        public Plotter() {
            super(new GridLayout());
            this.add(createChartPanel(getXYDataset()));
        }

        private ChartPanel createChartPanel(XYDataset dataset) {
            JFreeChart chart = ChartFactory.createPolarChart("Skyplot", dataset, true, true, false);
            LegendTitle title = chart.getLegend();
            title.setItemFont(new Font(Font.SERIF, Font.BOLD, 24));

            PolarPlot polPlot = (PolarPlot) chart.getPlot();
            polPlot.setRadiusMinorGridlinesVisible(false);
            polPlot.setBackgroundPaint(Color.WHITE);
            polPlot.setRadiusGridlinePaint(Color.DARK_GRAY);
            polPlot.setAngleGridlinePaint(Color.BLACK);

            DefaultPolarItemRenderer renderer = (DefaultPolarItemRenderer) polPlot.getRenderer();
            renderer.setShapesVisible(true);

            NumberAxis rangeAxis = (NumberAxis) polPlot.getAxis();
            rangeAxis.setTickUnit(new NumberTickUnit(10.0));
            rangeAxis.setMinorTickMarksVisible(false);
            rangeAxis.setRange(0.0, 90.0);
            rangeAxis.setInverted(true);

            return new ChartPanel(chart) {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(800, 600);
                }
            };
        }

        private XYDataset getXYDataset() {
            XYSeriesCollection dataset = new XYSeriesCollection();

            XYSeries g01 = new XYSeries("G01");
            g01.add(35, 45);
            dataset.addSeries(g01);

            XYSeries g02 = new XYSeries("G02");
            g02.add(105, 73);
            dataset.addSeries(g02);

            XYSeries g03 = new XYSeries("G03");
            g03.add(264, 15);
            dataset.addSeries(g03);

            return dataset;
        }
    }
}

我已经使用了上面的建议。 现在创建图表的方法如下所示:

private ChartPanel createChartPanel(XYDataset dataset) {
               // Create chart
               JFreeChart chart = ChartFactory.createPolarChart("Skyplot", dataset, true, true, false);

               PolarPlot polPlot = (PolarPlot) chart.getPlot();
               polPlot.setRadiusMinorGridlinesVisible(false);
               polPlot.setBackgroundPaint(Color.WHITE);
               polPlot.setRadiusGridlinePaint(Color.DARK_GRAY);
               polPlot.setAngleGridlinePaint(Color.BLACK);
               polPlot.setDrawingSupplier(new DrawingSupplier() {
                    @Override
                    public Paint getNextFillPaint() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public Paint getNextOutlinePaint() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public Stroke getNextOutlineStroke() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public Paint getNextPaint() {
                        Random rand = new Random();
                        int r = rand.nextInt(255);
                        int g = rand.nextInt(255);
                        int b = rand.nextInt(255);

                        return new Color(r,g,b);
                    }

                    @Override
                    public Shape getNextShape() {
                        return ShapeUtilities.createDiamond(5f);
                    }


                    @Override
                    public Stroke getNextStroke() {
                        // TODO Auto-generated method stub
                        return null;
                    }

                });

               NumberAxis rangeAxis = (NumberAxis) polPlot.getAxis();
               rangeAxis.setTickUnit(new NumberTickUnit(10.0));
               rangeAxis.setMinorTickMarksVisible(false);
               rangeAxis.setRange(0.0, 90.0);
               rangeAxis.setInverted(true);

               LegendTitle legend = chart.getLegend();
               Font legend_font = new Font("Verdana", Font.BOLD, 18);
               legend.setItemFont(legend_font);

               return new ChartPanel(chart){
                   @Override
                   public Dimension getPreferredSize() {
                       double H = plotFrame.getHeight()*0.9;
                       double W = plotFrame.getWidth()*0.9;
                       return new Dimension((int)W, (int)H);
                   }
               };
           }

使用DrawingSupplier的结果如下: resulting skyplot