JFreeChart: Add and sync a srollbar when zooming a chart (Eclipse plugin / SWT)

不问归期 提交于 2019-12-20 05:35:18

问题


I am using JFreeChart library to plot something in an Eclipse view and currently my code for view initialization looks as follows:

@Override
public void createPartControl(Composite parent)
{
    JFreeChart chart = null;

    // Created via different object     
    chart = graph.createLineChart("Test Graph", "x", "y");

    ChartComposite frame = new ChartComposite(parent, SWT.NONE, chart, true);
    frame.setRangeZoomable(false);      
    parent.layout(true);
}

I wanted to add scrolling to my graph when the user zooms in, but so far all the examples that I found (in the demo package, here, and other sources) are based on Swing dealing with JPanes and ChartPanels.

How can I achieve the same in the createPartControl() function of my view where I have only a Composite. Is it possible to do it in SWT only or should I mix (need to figure out how) SWT with SWING or AWT?

Thank you


回答1:


You might look at SlidingXYDataset, mentioned here, or the paging approach shown here.




回答2:


In addition to the accepted answer I'd like to post an answer myself, because I ran into a couple of issues regarding to SlidingXYDataset:

  1. The implementation allows to specify the number of points in the dataset that can be shown at any given time and that is OK for most use cases. But in the case where the data points are sparsed very uniformly in the dataset sliding thorugh data will cause the domain axis to change its range.
    For example if the window size is 5 datapoints and first 5 are 2 units appart and the next 5 are 20 units appart the X axis visible range size will change when your are sliding.
    So you can see what the behaviour will look like when all the points are ploted at arbitrary locations. This may or may not be a desired behaviour. In my case I needed to have a fixed visible range of the X axis (for example 200 units) and to keep it as such all the time.

  2. For some reason I was not able to create a SlidingXYDataset by giving it an empty XYSeriesCollection/TimeSeriesCollection. I needed to start with an empty dataset and update it in real time and I had to add useless data to start with. But that's maybe because I was doing something wrong.


Having said that above, there might be workarounds for it, but I went and implemented the zooming and scrollbar in a different than the accepted answer's way.

Also this example shows how to sync the slider when user performs a zoom action on the graph.


First: you need to create an XYLineChart and set the desired range (The example is elaborated for X axis only, but can be applied for Y axis as well)

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


Second: you need to put both the chart and a scroll bar inside the parent layout. In SWT you can do this for example through the user of 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);

Now every time you move the slider, you need to capture that event and change the chart's domain range with the to methods according to you slider data:

  domainAxis.setLowerBound(minimum visible);
  domainAxis.setUpperBound(maximum visible);


Third: Finaly you need to override the zoom method of the ChartComposite either by extending this object or right above when you create a new one

@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 */);
}

Hope this implementation can find it's use in other people's use cases.



来源:https://stackoverflow.com/questions/8361854/jfreechart-add-and-sync-a-srollbar-when-zooming-a-chart-eclipse-plugin-swt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!