diff --git a/src/org.eclipse.ice.viz.service/META-INF/MANIFEST.MF b/src/org.eclipse.ice.viz.service/META-INF/MANIFEST.MF index 34844cb69..daea3566a 100644 --- a/src/org.eclipse.ice.viz.service/META-INF/MANIFEST.MF +++ b/src/org.eclipse.ice.viz.service/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Import-Package: org.eclipse.core.commands.common, org.eclipse.core.runtime;version="3.4.0", org.eclipse.core.runtime.preferences, org.eclipse.equinox.security.storage;version="1.0.0", + org.eclipse.ice.client.common, org.eclipse.ice.client.widgets.properties, org.eclipse.ice.client.widgets.viz.service, org.eclipse.ice.datastructures.ICEObject, diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/csv/CSVPlot.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/csv/CSVPlot.java index 6414578ff..56e12207f 100644 --- a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/csv/CSVPlot.java +++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/csv/CSVPlot.java @@ -17,16 +17,23 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; +import org.eclipse.ice.client.common.ActionTree; import org.eclipse.ice.client.widgets.viz.service.IPlot; import org.eclipse.ice.viz.plotviewer.CSVDataLoader; import org.eclipse.ice.viz.plotviewer.CSVDataProvider; import org.eclipse.ice.viz.plotviewer.CSVPlotEditor; import org.eclipse.ice.viz.plotviewer.PlotProvider; import org.eclipse.ice.viz.plotviewer.SeriesProvider; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.MenuManager; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.events.MenuListener; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; /** * This class implements the IPlot interface to provide access to a basic CSV @@ -40,9 +47,6 @@ */ public class CSVPlot implements IPlot { - // FIXME We should be able to add and remove any number of series from the - // same drawn plot. Currently, we can only show one series at a time. - /** * The source of the data for this plot */ @@ -84,9 +88,6 @@ public CSVPlot(URI source) { properties = new HashMap(); // Create the plot type map and add empty arrays by default types = new HashMap(); - String[] emptyStringArray = {}; - types.put("line", emptyStringArray); - types.put("scatter", emptyStringArray); // Create the map of drawn plots. drawnPlots = new HashMap(); @@ -292,34 +293,16 @@ public void widgetDisposed(DisposeEvent e) { // FIXME Won't this affect all of the drawn plots? baseProvider.setTime(plotTime); - // Remove the previously plotted series, if one exists. + // FIXME This only affects one series... + // Remove the previously plotted series, if any exist. if (drawnPlot.seriesProvider != null) { drawnPlot.plotProvider.removeSeries(plotTime, drawnPlot.seriesProvider); drawnPlot.seriesProvider = null; } - // Get the axes to plot - String[] axes = plotType.split(" "); - String axis1 = axes[0]; - String axis2 = axes[2]; - - // Create a new series title for the new series - String seriesTitle = axis1 + " vs. " + axis2 + " at " + plotTime; - // Create a new series provider - SeriesProvider seriesProvider = new SeriesProvider(); - seriesProvider.setDataProvider(drawnPlot.dataProvider); - seriesProvider.setTimeForDataProvider(plotTime); - seriesProvider.setSeriesTitle(seriesTitle); - seriesProvider.setXDataFeature(axis1); - seriesProvider.setYDataFeature(axis2); - seriesProvider.setSeriesType(category); - // Add this new series to the plot provider - drawnPlot.seriesProvider = seriesProvider; - drawnPlot.plotProvider.addSeries(plotTime, seriesProvider); - - // Add the new plot to the editor. - drawnPlot.editor.showPlotProvider(drawnPlot.plotProvider, true); + // Add the specified series to the drawn plot. + addSeries(category, plotType, drawnPlot); // We need to return the Composite used to render the CSV plot. child = drawnPlot.editor.getPlotCanvas(); @@ -333,6 +316,62 @@ public void widgetDisposed(DisposeEvent e) { return child; } + /** + * Removes the specified series from the drawn plot. + * + * @param series + * The series to remove. + * @param drawnPlot + * The drawn plot that will lose its series. + */ + private void removeSeries(SeriesProvider series, DrawnPlot drawnPlot) { + Double plotTime = baseProvider.getTimes().get(0); + drawnPlot.plotProvider.removeSeries(plotTime, series); + } + + /** + * Adds a new series to the drawn plot. + * + * @param category + * The category of the series to add. + * @param type + * The type of the series to add. + * @param drawnPlot + * The drawn plot that will get a new series. + */ + private void addSeries(String category, String type, DrawnPlot drawnPlot) { + // As this is a private method, the parameters are expected to be valid. + + // Reset the plot time to the initial time. + Double plotTime = baseProvider.getTimes().get(0); + // FIXME Won't this affect all of the drawn plots? + baseProvider.setTime(plotTime); + + // Get the axes to plot + String[] axes = type.split(" "); + String axis1 = axes[0]; + String axis2 = axes[2]; + + // Create a new series title for the new series + String seriesTitle = axis1 + " vs. " + axis2 + " at " + plotTime; + // Create a new series provider + SeriesProvider seriesProvider = new SeriesProvider(); + seriesProvider.setDataProvider(drawnPlot.dataProvider); + seriesProvider.setTimeForDataProvider(plotTime); + seriesProvider.setSeriesTitle(seriesTitle); + seriesProvider.setXDataFeature(axis1); + seriesProvider.setYDataFeature(axis2); + seriesProvider.setSeriesType(category); + // Add this new series to the plot provider + drawnPlot.seriesProvider = seriesProvider; + drawnPlot.plotProvider.addSeries(plotTime, seriesProvider); + + // Add the new plot to the editor. + drawnPlot.editor.showPlotProvider(drawnPlot.plotProvider, true); + + return; + } + /** * An instance of this nested class is composed of the drawn * {@link CSVPlotEditor} and all providers necessary to populate it with CSV @@ -360,6 +399,17 @@ private class DrawnPlot { */ public SeriesProvider seriesProvider; + /** + * A tree of JFace {@code Action}s for adding new series to the drawn + * plot. + */ + private final ActionTree addSeriesTree; + /** + * A tree of JFace {@code Action}s for removing plotted series from the + * drawn plot. + */ + private final ActionTree removeSeriesTree; + /** * Creates a {@link CSVPlotEditor} and all providers necessary to * populate it. The editor is created inside the specified parent @@ -369,7 +419,7 @@ private class DrawnPlot { * The {@code Composite} in which to draw the CSV plot * editor. */ - public DrawnPlot(Composite parent) { + public DrawnPlot(Composite parent) throws Exception { // Create the editor and all required providers. editor = new CSVPlotEditor(); dataProvider = baseProvider; @@ -386,9 +436,66 @@ public DrawnPlot(Composite parent) { // Create the plot inside the parent Composite. editor.createPartControl(parent); + // Get the child Composite used to render the + Composite canvas = editor.getPlotCanvas(); + + // Get the context Menu for the parent Composite, or create a new + // one if the parent lacks a context Menu. + Menu menu = parent.getMenu(); + if (menu == null) { + MenuManager menuManager = new MenuManager(); + menu = menuManager.createContextMenu(canvas); + } + + // Create the ActionTrees for adding and removing series on the fly. + addSeriesTree = new ActionTree("Add Series"); + removeSeriesTree = new ActionTree("Remove Series"); + + // Fill out the add series tree. This tree will never need to be + // updated. + for (Entry e : getPlotTypes().entrySet()) { + final String category = e.getKey(); + String[] types = e.getValue(); + + if (category != null && types != null) { + // Create the tree for the category and all its types. + ActionTree catTree = new ActionTree(category); + addSeriesTree.add(catTree); + // Create Actions for all the types. Each Action should call + // addSeries(...) with the category and type. + for (final String type : types) { + if (type != null) { + catTree.add(new ActionTree(new Action(type) { + @Override + public void run() { + addSeries(category, type, DrawnPlot.this); + } + })); + } + } + } + } + + // TODO Set up the remove series tree... + + // When the Menu is about to be shown, add the add/remove series + // actions to it. + menu.addMenuListener(new MenuListener() { + @Override + public void menuHidden(MenuEvent e) { + // Nothing to do. + } + + @Override + public void menuShown(MenuEvent e) { + Menu menu = (Menu) e.widget; + addSeriesTree.getContributionItem().fill(menu, -1); + } + }); + // Set the context Menu for the main plot canvas. The slider can // have its own menu set later. - editor.getPlotCanvas().setMenu(parent.getMenu()); + editor.getPlotCanvas().setMenu(menu); return; }