com.keba.tracecompass.jitter.ui.SystemJitterView.java Source code

Java tutorial

Introduction

Here is the source code for com.keba.tracecompass.jitter.ui.SystemJitterView.java

Source

/*******************************************************************************
 * Copyright (c) 2015 
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   orangehero - Initial API and implementation
 *******************************************************************************/

package com.keba.tracecompass.jitter.ui;

import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler;
import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.views.TmfView;
import org.eclipse.tracecompass.tmf.ui.views.filter.FilterDialog;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.swtchart.Chart;
import org.swtchart.ISeries;
import org.swtchart.ISeries.SeriesType;
import org.swtchart.Range;

public class SystemJitterView extends TmfView {

    private static final String PLUGIN_ID = "com.keba.tracecompass.jitter.ui";
    private static final String VIEW_ID = "com.keba.tracecompass.jitter.ui.view";

    private static final Image ADD_IMAGE = AbstractUIPlugin
            .imageDescriptorFromPlugin(PLUGIN_ID, "/icons/add_button.gif").createImage();
    private static final Image DELETE_IMAGE = AbstractUIPlugin
            .imageDescriptorFromPlugin(PLUGIN_ID, "/icons/delete_button.gif").createImage();
    private static final Image EXPORT_IMAGE = AbstractUIPlugin
            .imageDescriptorFromPlugin(PLUGIN_ID, "/icons/export_button.gif").createImage();
    private static final Image IMPORT_IMAGE = AbstractUIPlugin
            .imageDescriptorFromPlugin(PLUGIN_ID, "/icons/import_button.gif").createImage();

    private static final String Y_AXIS_TITLE = "Frequency";
    private static final String X_AXIS_TITLE = "Jitter";
    private static final int TAB_INTERVAL_INDEX = 1;
    private static final int TAB_FILTER_INDEX = 2;

    private Shell fShell;
    private Chart fChart;
    private TreeViewer fIntervalTreeViewer;
    private TableViewer fIntervalFilterTableViewer;
    private CTabFolder fTabs;
    private ITmfTrace fCurrentTrace;
    private JitterRootNode fjitterNodes;
    private TmfSignalThrottler fThrottler;

    private Action addFilterAction;
    private Action deleteFilterAction;
    private Action importFilterAction;
    private Action exportFilterAction;

    private List<IntervalFilterSetting> fIntervalSettings;

    private class TmfChartTimeStampFormat extends SimpleDateFormat {
        private static final long serialVersionUID = 1L;

        @Override
        public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
            Long time = date.getTime();
            toAppendTo.append(time.toString());
            return toAppendTo;
        }
    }

    private class AddFilterAction extends Action {
        @Override
        public void run() {
            if (fTabs.getSelectionIndex() != TAB_FILTER_INDEX) {
                return;
            }
            fIntervalSettings.add(new IntervalFilterSetting());
            fIntervalFilterTableViewer.setInput(fIntervalSettings.toArray());
        }
    };

    private class DeleteFilterAction extends Action {
        @Override
        public void run() {
            if (fTabs.getSelectionIndex() != TAB_FILTER_INDEX) {
                return;
            }
            int selectionIndex = 0;
            StructuredSelection sel = (StructuredSelection) fIntervalFilterTableViewer.getSelection();
            Iterator<?> it = sel.iterator();
            while (it.hasNext()) {
                IntervalFilterSetting ifs = (IntervalFilterSetting) it.next();
                selectionIndex = fIntervalSettings.indexOf(ifs);
                fIntervalSettings.remove(ifs);
            }
            fIntervalFilterTableViewer.setInput(fIntervalSettings.toArray());
            int iValSettingsSize = fIntervalSettings.size();
            if (iValSettingsSize > 0) {
                if (selectionIndex >= iValSettingsSize) {
                    selectionIndex = iValSettingsSize - 1;
                }
                fIntervalFilterTableViewer.setSelection(
                        new StructuredSelection(fIntervalFilterTableViewer.getElementAt(selectionIndex)), true);
            }
        }
    };

    private class ImportFilterAction extends Action {
        @Override
        public void run() {
            FileDialog fileDialog = new FileDialog(fShell, SWT.OPEN);
            fileDialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$
            String pathName = fileDialog.open();
            if (pathName != null) {
                IntervalFilterSetting[] ivalSettings = IntervalFilterXML.load(pathName);
                fIntervalSettings.clear();
                for (IntervalFilterSetting e : ivalSettings) {
                    fIntervalSettings.add(e);
                }
                fIntervalFilterTableViewer.setInput(fIntervalSettings.toArray());
            }
        }
    };

    private class ExportFilterAction extends Action {
        @Override
        public void run() {
            FileDialog fileDialog = new FileDialog(fShell, SWT.SAVE);
            fileDialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$
            fileDialog.setOverwrite(true);
            String pathName = fileDialog.open();
            if (pathName != null) {
                IntervalFilterXML.save(pathName, fIntervalSettings.toArray(new IntervalFilterSetting[0]));//fColorSettings.toArray(new ColorSetting[0]));
            }
        }
    };

    private class SetEventFilterListener implements Listener {
        @Override
        public void handleEvent(Event event) {
            Point pt = new Point(event.x, event.y);
            TableItem item = fIntervalFilterTableViewer.getTable().getItem(pt);
            if (item != null) {
                Object o = item.getData();
                if (o instanceof IntervalFilterSetting) {
                    IntervalFilterSetting ival = (IntervalFilterSetting) o;
                    int index = TAB_INTERVAL_INDEX;
                    Rectangle rect1 = item.getBounds(index);
                    if (rect1.contains(pt)) {
                        FilterDialog dialog = new FilterDialog(fShell);
                        dialog.setFilter(ival.beginFilter);
                        dialog.open();
                        if (dialog.getReturnCode() == Window.OK) {
                            ival.beginFilter = dialog.getFilter();
                            if (ival.beginFilter != null) {
                                item.setText(index, ival.beginFilter.toString());
                            }
                        }
                    }
                    Rectangle rect2 = item.getBounds(TAB_FILTER_INDEX);
                    if (rect2.contains(pt)) {
                        FilterDialog dialog = new FilterDialog(fShell);
                        dialog.setFilter(ival.endFilter);
                        dialog.open();
                        if (dialog.getReturnCode() == Window.OK) {
                            ival.endFilter = dialog.getFilter();
                            if (ival.endFilter != null) {
                                item.setText(TAB_FILTER_INDEX, ival.endFilter.toString());
                            }
                        }
                    }
                }
            }
        }
    }

    public SystemJitterView(String viewName) {
        super(viewName);
        fThrottler = new TmfSignalThrottler(this, 200);
        fIntervalSettings = new ArrayList<>();
    }

    public SystemJitterView() {
        super(VIEW_ID);
        fThrottler = new TmfSignalThrottler(this, 200);
        fIntervalSettings = new ArrayList<>();
    }

    /* create the tree of intervals. */
    private void createIntervalTreeViewer() {
        fIntervalTreeViewer = new TreeViewer(fTabs, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
        fIntervalTreeViewer.setContentProvider(new SystemJitterTreeContentProvider());
        fIntervalTreeViewer.getTree().setHeaderVisible(true);
        fIntervalTreeViewer.setUseHashlookup(true);
        fIntervalTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(DoubleClickEvent event) {
                IStructuredSelection sel = (IStructuredSelection) event.getSelection();
                Object o = sel.getFirstElement();
                if (o instanceof JitterIntervalNode) {
                    JitterIntervalNode jin = (JitterIntervalNode) o;
                    TmfSelectionRangeUpdatedSignal signal = new TmfSelectionRangeUpdatedSignal(this,
                            jin.getStartTs(), jin.getEndTs());
                    fThrottler.queue(signal);
                }
            }
        });

        final TreeViewerColumn treeColumn1 = new TreeViewerColumn(fIntervalTreeViewer, 0);
        treeColumn1.getColumn().setText("Name");
        treeColumn1.getColumn().setWidth(200);
        treeColumn1.getColumn().setToolTipText("Tooltip");
        treeColumn1.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element instanceof JitterIntervalList) {
                    return ((JitterIntervalList) element).getName();
                } else if (element instanceof JitterIntervalNodeList) {
                    return Double.toString(((JitterIntervalNodeList) element).getJitter());
                }
                return "";
            }
        });

        final TreeViewerColumn treeColumn2 = new TreeViewerColumn(fIntervalTreeViewer, 0);
        treeColumn2.getColumn().setText("Start Timestamp");
        treeColumn2.getColumn().setWidth(100);
        treeColumn2.getColumn().setToolTipText("Tooltip");
        treeColumn2.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element instanceof JitterIntervalNode) {
                    return ((JitterIntervalNode) element).getStartTs().toString();
                }
                return "";
            }
        });

        final TreeViewerColumn treeColumn3 = new TreeViewerColumn(fIntervalTreeViewer, 0);
        treeColumn3.getColumn().setText("End Timestamp");
        treeColumn3.getColumn().setWidth(100);
        treeColumn3.getColumn().setToolTipText("Tooltip");
        treeColumn3.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element instanceof JitterIntervalNode) {
                    return ((JitterIntervalNode) element).getEndTs().toString();
                }
                return "";
            }
        });
    }

    private void createIntervalFilterTable() {
        fIntervalFilterTableViewer = new TableViewer(fTabs,
                SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
        fIntervalFilterTableViewer.setContentProvider(ArrayContentProvider.getInstance());
        fIntervalFilterTableViewer.getTable().setHeaderVisible(true);

        TableViewerFocusCellManager tvfcm = new TableViewerFocusCellManager(fIntervalFilterTableViewer,
                new FocusCellOwnerDrawHighlighter(fIntervalFilterTableViewer));
        TableViewerEditor.create(fIntervalFilterTableViewer, tvfcm,
                new ColumnViewerEditorActivationStrategy(fIntervalFilterTableViewer) {
                    protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
                        return event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION;
                    }
                }, ColumnViewerEditor.DEFAULT);

        final String[] columnProperties = { "Name", "1st event filter", "2nd event filter" };
        fIntervalFilterTableViewer.setColumnProperties(columnProperties);

        CellEditor[] editors = { new TextCellEditor(fIntervalFilterTableViewer.getTable()), null, null };
        fIntervalFilterTableViewer.setCellEditors(editors);
        fIntervalFilterTableViewer.setCellModifier(new ICellModifier() {

            @Override
            public void modify(Object element, String property, Object value) {
                if (element != null && element instanceof TableItem) {
                    IntervalFilterSetting ival = (IntervalFilterSetting) ((TableItem) element).getData();
                    ival.name = (String) value;
                }
                fIntervalFilterTableViewer.refresh();
            }

            @Override
            public Object getValue(Object element, String property) {
                if (element != null && element instanceof IntervalFilterSetting) {
                    IntervalFilterSetting ival = (IntervalFilterSetting) element;
                    return ival.name;
                }
                return "";
            }

            @Override
            public boolean canModify(Object element, String property) {
                if (property.equals(columnProperties[0]))
                    return true;
                return false;
            }
        });

        fIntervalFilterTableViewer.getTable().addListener(SWT.MouseDoubleClick, new SetEventFilterListener());

        TableViewerColumn colName = new TableViewerColumn(fIntervalFilterTableViewer, SWT.NONE);
        colName.getColumn().setWidth(200);
        colName.getColumn().setText(columnProperties[0]);
        colName.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element != null && element instanceof IntervalFilterSetting) {
                    IntervalFilterSetting ival = (IntervalFilterSetting) element;
                    return (ival.name == null || ival.name.equals("")) ? "Set name ..." : ival.name;
                }

                return "";
            }
        });

        TableViewerColumn colBeginFilter = new TableViewerColumn(fIntervalFilterTableViewer, SWT.NONE);
        colBeginFilter.getColumn().setWidth(200);
        colBeginFilter.getColumn().setText(columnProperties[TAB_INTERVAL_INDEX]);
        colBeginFilter.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element != null && element instanceof IntervalFilterSetting) {
                    IntervalFilterSetting ival = (IntervalFilterSetting) element;
                    return (ival.beginFilter == null) ? "No filter set." : ival.beginFilter.toString();
                }

                return "";
            }
        });

        TableViewerColumn colEndFilter = new TableViewerColumn(fIntervalFilterTableViewer, SWT.NONE);
        colEndFilter.getColumn().setWidth(200);
        colEndFilter.getColumn().setText(columnProperties[TAB_FILTER_INDEX]);
        colEndFilter.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element != null && element instanceof IntervalFilterSetting) {
                    IntervalFilterSetting ival = (IntervalFilterSetting) element;
                    return (ival.endFilter == null) ? "No filter set." : ival.beginFilter.toString();
                }

                return "";
            }
        });
    }

    /**
     * Create the action bar for adding, importing, exporting filters. 
     * */
    private void createActionBar() {
        addFilterAction = new AddFilterAction();
        addFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(ADD_IMAGE));
        addFilterAction.setToolTipText("Add new filter");

        deleteFilterAction = new DeleteFilterAction();
        deleteFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(DELETE_IMAGE));
        deleteFilterAction.setToolTipText("Delete filter");

        importFilterAction = new ImportFilterAction();
        importFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(IMPORT_IMAGE));
        importFilterAction.setToolTipText("Import filters from File");

        exportFilterAction = new ExportFilterAction();
        exportFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(EXPORT_IMAGE));
        exportFilterAction.setToolTipText("Export filters to File");

        IActionBars bars = getViewSite().getActionBars();
        IToolBarManager manager = bars.getToolBarManager();
        manager.add(addFilterAction);
        manager.add(deleteFilterAction);
        manager.add(importFilterAction);
        manager.add(exportFilterAction);
    }

    @Override
    public void createPartControl(Composite parent) {
        fShell = parent.getShell();

        fTabs = new CTabFolder(parent, SWT.BORDER);
        CTabItem item1 = new CTabItem(fTabs, SWT.BORDER);
        item1.setText("System Jitter Graph");
        CTabItem item2 = new CTabItem(fTabs, SWT.BORDER);
        item2.setText("Jitter Bookmarks");
        CTabItem item3 = new CTabItem(fTabs, SWT.BORDER);
        item3.setText("Filter");

        fChart = new Chart(fTabs, SWT.BORDER);
        fChart.getTitle().setVisible(false);
        fChart.getAxisSet().getXAxis(0).getTitle().setText(X_AXIS_TITLE);
        fChart.getAxisSet().getYAxis(0).getTitle().setText(Y_AXIS_TITLE);
        fChart.getAxisSet().getXAxis(0).getTick().setFormat(new TmfChartTimeStampFormat());
        fChart.getLegend().setVisible(false);

        createIntervalTreeViewer();

        createIntervalFilterTable();

        item1.setControl(fChart);
        item2.setControl(fIntervalTreeViewer.getControl());
        item3.setControl(fIntervalFilterTableViewer.getControl());
        fTabs.setSelection(item1);

        createActionBar();

        fjitterNodes = new JitterRootNode();

        TmfTraceManager traceManager = TmfTraceManager.getInstance();
        ITmfTrace trace = traceManager.getActiveTrace();
        if (trace != null) {
            traceSelected(new TmfTraceSelectedSignal(this, trace));
        }
    }

    @Override
    public void setFocus() {
        fChart.setFocus();
    }

    @TmfSignalHandler
    public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
        // Called when the time stamp preference is changed
        fChart.getAxisSet().getXAxis(0).getTick().setFormat(new TmfChartTimeStampFormat());
        fChart.redraw();
    }

    @TmfSignalHandler
    public void traceOpened(final TmfTraceOpenedSignal signal) {
        System.out.println("XXX Update Trace upon traceOpened!");
        setSelectedTrace(signal.getTrace());
    }

    @TmfSignalHandler
    public void traceSelected(final TmfTraceSelectedSignal signal) {
        System.out.println("XXX Update Trace upon traceSelected!");
        setSelectedTrace(signal.getTrace());
    }

    @TmfSignalHandler
    public void traceClosed(final TmfTraceClosedSignal signal) {
        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                if (fIntervalTreeViewer.getControl().isDisposed()) {
                    return;
                }

                fIntervalTreeViewer.setInput(null);

                fChart.getSeriesSet().getSeries()[0].setXSeries(new double[0]);
                fChart.getSeriesSet().getSeries()[0].setYSeries(new double[0]);
                fChart.redraw();
            }
        });
    }

    private void setSelectedTrace(ITmfTrace trace) {
        // Don't populate the view again if we're already showing this trace
        if (fCurrentTrace == trace) {
            System.out.println("XXX Trace already selected!");
            return;
        }
        fCurrentTrace = trace;
        fjitterNodes.cleanJitterEntries();
        for (IntervalFilterSetting ival : fIntervalSettings) {
            ival.matchBeginTS = null;
        }

        // Create the request to get data from the trace
        TmfEventRequest req = new TmfEventRequest(TmfEvent.class, TmfTimeRange.ETERNITY, 0,
                ITmfEventRequest.ALL_DATA, ITmfEventRequest.ExecutionType.BACKGROUND) {

            @Override
            public void handleData(ITmfEvent data) {
                super.handleData(data);

                for (IntervalFilterSetting ival : fIntervalSettings) {
                    if (ival.beginFilter != null && ival.beginFilter.matches(data)) {
                        ITmfTimestamp ts = data.getTimestamp();
                        if (ival.endFilter == null && ival.matchBeginTS != null) {
                            fjitterNodes.addJitterEntry(ival.name, ival.matchBeginTS, ts, true);
                        }
                        ival.matchBeginTS = ts;
                    }
                    if (ival.endFilter != null && ival.endFilter.matches(data)) {
                        // add to fjitterNodes
                        ITmfTimestamp ts = data.getTimestamp();
                        /* Record only if a beginFilter was matched */
                        if (ival.matchBeginTS != null) {
                            fjitterNodes.addJitterEntry(ival.name, ival.matchBeginTS, ts, false);
                        }
                        ival.matchBeginTS = null;
                    }
                }
            }

            @Override
            public void handleSuccess() {
                // Request successful, not more data available
                super.handleSuccess();

                // This part needs to run on the UI thread since it updates the chart SWT control
                Display.getDefault().asyncExec(new Runnable() {

                    @Override
                    public void run() {
                        Object[] keys = fjitterNodes.getKeyNodes();
                        double xAxisRangeMax = Double.MAX_VALUE;

                        for (ISeries s : fChart.getSeriesSet().getSeries()) {
                            fChart.getSeriesSet().deleteSeries(s.getId());
                        }

                        for (int idx = 0; idx < keys.length; idx++) {
                            final double x[] = fjitterNodes.getXValues(keys[idx].toString());
                            final double y[] = fjitterNodes.getYValues(keys[idx].toString());

                            if (x.length == 0 || y.length == 0) {
                                continue;
                            }

                            xAxisRangeMax = Math.min(xAxisRangeMax, x[x.length - 1]);

                            fChart.getSeriesSet().createSeries(SeriesType.LINE, keys[idx].toString());
                            fChart.getSeriesSet().getSeries()[idx].setXSeries(x);
                            fChart.getSeriesSet().getSeries()[idx].setYSeries(y);
                        }
                        // Set the new range
                        if (xAxisRangeMax != Double.MAX_VALUE && xAxisRangeMax > 0) {
                            fChart.getAxisSet().getXAxis(0).setRange(new Range(0, xAxisRangeMax));
                            fChart.getAxisSet().getYAxis(0)
                                    .setRange(new Range(fjitterNodes.getYMin(keys[0].toString()),
                                            fjitterNodes.getYMax(keys[0].toString())));
                        } else {
                            fChart.getAxisSet().getXAxis(0).setRange(new Range(0, 1));
                            fChart.getAxisSet().getYAxis(0).setRange(new Range(0, 1));
                        }
                        fChart.getAxisSet().adjustRange();

                        fChart.redraw();

                        fIntervalTreeViewer.setInput(fjitterNodes);
                    }

                });
            }

            @Override
            public void handleFailure() {
                // Request failed, not more data available
                super.handleFailure();
            }
        };
        trace.sendRequest(req);
    }

}