除了已接受的答案之外,我还想自己发布一个答案,因为我遇到了一些关于SlidingXYDataset
:
该实现允许指定数据集中可以在任何给定时间显示的点数,这对于大多数用例来说都是可以的。但在数据集中数据点稀疏非常均匀的情况下,滑动数据将导致域轴改变其范围。
例如,如果窗口大小为 5 个数据点,前 5 个数据点为 2 个单位,接下来的 5 个数据点为 20 个单位,则滑动时 X 轴可见范围大小将发生变化。
因此,您可以看到当所有点都绘制在任意位置时,行为会是什么样子。
这可能是也可能不是期望的行为。就我而言,我需要 X 轴有一个固定的可见范围(例如 200 个单位)并始终保持这样。
由于某种原因我无法创建SlidingXYDataset
给它一个空的XYSeriesCollection/TimeSeriesCollection
。我需要从一个空数据集开始并实时更新它,并且我必须首先添加无用的数据。但这可能是因为我做错了什么。
话虽如此,可能有解决方法,但我以与接受的答案不同的方式实现了缩放和滚动条。
此示例还展示了当用户在图表上执行缩放操作时如何同步滑块。
首先:您需要创建一个XYLineChart
并设置所需的范围(该示例仅针对 X 轴进行阐述,但也可以应用于 Y 轴)
XYSeries dataset = new XYSeries("my dataset");
XYSeriesCollection datasetCollection = new XYSeriesCollection(dataset);
JFreeChart chart = ChartFactory.createXYLineChart("title",
"x label",
"y label",
datasetCollection,
PlotOrientation.VERTICAL,
true, false, false);
XYPlot plot = chart.getXYPlot();
ValueAxis domainAxis = plot.getDomainAxis();
ValueAxis rangeAxis = plot.getRangeAxis();
domainAxis.setAutoRange(false);
domainAxis.setFixedAutoRange(300); // 300 units visible at anytime on X axis
domainAxis.setLowerBound(0); // start from 0
其次:您需要将图表和滚动条放在父布局中。在 SWT 中,您可以通过 FormLayout 的用户来执行此操作
// Given that composite is the parent Composite
FormLayout layout = new FormLayout();
composite.setLayout(layout);
chartComposite = new ChartComposite(composite, SWT.NONE, chart, true);
Slider slider = new Slider(composite, SWT.NONE);
sldier.setValues(/* depends on your needs */);
// add the slider to the bottom of the form
FormData sliderLayoutData = new FormData();
sliderLayoutData.left = new FormAttachment(0,0);
sliderLayoutData.bottom = new FormAttachment(100,0);
sliderLayoutData.right = new FormAttachment(100,0);
slider.setLayoutData(sliderLayoutData);
// now add the graphComposite to the form above the slider
FormData graphLayoutData = new FormData();
graphLayoutData.left = new FormAttachment(0,0);
graphLayoutData.right = new FormAttachment(100,0);
graphLayoutData.top = new FormAttachment(0,0);
graphLayoutData.bottom = new FormAttachment(slider);
chartComposite.setLayoutData(graphLayoutData);
// refresh the layout
composite.layout(true);
现在,每次移动滑块时,您都需要捕获该事件并根据滑块数据使用 to 方法更改图表的域范围:
domainAxis.setLowerBound(minimum visible);
domainAxis.setUpperBound(maximum visible);
第三:最后,您需要通过扩展此对象或在创建新对象时覆盖 ChartComposite 的缩放方法
@Override
public void zoom(Rectangle selection)
{
XYPlot plot = (XYPlot) getChart().getPlot();
Rectangle2D plotArea = new Rectangle2D.Double( getScreenDataArea().x,
getScreenDataArea().y,
getScreenDataArea().width,
getScreenDataArea().height);
float x1 = (float) plot.getDomainAxis().
java2DToValue(selection.x,
plotArea,
plot.getDomainAxisEdge());
float x2 = (float) plot.getDomainAxis().
java2DToValue(selection.x + selection.width,
plotArea,
plot.getDomainAxisEdge());
// x1 and x2 will have the points transalted into chart coordinates
// of the selection the user made for zooming the X axis
// you can adjust your chart to show only the selected (zoomed)
// information as such
domainAxis.setLowerBound(x1);
domainAxis.setUpperBound(x2);
// and now adjust the slider information so it's
// synced to your graph's current view
sldier.setValues(/* depends on your needs */);
}
希望这个实现可以在其他人的用例中找到它的用途。