【问题标题】:How to create hollow shapes in JFreeChart Scatter Plot如何在 JFreeChart 散点图中创建空心形状
【发布时间】:2019-11-12 05:32:47
【问题描述】:

使用的 JFreeChart 版本:1.5.0

我尝试了以下方法来获得散点图中的空心形状:

PlotFrame.java文件内容:

package javaapplication1;


import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 *
 * @author tarik
 */
public class PlotFrame extends javax.swing.JFrame {    
    public static void main(String[] argv) {
        PlotFrame plotFrame = new PlotFrame();
        plotFrame.setVisible(true);
    }


    /**
     * Creates new form PlotFrame
     */
    public PlotFrame() {    
        this.setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JFreeChart chart = createChart();    
        ChartPanel panel = new ChartPanel(chart);

        this.add(panel);
        pack();
    }

    private JFreeChart createChart() {
        // Create dataset  
        XYDataset dataset = createDataset();

        // Create chart  
        JFreeChart chart = ChartFactory.createScatterPlot(
                "Boys VS Girls weight comparison chart",
                "X-Axis", "Y-Axis", dataset);

        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
        //renderer.setBaseShapesFilled(false); 
        renderer.setUseFillPaint(false);

        return chart;
    }

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

        //Boys (Age,weight) series  
        XYSeries series1 = new XYSeries("Boys");
        series1.add(1, 72.9);
        series1.add(2, 81.6);
        series1.add(3, 88.9);
        series1.add(4, 96);
        series1.add(5, 102.1);
        series1.add(6, 108.5);
        series1.add(7, 113.9);
        series1.add(8, 119.3);
        series1.add(9, 123.8);
        series1.add(10, 124.4);

        dataset.addSeries(series1);

        //Girls (Age,weight) series  
        XYSeries series2 = new XYSeries("Girls");
        series2.add(1, 72.5);
        series2.add(2, 80.1);
        series2.add(3, 87.2);
        series2.add(4, 94.5);
        series2.add(5, 101.4);
        series2.add(6, 107.4);
        series2.add(7, 112.8);
        series2.add(8, 118.2);
        series2.add(9, 122.9);
        series2.add(10, 123.4);

        dataset.addSeries(series2);

        return dataset;
    }
}

它不起作用,形状仍然被填充。

【问题讨论】:

    标签: jfreechart marker scatter


    【解决方案1】:

    回想一下Graphics2D 可以draw() Shape 的轮廓以及fill() 的内部。通过将渲染限制为draw(),@micro 的approach 在这方面是合理的,但它假定版本为 1.0.19。当migrating 到 1.5 及更高版本时,请注意“许多方法 getBaseXXX()/setBaseXXX() 已重命名为 setDefaultXXX()/getDefaultXXX()。”正确的配方如下图所示:

    renderer.setDefaultShapesFilled(false); 
    renderer.setUseFillPaint(false);
    

    其他变化:

    经测试:

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    
    /**
     * @see https://stackoverflow.com/q/58812592/230513
     * @author trashgod
     * @author tarik
     */
    public class PlotFrame extends javax.swing.JFrame {    
        public static void main(String[] argv) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    PlotFrame plotFrame = new PlotFrame();
                    plotFrame.setLocationRelativeTo(null);
                    plotFrame.setVisible(true);
                }
            });
        }
    
        /**
         * Creates new form PlotFrame
         */
        public PlotFrame() {    
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JFreeChart chart = createChart();    
            ChartPanel panel = new ChartPanel(chart){
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(640, 480);
                }
            };
            this.add(panel);
            this.pack();
        }
    
        private JFreeChart createChart() {
            // Create dataset  
            XYDataset dataset = createDataset();
    
            // Create chart  
            JFreeChart chart = ChartFactory.createScatterPlot(
                    "Boys VS Girls weight comparison chart",
                    "X-Axis", "Y-Axis", dataset);
    
            XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
            renderer.setDefaultShapesFilled(false); 
            renderer.setUseFillPaint(false);
    
            return chart;
        }
    
        private XYDataset createDataset() {
            XYSeriesCollection dataset = new XYSeriesCollection();
    
            //Boys (Age,weight) series  
            XYSeries series1 = new XYSeries("Boys");
            series1.add(1, 72.9);
            series1.add(2, 81.6);
            series1.add(3, 88.9);
            series1.add(4, 96);
            series1.add(5, 102.1);
            series1.add(6, 108.5);
            series1.add(7, 113.9);
            series1.add(8, 119.3);
            series1.add(9, 123.8);
            series1.add(10, 124.4);
    
            dataset.addSeries(series1);
    
            //Girls (Age,weight) series  
            XYSeries series2 = new XYSeries("Girls");
            series2.add(1, 72.5);
            series2.add(2, 80.1);
            series2.add(3, 87.2);
            series2.add(4, 94.5);
            series2.add(5, 101.4);
            series2.add(6, 107.4);
            series2.add(7, 112.8);
            series2.add(8, 118.2);
            series2.add(9, 122.9);
            series2.add(10, 123.4);
    
            dataset.addSeries(series2);
    
            return dataset;
        }
    }
    

    【讨论】:

      【解决方案2】:

      来自源代码:

       if (getItemShapeFilled(series, item)) {
                      if (this.useFillPaint) {
                          g2.setPaint(getItemFillPaint(series, item));
                      }
                      else {
                          g2.setPaint(getItemPaint(series, item));
                      }
                      g2.fill(shape);
         }
      

      对于第一个if 没有别的,所以我们需要getItemShapeFilled 返回false。它看起来像这样:

            public boolean getItemShapeFilled(int series, int item) {
                  Boolean flag = getSeriesShapesFilled(series);
                  if (flag != null) {
                      return flag;
                  }
                  return this.baseShapesFilled;
            }
      

      最简单的方法就是使用这个方法:

             public void setBaseShapesFilled(boolean flag) {
                    this.baseShapesFilled = flag;
                    fireChangeEvent();
              }
      

      所以实际的代码是:

      import javax.swing.JFrame;
      import org.jfree.chart.ChartFactory;
      import org.jfree.chart.ChartPanel;
      import org.jfree.chart.JFreeChart;
      import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
      import org.jfree.data.xy.XYDataset;
      import org.jfree.data.xy.XYSeries;
      import org.jfree.data.xy.XYSeriesCollection;
      
      /**
       *
       * @author tarik
       */
      public class PlotFrame extends javax.swing.JFrame {    
          public static void main(String[] argv) {
              PlotFrame plotFrame = new PlotFrame();
              plotFrame.setVisible(true);
          }
      
      
          /**
           * Creates new form PlotFrame
           */
          public PlotFrame() {    
              this.setLocationRelativeTo(null);
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
              JFreeChart chart = createChart();    
              ChartPanel panel = new ChartPanel(chart);
      
              this.add(panel);
              pack();
          }
      
          private JFreeChart createChart() {
              // Create dataset  
              XYDataset dataset = createDataset();
      
              // Create chart  
              JFreeChart chart = ChartFactory.createScatterPlot(
                      "Boys VS Girls weight comparison chart",
                      "X-Axis", "Y-Axis", dataset);
      
              XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
              renderer.setBaseShapesFilled(false); 
              renderer.setUseFillPaint(false);
      
              return chart;
          }
      
          private XYDataset createDataset() {
              XYSeriesCollection dataset = new XYSeriesCollection();
      
              //Boys (Age,weight) series  
              XYSeries series1 = new XYSeries("Boys");
              series1.add(1, 72.9);
              series1.add(2, 81.6);
              series1.add(3, 88.9);
              series1.add(4, 96);
              series1.add(5, 102.1);
              series1.add(6, 108.5);
              series1.add(7, 113.9);
              series1.add(8, 119.3);
              series1.add(9, 123.8);
              series1.add(10, 124.4);
      
              dataset.addSeries(series1);
      
              //Girls (Age,weight) series  
              XYSeries series2 = new XYSeries("Girls");
              series2.add(1, 72.5);
              series2.add(2, 80.1);
              series2.add(3, 87.2);
              series2.add(4, 94.5);
              series2.add(5, 101.4);
              series2.add(6, 107.4);
              series2.add(7, 112.8);
              series2.add(8, 118.2);
              series2.add(9, 122.9);
              series2.add(10, 123.4);
      
              dataset.addSeries(series2);
      
              return dataset;
          }
      }
      

      我的结果是:

      这不是你的意思吗?

      【讨论】:

      • 将在恢复工作时尝试此操作,如果有效,将不会无法将您的答案标记为已接受。
      • 好的,我尝试了您的解决方案,但没有成功。未找到符号错误。查看包含完整代码的更新问题。
      • 我已经详细说明了差异here。由于我的回答只是解释性的,请不要犹豫,将赏金奖励给@micro。
      • renderer.setBaseShapesFilled(false);我找不到符号。我正在使用 JFreeChart 1.5
      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 2012-09-12
      相关资源
      最近更新 更多