JFreeChart 的放大和缩小功能的异常行为?
Abnormal Behaviour of the Zoom In and Zoom Out Functionality of the JFreeChart?
我观察到 "Zoom-In" 和 "Zoom-out" 的功能实现与 expected.Like 完全不同,例如当我执行一个步骤 "Zoom-out" 然后再执行一次时"Zoom-In" 后退一步。我又看不到原图了。
我没有看到 JFreechart 的 "Zoom-In" 和 "Zoom-out" 功能同步。
public class ChartPanelDemo {
private static final String title = "Historical Data Graph";
private ChartPanel chartPanel = createChart();
private JButton ZoomX;
private JButton ZoomY;
private JButton Zoom;
private JButton ZoomXOut;
private JButton ZoomYOut;
private JButton ZoomOut;
private JButton originalGraph;
private JButton xscaleInc;
private JButton xscaleDec;
private NumberAxis domainAxis;
private NumberAxis rangeAxis;
private int UNITS = 1;
private static final int COUNT = 100;
private JPanel panel;
private double[][] sizeFr = { { TableLayout.FILL }, { TableLayout.FILL } };
public ChartPanelDemo() {
JFrame f = new JFrame(title);
panel = new JPanel();
f.setTitle(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout(0, 5));
f.add(chartPanel, BorderLayout.CENTER);
chartPanel.setMouseWheelEnabled(true);
// chartPanel.setHorizontalAxisTrace(true);
// chartPanel.setVerticalAxisTrace(true);
chartPanel.setZoomInFactor(0.9);
chartPanel.setZoomOutFactor(0.9);
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(createTrace());
panel.add(createDate());
panel.add(createZoom());
panel.add(createZoomOutX());
panel.add(createZoomOutY());
panel.add(createZoomOut());
panel.add(toOriginalGraph());
panel.add(AutoScaleDecXaxis());
//panel.add(AutoScaleDecXaxis());
f.add(panel, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JSpinner AutoScaleDecXaxis() {
final JSpinner spinner = new JSpinner(
new SpinnerNumberModel(UNITS, 1, COUNT, 1));
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSpinner s = (JSpinner) e.getSource();
Number n = (Number) s.getValue();
domainAxis.setTickUnit(new NumberTickUnit(n.intValue()));
}
});
return spinner;
}
private JButton toOriginalGraph() {
originalGraph = new JButton(new AbstractAction("RestoreGraph") {
@Override
public void actionPerformed(ActionEvent e) {
chartPanel.restoreAutoBounds();
}
});
return originalGraph;
}
private JButton createZoomOut() {
ZoomOut = new JButton(new AbstractAction("ZoomOut") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomOut.setActionCommand(chartPanel.ZOOM_OUT_BOTH_COMMAND);
ZoomOut.addActionListener(chartPanel);
}
});
return ZoomOut;
}
private JButton createZoomOutY() {
ZoomYOut = new JButton(new AbstractAction("ZoomOutY") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomYOut.setActionCommand(chartPanel.ZOOM_OUT_RANGE_COMMAND);
ZoomYOut.addActionListener(chartPanel);
}
});
return ZoomYOut;
}
private JButton createZoomOutX() {
ZoomXOut = new JButton(new AbstractAction("ZoomOutX") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomXOut.setActionCommand(chartPanel.ZOOM_OUT_DOMAIN_COMMAND);
ZoomXOut.addActionListener(chartPanel);
}
});
return ZoomXOut;
}
private JButton createTrace() {
ZoomX = new JButton(new AbstractAction("ZoomInX") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomX.setActionCommand(chartPanel.ZOOM_IN_DOMAIN_COMMAND);
ZoomX.addActionListener(chartPanel);
// chartPanel.restoreAutoBounds();
}
});
return ZoomX;
}
private JButton createDate() {
ZoomY = new JButton(new AbstractAction("ZoomInY") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomY.setActionCommand(chartPanel.ZOOM_IN_RANGE_COMMAND);
ZoomY.addActionListener(chartPanel);
}
});
return ZoomY;
}
private JButton createZoom() {
Zoom = new JButton(new AbstractAction("Zoom") {
@Override
public void actionPerformed(ActionEvent e) {
Zoom.setActionCommand(chartPanel.ZOOM_IN_BOTH_COMMAND);
Zoom.addActionListener(chartPanel);
}
});
return Zoom;
}
private ChartPanel createChart() {
XYDataset roiData = createDataset();
JFreeChart chart = createChart(roiData);
chart.setBackgroundPaint(new Color(0xBBBBDD));
XYPlot plot = chart.getXYPlot();
XYSplineRenderer r = new XYSplineRenderer(20);
plot.setRenderer(r);
r.setBaseShapesVisible(true);
rangeAxis = (NumberAxis) plot.getRangeAxis();
domainAxis = (NumberAxis) plot.getDomainAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
return new ChartPanel(chart);
}
private JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createXYLineChart("Historical Data", // chart
// title
"X", // x axis label
"Y", // y axis label
dataset, // data
PlotOrientation.VERTICAL, true, // include legend
true, // tooltips
false // urls
);
return chart;
}
private XYDataset createDataset() {
XYSeries series1 = new XYSeries("First");
series1.add(1.0, 1.0);
series1.add(2.0, 4.0);
series1.add(3.0, 3.0);
series1.add(4.0, 5.0);
series1.add(5.0, 5.0);
series1.add(6.0, 7.0);
series1.add(7.0, 7.0);
series1.add(8.0, 8.0);
XYSeries series2 = new XYSeries("Second");
series2.add(1.0, 5.0);
series2.add(2.0, 7.0);
series2.add(3.0, 6.0);
series2.add(4.0, 8.0);
series2.add(5.0, 4.0);
series2.add(6.0, 4.0);
series2.add(7.0, 2.0);
series2.add(8.0, 1.0);
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series1);
dataset.addSeries(series2);
return dataset;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ChartPanelDemo cpd = new ChartPanelDemo();
}
});
}
}
问题 2:在 ZoomInX 上点击两次后
再次点击两次 ZoomOutX(这是原始图表)
但是在两次点击 ZoomInX 之后,我再次看到了不同的图表,而不是这个问题中应该是的第一张图片。
您的示例似乎混合了 建议的两种方法,从您自己的 actionPerformed()
实现中调用图表面板的处理程序。虽然图表面板处理程序可重用,但它们不可重入。相反,直接使用图表面板的实现。下面的示例着重于放大和缩小域的两个按钮:
toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
…
private JButton createButton(String name, String command) {
final JButton b = new JButton(name);
b.setActionCommand(command);
b.addActionListener(chartPanel);
return b;
}
点击后放大 X:
点击后 缩小 X:
这个完整的示例重构了 createButton()
方法以使用可用的缩放处理程序并使用 JToolBar
.
进行了说明
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.Year;
import org.jfree.data.xy.XYDataset;
import static org.jfree.chart.ChartPanel.*;
/** @see */
public class ZoomDemo {
private static final String TITLE = "Return On Investment";
private final ChartPanel chartPanel = createChart();
public ZoomDemo() {
JFrame f = new JFrame(TITLE);
f.setTitle(TITLE);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout(0, 5));
f.add(chartPanel, BorderLayout.CENTER);
chartPanel.setMouseWheelEnabled(true);
JPanel panel = new JPanel();
JToolBar toolBar = new JToolBar();
toolBar.add(createButton("Zoom In", ZOOM_IN_BOTH_COMMAND));
toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND));
toolBar.add(createButton("Zoom Out", ZOOM_OUT_BOTH_COMMAND));
toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
toolBar.add(createButton("Zoom Out Y", ZOOM_OUT_RANGE_COMMAND));
toolBar.add(createButton("Reset", ZOOM_RESET_BOTH_COMMAND));
toolBar.add(createButton("Reset X", ZOOM_RESET_DOMAIN_COMMAND));
toolBar.add(createButton("Reset Y", ZOOM_RESET_RANGE_COMMAND));
panel.add(toolBar);
f.add(panel, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JButton createButton(String name, String command) {
final JButton b = new JButton(name);
b.setActionCommand(command);
b.addActionListener(chartPanel);
return b;
}
private ChartPanel createChart() {
XYDataset roiData = createDataset();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
TITLE, "Date", "Value", roiData, true, true, false);
XYPlot plot = chart.getXYPlot();
XYLineAndShapeRenderer renderer =
(XYLineAndShapeRenderer) plot.getRenderer();
renderer.setBaseShapesVisible(true);
NumberFormat currency = NumberFormat.getCurrencyInstance();
currency.setMaximumFractionDigits(0);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setNumberFormatOverride(currency);
return new ChartPanel(chart);
}
private XYDataset createDataset() {
TimeSeriesCollection tsc = new TimeSeriesCollection();
tsc.addSeries(createSeries("Projected", 200));
tsc.addSeries(createSeries("Actual", 100));
return tsc;
}
private TimeSeries createSeries(String name, double scale) {
TimeSeries series = new TimeSeries(name);
for (int i = 0; i < 6; i++) {
series.add(new Year(2016 + i), Math.pow(2, i) * scale);
}
return series;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ZoomDemo cpd = new ZoomDemo();
}
});
}
}
我观察到 "Zoom-In" 和 "Zoom-out" 的功能实现与 expected.Like 完全不同,例如当我执行一个步骤 "Zoom-out" 然后再执行一次时"Zoom-In" 后退一步。我又看不到原图了。
我没有看到 JFreechart 的 "Zoom-In" 和 "Zoom-out" 功能同步。
public class ChartPanelDemo {
private static final String title = "Historical Data Graph";
private ChartPanel chartPanel = createChart();
private JButton ZoomX;
private JButton ZoomY;
private JButton Zoom;
private JButton ZoomXOut;
private JButton ZoomYOut;
private JButton ZoomOut;
private JButton originalGraph;
private JButton xscaleInc;
private JButton xscaleDec;
private NumberAxis domainAxis;
private NumberAxis rangeAxis;
private int UNITS = 1;
private static final int COUNT = 100;
private JPanel panel;
private double[][] sizeFr = { { TableLayout.FILL }, { TableLayout.FILL } };
public ChartPanelDemo() {
JFrame f = new JFrame(title);
panel = new JPanel();
f.setTitle(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout(0, 5));
f.add(chartPanel, BorderLayout.CENTER);
chartPanel.setMouseWheelEnabled(true);
// chartPanel.setHorizontalAxisTrace(true);
// chartPanel.setVerticalAxisTrace(true);
chartPanel.setZoomInFactor(0.9);
chartPanel.setZoomOutFactor(0.9);
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.add(createTrace());
panel.add(createDate());
panel.add(createZoom());
panel.add(createZoomOutX());
panel.add(createZoomOutY());
panel.add(createZoomOut());
panel.add(toOriginalGraph());
panel.add(AutoScaleDecXaxis());
//panel.add(AutoScaleDecXaxis());
f.add(panel, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JSpinner AutoScaleDecXaxis() {
final JSpinner spinner = new JSpinner(
new SpinnerNumberModel(UNITS, 1, COUNT, 1));
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSpinner s = (JSpinner) e.getSource();
Number n = (Number) s.getValue();
domainAxis.setTickUnit(new NumberTickUnit(n.intValue()));
}
});
return spinner;
}
private JButton toOriginalGraph() {
originalGraph = new JButton(new AbstractAction("RestoreGraph") {
@Override
public void actionPerformed(ActionEvent e) {
chartPanel.restoreAutoBounds();
}
});
return originalGraph;
}
private JButton createZoomOut() {
ZoomOut = new JButton(new AbstractAction("ZoomOut") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomOut.setActionCommand(chartPanel.ZOOM_OUT_BOTH_COMMAND);
ZoomOut.addActionListener(chartPanel);
}
});
return ZoomOut;
}
private JButton createZoomOutY() {
ZoomYOut = new JButton(new AbstractAction("ZoomOutY") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomYOut.setActionCommand(chartPanel.ZOOM_OUT_RANGE_COMMAND);
ZoomYOut.addActionListener(chartPanel);
}
});
return ZoomYOut;
}
private JButton createZoomOutX() {
ZoomXOut = new JButton(new AbstractAction("ZoomOutX") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomXOut.setActionCommand(chartPanel.ZOOM_OUT_DOMAIN_COMMAND);
ZoomXOut.addActionListener(chartPanel);
}
});
return ZoomXOut;
}
private JButton createTrace() {
ZoomX = new JButton(new AbstractAction("ZoomInX") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomX.setActionCommand(chartPanel.ZOOM_IN_DOMAIN_COMMAND);
ZoomX.addActionListener(chartPanel);
// chartPanel.restoreAutoBounds();
}
});
return ZoomX;
}
private JButton createDate() {
ZoomY = new JButton(new AbstractAction("ZoomInY") {
@Override
public void actionPerformed(ActionEvent e) {
ZoomY.setActionCommand(chartPanel.ZOOM_IN_RANGE_COMMAND);
ZoomY.addActionListener(chartPanel);
}
});
return ZoomY;
}
private JButton createZoom() {
Zoom = new JButton(new AbstractAction("Zoom") {
@Override
public void actionPerformed(ActionEvent e) {
Zoom.setActionCommand(chartPanel.ZOOM_IN_BOTH_COMMAND);
Zoom.addActionListener(chartPanel);
}
});
return Zoom;
}
private ChartPanel createChart() {
XYDataset roiData = createDataset();
JFreeChart chart = createChart(roiData);
chart.setBackgroundPaint(new Color(0xBBBBDD));
XYPlot plot = chart.getXYPlot();
XYSplineRenderer r = new XYSplineRenderer(20);
plot.setRenderer(r);
r.setBaseShapesVisible(true);
rangeAxis = (NumberAxis) plot.getRangeAxis();
domainAxis = (NumberAxis) plot.getDomainAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
return new ChartPanel(chart);
}
private JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createXYLineChart("Historical Data", // chart
// title
"X", // x axis label
"Y", // y axis label
dataset, // data
PlotOrientation.VERTICAL, true, // include legend
true, // tooltips
false // urls
);
return chart;
}
private XYDataset createDataset() {
XYSeries series1 = new XYSeries("First");
series1.add(1.0, 1.0);
series1.add(2.0, 4.0);
series1.add(3.0, 3.0);
series1.add(4.0, 5.0);
series1.add(5.0, 5.0);
series1.add(6.0, 7.0);
series1.add(7.0, 7.0);
series1.add(8.0, 8.0);
XYSeries series2 = new XYSeries("Second");
series2.add(1.0, 5.0);
series2.add(2.0, 7.0);
series2.add(3.0, 6.0);
series2.add(4.0, 8.0);
series2.add(5.0, 4.0);
series2.add(6.0, 4.0);
series2.add(7.0, 2.0);
series2.add(8.0, 1.0);
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series1);
dataset.addSeries(series2);
return dataset;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ChartPanelDemo cpd = new ChartPanelDemo();
}
});
}
}
问题 2:在 ZoomInX 上点击两次后
再次点击两次 ZoomOutX(这是原始图表)
但是在两次点击 ZoomInX 之后,我再次看到了不同的图表,而不是这个问题中应该是的第一张图片。
您的示例似乎混合了 actionPerformed()
实现中调用图表面板的处理程序。虽然图表面板处理程序可重用,但它们不可重入。相反,直接使用图表面板的实现。下面的示例着重于放大和缩小域的两个按钮:
toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
…
private JButton createButton(String name, String command) {
final JButton b = new JButton(name);
b.setActionCommand(command);
b.addActionListener(chartPanel);
return b;
}
点击后放大 X:
点击后 缩小 X:
这个完整的示例重构了 createButton()
方法以使用可用的缩放处理程序并使用 JToolBar
.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.Year;
import org.jfree.data.xy.XYDataset;
import static org.jfree.chart.ChartPanel.*;
/** @see */
public class ZoomDemo {
private static final String TITLE = "Return On Investment";
private final ChartPanel chartPanel = createChart();
public ZoomDemo() {
JFrame f = new JFrame(TITLE);
f.setTitle(TITLE);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout(0, 5));
f.add(chartPanel, BorderLayout.CENTER);
chartPanel.setMouseWheelEnabled(true);
JPanel panel = new JPanel();
JToolBar toolBar = new JToolBar();
toolBar.add(createButton("Zoom In", ZOOM_IN_BOTH_COMMAND));
toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND));
toolBar.add(createButton("Zoom Out", ZOOM_OUT_BOTH_COMMAND));
toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
toolBar.add(createButton("Zoom Out Y", ZOOM_OUT_RANGE_COMMAND));
toolBar.add(createButton("Reset", ZOOM_RESET_BOTH_COMMAND));
toolBar.add(createButton("Reset X", ZOOM_RESET_DOMAIN_COMMAND));
toolBar.add(createButton("Reset Y", ZOOM_RESET_RANGE_COMMAND));
panel.add(toolBar);
f.add(panel, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JButton createButton(String name, String command) {
final JButton b = new JButton(name);
b.setActionCommand(command);
b.addActionListener(chartPanel);
return b;
}
private ChartPanel createChart() {
XYDataset roiData = createDataset();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
TITLE, "Date", "Value", roiData, true, true, false);
XYPlot plot = chart.getXYPlot();
XYLineAndShapeRenderer renderer =
(XYLineAndShapeRenderer) plot.getRenderer();
renderer.setBaseShapesVisible(true);
NumberFormat currency = NumberFormat.getCurrencyInstance();
currency.setMaximumFractionDigits(0);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setNumberFormatOverride(currency);
return new ChartPanel(chart);
}
private XYDataset createDataset() {
TimeSeriesCollection tsc = new TimeSeriesCollection();
tsc.addSeries(createSeries("Projected", 200));
tsc.addSeries(createSeries("Actual", 100));
return tsc;
}
private TimeSeries createSeries(String name, double scale) {
TimeSeries series = new TimeSeries(name);
for (int i = 0; i < 6; i++) {
series.add(new Year(2016 + i), Math.pow(2, i) * scale);
}
return series;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ZoomDemo cpd = new ZoomDemo();
}
});
}
}