2013-03-26 92 views
1

我使用的JFreeChart顯示這種情節: chart examplejFreeChart。組合圖表錯誤中的子圖的高度?

好了,問題是,當程序> 800像素高度黑影在監視器上運行,並且45虛線不正確地繪製。

我發現,這個問題是由返回錯誤值造成的:

chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0).getDataArea() 

的DATAAREA是不正確的,高度是錯誤的,因此陰影不是畫在預期的位置。但是,這隻發生在調整大於800px高度的窗口時。

我已經成功地重現錯誤的小SSCCE(jcommon和jfreechart的需要):

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.event.ComponentEvent; 
import java.awt.event.ComponentListener; 
import java.awt.geom.Rectangle2D; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.border.EmptyBorder; 

import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.plot.CombinedDomainXYPlot; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYItemRenderer; 
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; 
import org.jfree.data.time.TimeSeriesCollection; 
import org.jfree.ui.RectangleEdge; 
import org.jfree.ui.RectangleInsets; 

public class Window extends JFrame implements ComponentListener { 
    private static final long serialVersionUID = 1L; 
    private JPanel contentPane; 
    private XYPlot subplotTop; 
    private XYPlot subplotBottom; 
    private CombinedDomainXYPlot plot; 
    private JFreeChart chart; 
    private ChartPanel chartPanel; 
    private JLabel label; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        Window frame = new Window(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public Window() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 700, 500); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     contentPane.setLayout(new BorderLayout(0, 0)); 
     setContentPane(contentPane); 

     JPanel example = new JPanel(); 
     label = new JLabel("Resize this window (do not use the \"maximize\" button"); 
     example.add(label); 
     contentPane.add(example, BorderLayout.NORTH); 

     createTopChart(); 
     createBottomChart(); 
     createCombinedChart(); 
     chartPanel = new ChartPanel(chart); 
     this.add(chartPanel, BorderLayout.CENTER); 

     //window resize listener 
     this.addComponentListener(this); 
    } 

    private void createTopChart() { 
     subplotTop = new XYPlot(); 
     subplotTop.setDomainPannable(true); 
     subplotTop.setBackgroundPaint(Color.lightGray); 
     subplotTop.setDomainGridlinePaint(Color.white); 
     subplotTop.setRangeGridlinePaint(Color.white); 

     XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); 
     subplotTop.setRenderer(renderer); 

     NumberAxis range = new NumberAxis("dBA"); 
     range.setRange(30, 120); 
     range.setAutoRange(false); 
     subplotTop.setRangeAxis(range); 

     TimeSeriesCollection dataset_L = randomDataset(30,120); 
     subplotTop.setDataset(dataset_L); 
    } 

    private void createBottomChart(){ 
     subplotBottom = new XYPlot(); 
     subplotBottom.setDomainPannable(true); 
     subplotBottom.setBackgroundPaint(Color.lightGray); 
     subplotBottom.setDomainGridlinePaint(Color.white); 
     subplotBottom.setRangeGridlinePaint(Color.white); 

     XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); 
     subplotBottom.setRenderer(renderer); 

     NumberAxis range = new NumberAxis("%"); 
     range.setRange(-10, 100); 
     range.setAutoRange(false); 
     subplotBottom.setRangeAxis(range); 

     TimeSeriesCollection dataset_P = randomDataset(0,100); 
     subplotBottom.setDataset(dataset_P); 
    } 

    private void createCombinedChart() {  
     plot = new CombinedDomainXYPlot(); 
     plot.setGap(30); 
     plot.add(subplotTop, 4); 
     plot.add(subplotBottom, 1); 
     plot.setOrientation(PlotOrientation.VERTICAL); 

     chart = new JFreeChart("Title", new Font("Arial", Font.BOLD, 18), plot, true); 
     chart.getLegend().setVisible(false); 
     chart.getLegend().setPosition(RectangleEdge.RIGHT); 
     chart.getTitle().setMargin(new RectangleInsets(15,5,15,5)); 
     chart.getTitle().setPaint(Color.BLACK); 
    } 

    private TimeSeriesCollection randomDataset(float min, float max) { 
     return null; 
    } 

    private void showAreas() { 
     Rectangle2D screenDataAreaChartPanel = this.chartPanel.getScreenDataArea(); 
     System.out.println("screenDataAreaChartPanel: "+screenDataAreaChartPanel); 

     Rectangle2D plotArea = this.chartPanel.getChartRenderingInfo().getPlotInfo().getPlotArea(); 
     System.out.println("getPlotArea: "+plotArea.toString()); 

     Rectangle2D dataAreaPlot = this.chartPanel.getChartRenderingInfo().getPlotInfo().getDataArea(); 
     System.out.println("getDataArea: "+dataAreaPlot.toString()); 

     Rectangle2D dataAreaSubplotTop = this.chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0).getDataArea(); 
     Rectangle2D dataAreaSubplotBottom = this.chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(1).getDataArea(); 
     System.out.println("dataAreaSubplotTop: "+dataAreaSubplotTop.toString()); 
     System.out.println("dataAreaSubplotBottom: "+dataAreaSubplotBottom.toString()); 

     System.out.println(); 

     label.setText("ScreenDataArea.height="+Math.round(screenDataAreaChartPanel.getHeight())+ 
       ". SubPlotTop.heigth="+Math.round(dataAreaSubplotTop.getHeight())+ 
       ". SubPlotBottom.heigth="+Math.round(dataAreaSubplotBottom.getHeight())); 
     repaint(); 
    } 

    @Override 
    public void componentHidden(ComponentEvent e) {} 

    @Override 
    public void componentMoved(ComponentEvent e) { } 

    @Override 
    public void componentResized(ComponentEvent e) { 
     chartPanel.repaint(); 
     chartPanel.revalidate(); 
     this.repaint(); 
     showAreas(); 
    } 

    @Override 
    public void componentShown(ComponentEvent e) { } 
} 

我已經使用了JFreeChart v1.0.14和jcommon v1.0.18。 在該示例中,圖表上方有三個值。你會發現三個數值會隨着窗口變大而增大,但在800px左右的高度上,第一個值會保持增長,而其他值不會增加。爲什麼?
如果您沒有大屏幕分辨率,您可能不會看到錯誤,因爲它發生在我身上。

我做錯了什麼?這是一個錯誤?

+1

+1 [sscce](http://sscce.org/)。這個例子是否意味着空虛? – trashgod 2013-03-26 11:34:18

+0

是@trashgod沒有必要添加數據,錯誤同時出現有數據和沒有數據,所以它似乎沒有關聯 – TheBronx 2013-03-26 12:18:42

+0

Cross-posted [here](http://www.jfree.org/forum/viewtopic .PHP?F = 3&T = 116448)。 – trashgod 2013-03-27 02:12:06

回答

1

的幾個注意事項:

  • 你可能會尋找org.jfree.chart.annotations之一,其中「座標數據空間中指定;」幾個例子見here

  • A JFreeChart不是組件;一個ChartPanel是重繪的面板響應各種圖表事件的組件; ComponentListener很少有擔保。

  • 請勿使用setBounds();相反,pack()內附Window;如果默認值不滿意,則在ChartPanel中覆蓋getPreferredSize()

  • event dispatch thread上構建和操作Swing GUI對象只有

+0

感謝您的回答。我只使用'setBounds'作爲例子。在EDT中正在操作GUI對象。我不明白你想用第二點說什麼,我應該改變ComponentListener嗎?我應該用什麼來代替? – TheBronx 2013-03-26 12:28:38

+0

註解將簡化整個問題。 – trashgod 2013-03-26 12:30:32

+0

我會看看註釋,但我不知道怎麼才能知道子圖高度與 – TheBronx 2013-03-26 12:37:20

1

我自己也有類似的問題。

該問題似乎源於圖表面板限制其默認最大大小,導致子圖塊數據區域停止正確更新。

增加最大高度/寬度應該可以解決您的問題。

panel.setMaximumHeight(2000); 
panel.setMaximumSize(1500); 

查看此錯誤信息以獲取更多信息。 http://sourceforge.net/p/jfreechart/bugs/911/