我正在尝试创建一个烛台图,用户可以像这样TradingView chart那样进行缩放和平移。
// Domain axis
DateAxis dateAxis = new DateAxis();
// Range axis
NumberAxis priceAxis = new NumberAxis("Price");
priceAxis.setRangeType(RangeType.POSITIVE);
priceAxis.setAutoRange(true);
priceAxis.setAutoRangeIncludesZero(false);
// Plot
CandlestickRenderer renderer = new CandlestickRenderer();
XYPlot plot = new XYPlot(mPriceDataSet, dateAxis, priceAxis, renderer);
plot.setDomainPannable(true);
plot.setRangePannable(false);
// Chart
mChart = new JFreeChart("Price History", plot);
其中mPriceDataSet
是我的数据集,类型为DefaultOHLCDataset
。这就是我创建ChartPanel
的方式:
ChartPanel chartPanel = new ChartPanel(mChart);
chartPanel.setMouseZoomable(true);
chartPanel.setRangeZoomable(false);
chartPanel.setMouseWheelEnabled(true);
行为:呈现图表时,一切正常,但是,当用户缩放和/或平移视口时,范围轴不会缩放,而是显示第一个范围。
所需的行为:在缩放范围内,轴应动态设置其范围。就像TrandingView charts。
我已经基于您的Sample8创建了MCVE。要重现该问题,只需运行该应用程序并使用鼠标拖动在12:5选择蜡烛。如您所见,缩放/选择后的图表不会自动调整范围,用户必须使用上下文菜单手动进行调整。
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.data.time.Minute;
import org.jfree.data.time.ohlc.OHLCSeries;
import org.jfree.data.time.ohlc.OHLCSeriesCollection;
import javax.swing.*;
import java.awt.*;
import java.text.SimpleDateFormat;
public class AutoRangeTestApp {
private final ChartPanel chartPanel;
private final OHLCSeriesCollection seriesCollection = new OHLCSeriesCollection();
public AutoRangeTestApp() {
JFreeChart chart = ChartFactory.createCandlestickChart(
"Sample8", "Time", "Price", seriesCollection, true);
chart.getXYPlot().setOrientation(PlotOrientation.VERTICAL);
chart.getXYPlot().setDomainPannable(true);
CandlestickRenderer r = (CandlestickRenderer) chart.getXYPlot().getRenderer();
r.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_SMALLEST);
// Y-axis
NumberAxis numberAxis = (NumberAxis) chart.getXYPlot().getRangeAxis();
numberAxis.setAutoRangeIncludesZero(false);
numberAxis.setAutoRangeStickyZero(false);
// X-axis
DateAxis dateAxis = (DateAxis) chart.getXYPlot().getDomainAxis();
dateAxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
dateAxis.setTickUnit(new DateTickUnit(DateTickUnitType.MINUTE, 1));
dateAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
// chartPanel
chartPanel = new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 400);
}
};
chartPanel.setMouseWheelEnabled(true);
chartPanel.setMouseZoomable(true);
chartPanel.setRangeZoomable(false);
// series
addSeries1();
}
private void addSeries1() {
OHLCSeries series = new OHLCSeries("One");
series.add(new Minute(0, 12, 1, 1, 2014), 97.23D, 98.47D, 97.15D, 97.43);
series.add(new Minute(1, 12, 1, 1, 2014), 96.47D, 98.81D, 96.27D, 97.49);
series.add(new Minute(2, 12, 1, 1, 2014), 95.88D, 96.87D, 96.11D, 96.75);
series.add(new Minute(3, 12, 1, 1, 2014), 96.05D, 96.94D, 95.89D, 96.59);
series.add(new Minute(4, 12, 1, 1, 2014), 95.92D, 97.00D, 95.69D, 96.92);
series.add(new Minute(5, 12, 1, 1, 2014), 96.34D, 96.71D, 95.68D, 96.70);
series.add(new Minute(6, 12, 1, 1, 2014), 96.65D, 96.87D, 94.91D, 96.38);
series.add(new Minute(7, 12, 1, 1, 2014), 97.75D, 98.20D, 96.90D, 97.24);
series.add(new Minute(8, 12, 1, 1, 2014), 97.72D, 98.47D, 97.35D, 97.64);
series.add(new Minute(9, 12, 1, 1, 2014), 98.30D, 98.77D, 97.56D, 97.99);
seriesCollection.addSeries(series);
}
public ChartPanel getChartPanel() {
return chartPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
AutoRangeTestApp app = new AutoRangeTestApp();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(app.getChartPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}