1

私はjFreeChartを使用してこの種のプロットを表示しています: チャートの例

問題は、高さが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) { }
}

私はjfreechartv1.0.14とjcommonv1.0.18を使用しました。この例では、グラフの上に3つの値があります。ウィンドウを大きくすると3つの値が大きくなることがわかりますが、高さが約800ピクセルの場合、最初の値は大きくなり続けますが、他の値は大きくなりません。なんで?
大画面の解像度がない場合は、私に起こったように、おそらくエラーは表示されません。

私は何か間違ったことをしていますか?それはバグですか?

4

2 に答える 2

1

いくつかの注意:

  • org.jfree.chart.annotations「座標がデータ空間で指定されている」のいずれかを探している可能性があります。ここにいくつかの例があります

  • AJFreeChartはコンポーネントではありません。aChartPanelは、さまざまなチャートイベントに応じてパネルを再描画するコンポーネントです。aComponentListenerが保証されることはめったにありません。

  • 使用しないでくださいsetBounds(); 代わりにpack()、囲んでいるWindow; デフォルトが不十分な場合は、オーバーライドgetPreferredSize()します。ChartPanel

  • Swing GUIオブジェクトは、イベントディスパッチスレッドでのみ構築および操作してください。

于 2013-03-26T11:33:46.677 に答える
1

私自身も同様の問題を抱えていました。

この問題は、チャートパネルがデフォルトの最大サイズを制限しているため、サブプロットデータ領域の更新が正しく停止していることが原因のようです。

最大の高さ/幅を増やすと、問題が解決するはずです。

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

詳細については、このバグ投稿を参照してください。 http://sourceforge.net/p/jfreechart/bugs/911/

于 2015-07-09T17:55:05.200 に答える