CombinedDomainXYPlot не перемасштабирует доменную ось
Когда я скрою ряд серий из диаграммы, использующей CombinedDomainXYPlot, все оси диапазона автоматически масштабируются. Как бы то ни было, ось домена не масштабируется. Есть ли способ ручного обновления масштабирования, или, возможно, есть параметр, который мне не хватает, чтобы включить автоматическое масштабирование оси домена в этой настройке?
- Как рассчитать количество строк (и столбцов в каждой строке), которые текст принимает в JTextArea?
- Как добавить гиперссылку в JLabel
- Как нарисовать в JPanel? (Swing / графика Java)
- Программа не получает доступ к методу paintComponent () расширенного classа JPanel
- JTable, как работаетEditor
- Добавить новую строку в конец JtextArea
- Создайте шахматную доску с JPanel
- Как нарисовать изображение над другим изображением?
CombinedDomainXYPlot
устанавливает объединенный максимальный Range
для своей общей оси домена в getDataRange()
. Это необходимо для обеспечения совместного использования оси. Изменение видимости серии не влияет на ось общего домена; изменение Dataset
обновляет ось общего домена с помощью метода configure()
. В любом случае осей диапазона подзаголов можно обновлять отдельно.
В приведенном ниже примере можно обновить подзаголовок или изменить видимость серии независимо. Перерыв configure()
чтобы увидеть эффект. Ваше предложение переключить setAutoRange ()
можно заменить одним вызовом configure()
; но эффект должен быть равен нулю, так как данные и его объединенный максимальный Range
не изменяются.
mainPlot.getDomainAxis().configure();
Чтобы автоматически обновлять общую доменную ось, используйте addSeries()
или removeSeries()
вместо setSeriesVisible()
.
В стороне, не пренебрегайте начальными streamами и 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 org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; /** * @see http://stackoverflow.com/q/11870416/230513 */ public class CombinedPlot { private static final int MAX = 3; private static final Random rand = new Random(); public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { init(); } }); } private static void init() { XYItemRenderer renderer = new StandardXYItemRenderer(); 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.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); 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(rand.nextGaussian(), rand.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; } }