2016-10-26 9 views
1

私はJFreeChartを使用してプロットを開始しました。 私は私のチャートは下の画像のようになりたい:しかし、その私はまだだろう特定のものがありますJFreeChart:BoxAndWhiskerチャートをカスタマイズする

my graph

:私はBoxAndWhiskerチャートを使用して、非常に近くに来た

Interval graph

変更したい私は唯一の中間線を持っているので、ボックスを削除する方法はありますか?バーにラベルを追加するにはどうしたらいいですか?何らかの理由で、y軸の最後の数(画像の右下)が途切れてしまいます。

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.GeneralPath; 
import java.awt.geom.Line2D; 
import java.awt.geom.Rectangle2D; 
import java.text.DecimalFormat; 
import javax.swing.Icon; 
import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.AxisLocation; 
import org.jfree.chart.axis.CategoryAxis; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.axis.ValueAxis; 
import org.jfree.chart.plot.CategoryPlot; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.renderer.category.CategoryItemRendererState; 
import org.jfree.chart.renderer.category.MinMaxCategoryRenderer; 
import org.jfree.data.category.CategoryDataset; 
import org.jfree.data.category.DefaultCategoryDataset; 
import org.jfree.ui.ApplicationFrame; 
import org.jfree.ui.RectangleInsets; 
import org.jfree.ui.RefineryUtilities; 

public class MinMaxCategoryPlotTest extends ApplicationFrame { 

    public MinMaxCategoryPlotTest(String title) { 

     super(title); 

     DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 

     dataset.addValue(1604, "1", "PESAII"); 
     dataset.addValue(1704, "2", "PESAII"); 
     dataset.addValue(1804, "3", "PESAII"); 

     dataset.addValue(1512, "1", "NSGAII"); 
     dataset.addValue(1612, "2", "NSGAII"); 
     dataset.addValue(1712, "3", "NSGAII"); 

     dataset.addValue(1436, "1", "SPEA2"); 
     dataset.addValue(1536, "2", "SPEA2"); 
     dataset.addValue(1636, "3", "SPEA2"); 

     dataset.addValue(1363, "1", "IBEA"); 
     dataset.addValue(1463, "2", "IBEA"); 
     dataset.addValue(1563, "3", "IBEA"); 

     dataset.addValue(1186, "1", "MOEA/D"); 
     dataset.addValue(1286, "2", "MOEA/D"); 
     dataset.addValue(1386, "3", "MOEA/D"); 

     final CategoryAxis xAxis = new CategoryAxis(""); 
     xAxis.setTickLabelsVisible(false); 

     final NumberAxis yAxis = new NumberAxis("Rating"); 
     yAxis.setRange(1100, 2000); 

     DecimalFormat df = new DecimalFormat("0"); // Override the decimal format to get integer numbers on the axis (1.800 -> 1800) 
     yAxis.setNumberFormatOverride(df); 
     yAxis.setAutoRangeIncludesZero(false); 

     MyMinMaxCategoryRenderer renderer = new MyMinMaxCategoryRenderer(); 

     renderer.setSeriesPaint(0, new Color(0, 0, 0, 0)); // invisible 
     renderer.setSeriesPaint(1, Color.black); 
     renderer.setSeriesPaint(2, new Color(0, 0, 0, 0)); // invisible 

     renderer.setSeriesShape(1, new Line2D.Double(0, -6, 0, 6)); //not working 
     renderer.setSeriesVisible(0, false); // not working 

     renderer.setMinIcon(getIcon(new Line2D.Double(0, -6, 0, 6), true, true)); 
     renderer.setMaxIcon(getIcon(new Line2D.Double(0, -6, 0, 6), true, true)); 
     renderer.setObjectIcon(getIcon(new Line2D.Double(0, -4, 0, 4), true, true)); 

     final CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer); 
     plot.setOrientation(PlotOrientation.HORIZONTAL); 
     plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); 

     final JFreeChart chart = new JFreeChart(
      title, 
      new Font("SansSerif", Font.BOLD, 16), 
      plot, 
      false 
     ); 

     final ChartPanel chartPanel = new ChartPanel(chart); 
     chartPanel.setPreferredSize(new java.awt.Dimension(1000, 400)); 
     setContentPane(chartPanel); 

     chart.setBackgroundPaint(Color.white); 

     chart.setPadding(new RectangleInsets(10, 10, 10, 10)); // Fix: tick label cut off 

    } 

    private Icon getIcon(Shape shape, final boolean fill, 
     final boolean outline) { 
     final int width = shape.getBounds().width; 
     final int height = shape.getBounds().height; 
     final GeneralPath path = new GeneralPath(shape); 
     return new Icon() { 
      public void paintIcon(Component c, Graphics g, int x, int y) { 
       Graphics2D g2 = (Graphics2D) g; 
       path.transform(AffineTransform.getTranslateInstance(x, y)); 
       if (fill) { 
        g2.fill(path); 
       } 
       if (outline) { 
        g2.draw(path); 
       } 
       path.transform(AffineTransform.getTranslateInstance(-x, -y)); 
      } 

      public int getIconWidth() { 
       return width; 
      } 

      public int getIconHeight() { 
       return height; 
      } 
     }; 
    } 

    public static void main(String[] args) { 

     MinMaxCategoryPlotTest demo = new MinMaxCategoryPlotTest("Rating Interval"); 
     demo.pack(); 
     RefineryUtilities.centerFrameOnScreen(demo); 
     demo.setVisible(true); 

    } 

    public class MyMinMaxCategoryRenderer extends MinMaxCategoryRenderer { 

     @Override 
     public void drawItem(Graphics2D g2, CategoryItemRendererState state, 
      Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, 
      ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, 
      int pass) { 
      super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass); 

      //Draw label 
      if (dataset.getRowCount() - 1 == row) { //last row 

       Number value = dataset.getValue(row, column); 
       double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), 
        dataArea, plot.getDomainAxisEdge()); 
       double y1 = rangeAxis.valueToJava2D(value.doubleValue(), dataArea, 
        plot.getRangeAxisEdge()); 

       g2.setFont(new Font("SansSerif", Font.BOLD, 14)); 
       g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       String name = dataset.getColumnKey(column).toString(); 
       int width = g2.getFontMetrics().stringWidth(name); 

       g2.drawString(name, (int) y1 - width, (int) x1 - 12); 

      } 
     } 

    } 
} 

評価/信頼区間の最終完全な結果:ここで

は私のサンプルコードです Final result

答えて

1

代わりBoxAndWhiskerRendererの、PlotOrientation.HORIZONTALカスタムAxisLocationMinMaxCategoryRendererを使用し、hereを調べました。

CategoryPlot plot = (CategoryPlot) chart.getPlot(); 
plot.setOrientation(PlotOrientation.HORIZONTAL); 
MinMaxCategoryRenderer renderer = new MinMaxCategoryRenderer(); 
plot.setRenderer(renderer); 
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); 

image

あなたはこのように使用Iconを変更したり、this approachをもとに、独自のアイコンを作成することができます。

renderer.setObjectIcon(renderer.getMinIcon()); 
+0

ありがとう、MinMaxCategoryRendererはトリックを行います。しかし、y軸上の最後の数字はフレームの外側にあります。私の例のように、ラベルの上にラベルをどのように表示するかはまだ分かりません。 – Ravby

+0

[カテゴリ]の[CategoryItemLabelGenerator]を使用します(http://stackoverflow.com/a/13627138/230513)。その他の問題を示す[mcve]を含めるように質問を編集してください。 – trashgod

+0

これは 'IntervalBarRenderer'では動作しますが、' MinMaxCategoryRenderer'や 'BoxAndWhiskerRenderer'では動作しません。 – Ravby

関連する問題