2015-04-17 153 views
4

我正嘗試在Java中創建自定義動態直方圖類型條形圖。我搜索了很多,但沒有找到一個方法來實現這一目標。我知道JFreeChart庫,但它不符合我的需要。這是JFreeChart的直方圖的樣子:自定義圖形 - Java Swing

enter image description here

但我要的是一個dyanamic直方圖只有X軸。
這photoshopped圖像會讓它更容易理解。 enter image description here

JFrame將有固定的邊界。如你所見,應該沒有Y軸。根據這些值自動調整條的高度。

請幫我建立這個!提前致謝。

+2

也許像[這裏](http://stackoverflow.com/questions/12518496/drawing-a -graphical-histogram/12520104#12520104)爲起點 – MadProgrammer

回答

3

一個窮人的直方圖:

enter image description here

import java.awt.*; 
import java.util.List; 
import java.util.ArrayList; 
import javax.swing.*; 
import javax.swing.border.*; 

public class HistogramPanel extends JPanel 
{ 
    private int histogramHeight = 200; 
    private int barWidth = 50; 
    private int barGap = 10; 

    private JPanel barPanel; 
    private JPanel labelPanel; 

    private List<Bar> bars = new ArrayList<Bar>(); 

    public HistogramPanel() 
    { 
     setBorder(new EmptyBorder(10, 10, 10, 10)); 
     setLayout(new BorderLayout()); 

     barPanel = new JPanel(new GridLayout(1, 0, barGap, 0)); 
     Border outer = new MatteBorder(1, 1, 1, 1, Color.BLACK); 
     Border inner = new EmptyBorder(10, 10, 0, 10); 
     Border compound = new CompoundBorder(outer, inner); 
     barPanel.setBorder(compound); 

     labelPanel = new JPanel(new GridLayout(1, 0, barGap, 0)); 
     labelPanel.setBorder(new EmptyBorder(5, 10, 0, 10)); 

     add(barPanel, BorderLayout.CENTER); 
     add(labelPanel, BorderLayout.PAGE_END); 
    } 

    public void addHistogramColumn(String label, int value, Color color) 
    { 
     Bar bar = new Bar(label, value, color); 
     bars.add(bar); 
    } 

    public void layoutHistogram() 
    { 
     barPanel.removeAll(); 
     labelPanel.removeAll(); 

     int maxValue = 0; 

     for (Bar bar: bars) 
      maxValue = Math.max(maxValue, bar.getValue()); 

     for (Bar bar: bars) 
     { 
      JLabel label = new JLabel(bar.getValue() + ""); 
      label.setHorizontalTextPosition(JLabel.CENTER); 
      label.setHorizontalAlignment(JLabel.CENTER); 
      label.setVerticalTextPosition(JLabel.TOP); 
      label.setVerticalAlignment(JLabel.BOTTOM); 
      int barHeight = (bar.getValue() * histogramHeight)/maxValue; 
      Icon icon = new ColorIcon(bar.getColor(), barWidth, barHeight); 
      label.setIcon(icon); 
      barPanel.add(label); 

      JLabel barLabel = new JLabel(bar.getLabel()); 
      barLabel.setHorizontalAlignment(JLabel.CENTER); 
      labelPanel.add(barLabel); 
     } 
    } 

    private class Bar 
    { 
     private String label; 
     private int value; 
     private Color color; 

     public Bar(String label, int value, Color color) 
     { 
      this.label = label; 
      this.value = value; 
      this.color = color; 
     } 

     public String getLabel() 
     { 
      return label; 
     } 

     public int getValue() 
     { 
      return value; 
     } 

     public Color getColor() 
     { 
      return color; 
     } 
    } 

    private class ColorIcon implements Icon 
    { 
     private int shadow = 3; 

     private Color color; 
     private int width; 
     private int height; 

     public ColorIcon(Color color, int width, int height) 
     { 
      this.color = color; 
      this.width = width; 
      this.height = height; 
     } 

     public int getIconWidth() 
     { 
      return width; 
     } 

     public int getIconHeight() 
     { 
      return height; 
     } 

     public void paintIcon(Component c, Graphics g, int x, int y) 
     { 
      g.setColor(color); 
      g.fillRect(x, y, width - shadow, height); 
      g.setColor(Color.GRAY); 
      g.fillRect(x + width - shadow, y + shadow, shadow, height - shadow); 
     } 
    } 

    private static void createAndShowGUI() 
    { 
     HistogramPanel panel = new HistogramPanel(); 
     panel.addHistogramColumn("A", 350, Color.RED); 
     panel.addHistogramColumn("B", 690, Color.YELLOW); 
     panel.addHistogramColumn("C", 510, Color.BLUE); 
     panel.addHistogramColumn("D", 570, Color.ORANGE); 
     panel.addHistogramColumn("E", 180, Color.MAGENTA); 
     panel.addHistogramColumn("F", 504, Color.CYAN); 
     panel.layoutHistogram(); 

     JFrame frame = new JFrame("Histogram Panel"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(panel); 
     frame.setLocationByPlatform(true); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
+1

另請參閱此相關的[方法](http://stackoverflow.com/a/29283528/230513)。 – trashgod

+0

我試圖將這個直方圖添加到另一個類(它在同一個包中)中的JFrame的JPanel。當我使用'panel.add(新的直方圖());',直方圖不顯示。你能幫我解決這個問題嗎? –

+0

@camickr請幫忙^^ –

4

我給JFreeChart第二次看。您可以使範圍軸不可見並使用項目標籤。缺少圖例,重寫getItemPaint()可以提供任意顏色。另一種方法顯示爲here

image

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Paint; 
import javax.swing.JFrame; 
import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.CategoryAxis; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.axis.ValueAxis; 
import org.jfree.chart.labels.ItemLabelAnchor; 
import org.jfree.chart.labels.ItemLabelPosition; 
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; 
import org.jfree.chart.plot.CategoryPlot; 
import org.jfree.chart.renderer.category.BarRenderer; 
import org.jfree.chart.renderer.category.StandardBarPainter; 
import org.jfree.data.category.CategoryDataset; 
import org.jfree.data.category.DefaultCategoryDataset; 
import org.jfree.ui.TextAnchor; 

/** 
* @see https://stackoverflow.com/a/29709153/230513 
*/ 
public class BarChart { 

    private CategoryDataset createDataset() { 
     String row = "Row"; 
     DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 
     dataset.addValue(350, row, "A"); 
     dataset.addValue(690, row, "B"); 
     dataset.addValue(510, row, "C"); 
     dataset.addValue(570, row, "D"); 
     dataset.addValue(180, row, "E"); 
     dataset.addValue(504, row, "F"); 
     return dataset; 
    } 

    private JFreeChart createChart(CategoryDataset dataset) { 
     CategoryAxis categoryAxis = new CategoryAxis(""); 
     ValueAxis valueAxis = new NumberAxis(""); 
     valueAxis.setVisible(false); 
     BarRenderer renderer = new BarRenderer() { 

      @Override 
      public Paint getItemPaint(int row, int column) { 
       switch (column) { 
        case 0: 
         return Color.red; 
        case 1: 
         return Color.yellow; 
        case 2: 
         return Color.blue; 
        case 3: 
         return Color.orange; 
        case 4: 
         return Color.gray; 
        case 5: 
         return Color.green.darker(); 
        default: 
         return Color.red; 
       } 
      } 
     }; 
     renderer.setDrawBarOutline(false); 
     renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); 
     renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
      ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER)); 
     renderer.setBaseItemLabelsVisible(Boolean.TRUE); 
     renderer.setBarPainter(new StandardBarPainter()); 
     CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer); 
     JFreeChart chart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, plot, false); 
     chart.setBackgroundPaint(Color.white); 
     return chart; 
    } 

    private void display() { 
     JFrame f = new JFrame("BarChart"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new ChartPanel(createChart(createDataset()))); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> { 
      new BarChart().display(); 
     }); 
    } 
}