CombinedDomainXYPlot を使用しているグラフからシリーズの数を非表示にすると、すべての範囲軸が適切に自動再スケーリングされます。ただし、ドメイン軸は再スケーリングされません。スケーリングを手動で更新する方法はありますか、またはこの設定でドメイン軸の自動スケーリングを有効にするために欠落している設定がありますか?
2 に答える
CombinedDomainXYPlot
Range
の共有ドメイン軸の結合最大値を確立しますgetDataRange()
。これは、軸を共有できるようにするために必要です。シリーズの可視性を変更しても、共有ドメイン軸には影響しません。変更すると、そのメソッドDataset
を介して共有ドメイン軸が更新されます。configure()
いずれの場合も、サブプロットの範囲軸は個別に更新できます。
以下の例では、サブプロットを更新したり、シリーズの可視性を個別に変更したりできます。休憩しconfigure()
て効果を確認してください。トグルへのあなたの提案は、へsetAutoRange ()
の単一の呼び出しに置き換えることができますconfigure()
; Range
しかし、データとその結合された最大値は変更されていないため、効果はゼロになるはずです。
mainPlot.getDomainAxis().configure();
共有ドメイン軸を自動的に更新するには、 の代わりにaddSeries()
またはを使用します。removeSeries()
setSeriesVisible()
余談ですが、初期スレッドとpack()
.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.*;
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.StandardXYItemRenderer;
import static org.jfree.chart.renderer.xy.StandardXYItemRenderer.*;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/**
* @see https://stackoverflow.com/a/64508866/230513
* @see https://stackoverflow.com/q/11870416/230513
*/
public class CombinedPlot {
private static final int MAX = 3;
private static final Random RND = new Random();
public static void main(String[] args) {
EventQueue.invokeLater(CombinedPlot::init);
}
private static void init() {
XYItemRenderer renderer = new StandardXYItemRenderer(SHAPES_AND_LINES);
XYPlot plot1 = new XYPlot(
generateData(), null, new NumberAxis("Range 1"), renderer);
XYPlot plot2 = new XYPlot(
generateData(), null, new NumberAxis("Range 2"), renderer);
final CombinedDomainXYPlot plot =
new CombinedDomainXYPlot(new NumberAxis("Domain"));
plot.setDomainPannable(true);
plot.setRangePannable(true);
plot.add(plot1);
plot.add(plot2);
plot.setOrientation(PlotOrientation.VERTICAL);
JFreeChart chart = new JFreeChart(
"Combined Plots", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(800, 500));
JPanel controlPanel = new JPanel();
controlPanel.add(new JButton(new UpdateAction(plot, 0)));
controlPanel.add(new JButton(new UpdateAction(plot, 1)));
for (int i = 0; i < MAX; i++) {
JCheckBox jcb = new JCheckBox(new VisibleAction(renderer, i));
jcb.setSelected(true);
renderer.setSeriesVisible(i, true);
controlPanel.add(jcb);
}
JFrame frame = new JFrame("Combined Plot Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(chartPanel, BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class UpdateAction extends AbstractAction {
private final XYPlot plot;
public UpdateAction(CombinedDomainXYPlot plot, int i) {
super("Update plot " + (i + 1));
this.plot = (XYPlot) plot.getSubplots().get(i);
}
@Override
public void actionPerformed(ActionEvent e) {
plot.setDataset(CombinedPlot.generateData());
}
}
private static class VisibleAction extends AbstractAction {
private XYItemRenderer renderer;
private int i;
public VisibleAction(XYItemRenderer renderer, int i) {
super("Series " + (i + 1));
this.renderer = renderer;
this.i = i;
}
@Override
public void actionPerformed(ActionEvent e) {
renderer.setSeriesVisible(i, !renderer.getSeriesVisible(i));
}
}
private static XYSeriesCollection generateData() {
XYSeriesCollection data = new XYSeriesCollection();
for (int i = 0; i < MAX; i++) {
data.addSeries(generateSeries("Series " + (i + 1)));
}
return data;
}
private static XYSeries generateSeries(String key) {
XYSeries series = new XYSeries(key);
for (int i = 0; i < 16; i++) {
series.add(RND.nextGaussian(), RND.nextGaussian());
}
return series;
}
}
私自身の質問に答える:
ちょっとしたハックを使用して、軸を更新することができました。
mainPlot.getDomainAxis().setAutoRange(false);
mainPlot.getDomainAxis().setAutoRange(true);
それはいいことではありませんが、うまくいきます。それにもかかわらず、誰かがより良い解決策を投稿できたらいいのにと思います...
動作しない非カスタム データ セットを使用するコードを次に示します。それを実行してから、クリックという大きなボタンを複数回クリックして、いくつかのシリーズを非表示にしてください。ドメイン軸は再スケーリングされません。
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Random;
import javax.swing.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleEdge;
public class Runner {
private static Random rand = new Random();
public static void main(String[] args) {
XYSeriesCollection data = new XYSeriesCollection();
int max = rand.nextInt(2) + 2;
for (int i = 0; i < max; i++) {
data.addSeries(generateSeries("Series" + (i + 1)));
}
final XYItemRenderer renderer1 = new StandardXYItemRenderer();
final XYPlot plot1 = new XYPlot(data, null, new DateAxis("Dates"), renderer1);
data = new XYSeriesCollection();
for (int i = 0; i < max; i++) {
data.addSeries(generateSeries("Series" + (i + 1)));
}
final XYPlot plot2 = new XYPlot(data, null, new NumberAxis("Numbers"), renderer1);
final CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain"));
plot.setGap(10.0);
// add the subplots...
plot.add(plot1, 1);
plot.add(plot2, 1);
plot.setOrientation(PlotOrientation.VERTICAL);
// return a new chart containing the overlaid plot...
final JFreeChart chart = new JFreeChart("CombinedDomainXYPlot Demo",
JFreeChart.DEFAULT_TITLE_FONT, plot, true);
chart.getLegend().setPosition(RectangleEdge.RIGHT);
chart.addChangeListener(new ChartChangeListener() {
boolean changed = false;
@Override
public void chartChanged(ChartChangeEvent event) {
if (!changed) {
} else {
changed = false;
}
}
});
ChartPanel panel = new ChartPanel(chart);
JPanel panel2 = new JPanel(new BorderLayout(0, 10));
panel2.add(panel, BorderLayout.CENTER);
JButton b = new JButton("Click");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CombinedDomainXYPlot plot = (CombinedDomainXYPlot) chart.getXYPlot();
List l = plot.getSubplots();
int index = rand.nextInt(plot1.getSeriesCount() + plot2.getSeriesCount());
boolean b = renderer1.isSeriesVisible(index);
renderer1.setSeriesVisible(index, false);
}
});
panel2.add(b, BorderLayout.NORTH);
panel2.setVisible(true);
JFrame frame = new JFrame("dsadsa");
frame.add(panel2);
frame.setSize(800, 600);
frame.setVisible(true);
}
private static XYSeries generateSeries(String key) {
XYSeries series = new XYSeries(key);
int points = 15;
double val = 0.0;
double x = 0.0;
for (int i = 0; i < points; i++) {
val += rand.nextDouble() * 6 - 3;
x += rand.nextDouble() * 4;
series.add(x, val);
}
return series;
}
}