Commit 1141b286 authored by Alex McCaskey's avatar Alex McCaskey
Browse files

CSVPlot/ICEResourcePage update:



Committing the new CSVPlot implementation that makes it possible for CSV
VizResources to updated dynamically. This also adds to
ICEResourcePage.update with code to handle updated VizResources. 
Signed-off-by: default avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 1fbea88b
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?><target name="mars" sequenceNumber="149">
<?pde version="3.8"?><target name="mars" sequenceNumber="151">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="ca.odell.glazedlists" version="1.9.0.v201303080712"/>
<unit id="com.sun.jersey" version="1.17.0.v20130314-2020"/>
<unit id="javax.ws.rs" version="1.1.1.v20130318-1750"/>
<unit id="javax.xml.rpc" version="1.1.0.v201209140446"/>
<unit id="org.codehaus.jackson.jaxrs" version="1.6.0.v20101005-1100"/>
<unit id="com.google.gson" version="2.2.4.v201311231704"/>
<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.nebula.feature.feature.group" version="1.0.0.201409040043"/>
<repository location="http://download.eclipse.org/technology/nebula/archives/Q32014/release"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.eclipse.swtbot.eclipse.feature.group" version="2.3.0.201506081302"/>
<unit id="org.hamcrest.core" version="1.3.0.v201303031735"/>
......@@ -31,19 +18,6 @@
<repository location="http://download.eclipse.org/technology/swtbot/releases/latest"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.source.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.core.source.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.source.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.core.feature.feature.group" version="1.3.0.201503261201"/>
<repository location="http://download.eclipse.org/nattable/releases/1.3.0/repository"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.apache.commons.math" version="2.1.0.v201105210652"/>
<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.ptp.remote.feature.group" version="9.0.0.201506101404"/>
<unit id="org.eclipse.ecf.core.source.feature.feature.group" version="1.1.0.v20150512-1727"/>
<unit id="org.eclipse.rse.dstore.feature.group" version="3.7.0.201505221634"/>
......@@ -153,6 +127,19 @@
<repository location="http://download.eclipse.org/releases/mars/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.nebula.feature.feature.group" version="1.0.0.201409040043"/>
<repository location="http://download.eclipse.org/technology/nebula/archives/Q32014/release"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.source.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.core.source.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.source.feature.feature.group" version="1.3.0.201503261201"/>
<unit id="org.eclipse.nebula.widgets.nattable.core.feature.feature.group" version="1.3.0.201503261201"/>
<repository location="http://download.eclipse.org/nattable/releases/1.3.0/repository"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.ease.ui.feature.feature.group" version="0.2.0.201505111426"/>
<unit id="org.eclipse.ease.feature.feature.group" version="0.2.0.201504281226"/>
<unit id="org.eclipse.ease.modules.charting.feature.feature.group" version="0.2.0.201504281229"/>
......@@ -163,5 +150,16 @@
<unit id="org.eclipse.ease.modules.feature.feature.group" version="0.2.0.201504281229"/>
<repository location="http://download.eclipse.org/ease/update/release"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.2.4.v201311231704"/>
<unit id="org.apache.commons.math" version="2.1.0.v201105210652"/>
<unit id="javax.ws.rs" version="1.1.1.v20130318-1750"/>
<unit id="com.sun.jersey" version="1.17.0.v20130314-2020"/>
<unit id="org.apache.commons.beanutils" version="1.8.0.v201205091237"/>
<unit id="org.codehaus.jackson.jaxrs" version="1.6.0.v20101005-1100"/>
<unit id="ca.odell.glazedlists" version="1.9.0.v201303080712"/>
<unit id="javax.xml.rpc" version="1.1.0.v201209140446"/>
<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository"/>
</location>
</locations>
</target>
......@@ -58,6 +58,8 @@ import org.eclipse.ui.ide.FileStoreEditorInput;
* @author Taylor Patterson
* @author Anna Wojtowicz
* @author Jordan Deyton
* @author Alex McCaskey
*
*/
public class ICEResourcePage extends ICEFormPage implements ISelectionListener,
IUpdateableListener {
......@@ -254,7 +256,7 @@ public class ICEResourcePage extends ICEFormPage implements ISelectionListener,
* The resource to render. Assumed not to be {@code null}.
* @throws PartInitException
*/
void showResource(ICEResource resource) throws PartInitException {
public void showResource(ICEResource resource) throws PartInitException {
// TODO This method has several return statements, making it a little
// hard to read. It should be updated and simplified.
......@@ -394,7 +396,7 @@ public class ICEResourcePage extends ICEFormPage implements ISelectionListener,
} catch (Exception e) {
// Instead of printing the stack trace, print the error
// message. This means the plot could not be created.
System.err.println(e.getMessage());
System.err.println("Create Plot failed: " + e.getMessage());
}
}
}
......@@ -501,6 +503,11 @@ public class ICEResourcePage extends ICEFormPage implements ISelectionListener,
// to sync the ResourceComponent.
if (component != null) {
resourceComponent.register(this);
for (ICEResource resource : resourceComponent.getResources()) {
if (resource instanceof VizResource) {
resource.register(this);
}
}
update(resourceComponent);
}
}
......@@ -560,9 +567,29 @@ public class ICEResourcePage extends ICEFormPage implements ISelectionListener,
// If there is no plot already, try to create one.
if (plot == null) {
plot = createPlot((VizResource) resource);
// Register with the Resource so that if it
// changes we can know and operate accordingly
resource.register(this);
}
}
}
} else if (component != null && component instanceof VizResource) {
// Cast to a VizResource
final VizResource resource = (VizResource) component;
// Get the plot associated with this resource and redraw it.
plots.get(getPlotKey(resource)).redraw();
// Layout the composite on the UI thread.
if (pageComposite != null) {
pageComposite.getDisplay().asyncExec(new Runnable() {
public void run() {
pageComposite.layout();
activateEditor();
}
});
}
}
return;
......@@ -580,4 +607,4 @@ public class ICEResourcePage extends ICEFormPage implements ISelectionListener,
// selection. Note that the current selection can change based on the
// currently active view/part.
}
}
}
\ No newline at end of file
......@@ -197,4 +197,10 @@ public class VisItPlot extends ConnectionPlot<VisItSwtConnection> {
: new ArrayList<String>());
}
@Override
public void redraw() {
// TODO Auto-generated method stub
}
}
......@@ -5,9 +5,17 @@ Bundle-SymbolicName: org.eclipse.ice.viz.service;singleton:=true
Bundle-Version: 2.0.0
Bundle-Vendor: Oak Ridge National Laboratory
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: com.google.gson;version="2.2.4",
Import-Package: ca.odell.glazedlists,
org.apache.commons.beanutils,
org.apache.commons.math.linear;version="2.1.0",
Import-Package: ca.odell.glazedlists,
com.google.gson;version="2.2.4",
org.apache.commons.beanutils,
org.apache.commons.math;version="2.1.0",
org.apache.commons.math.linear;version="2.1.0",
org.eclipse.core.commands.common,
org.eclipse.core.runtime;version="3.4.0",
org.eclipse.core.runtime.jobs,
org.eclipse.core.runtime.preferences,
org.eclipse.draw2d,
org.eclipse.equinox.security.storage;version="1.0.0",
......
......@@ -35,7 +35,7 @@ import org.eclipse.swt.widgets.Composite;
* Implementations should not be restricted to one usage scenario.
* </p>
*
* @author Jay Jay Billings
* @author Jay Jay Billings, Alex McCaskey
*
*/
public interface IPlot {
......@@ -141,5 +141,17 @@ public interface IPlot {
* @return True if the source is on a remote machine, false otherwise
*/
public boolean isSourceRemote();
/**
* This operation directs the IPlot to redraw its contents. This can be invoked
* when, for example, the data represented by this IPlot changes, and a change in
* the IPlot's UI must change accordingly.
*
* The exact details of how this IPlot is redrawn after a valid draw is left
* completely to the implementation.
*
*/
public void redraw();
}
......@@ -11,7 +11,10 @@
*******************************************************************************/
package org.eclipse.ice.viz.service.csv;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
......@@ -19,7 +22,11 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.math.linear.MatrixUtils;
import org.apache.commons.math.linear.RealMatrix;
import org.eclipse.ice.client.common.ActionTree;
import org.eclipse.ice.datastructures.ICEObject.ListComponent;
import org.eclipse.ice.viz.service.IPlot;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
......@@ -38,11 +45,21 @@ import org.eclipse.swt.widgets.Menu;
* In addition to the IPlot operations it provides the load() operation that
* should be called after construction.
*
* @author Jay Jay Billings, Anna Wojtowicz
* @author Jay Jay Billings, Anna Wojtowicz, Alex McCaskey
*
*/
public class CSVPlot implements IPlot {
/**
* Reference to the read-in matrix of CSV data.
*/
private RealMatrix csvData;
/**
* Reference to the mapping between Feature strings and matrix indices.
*/
private HashMap<String, Integer> featureToIndexMap;
/**
* The source of the data for this plot
*/
......@@ -72,6 +89,16 @@ public class CSVPlot implements IPlot {
*/
private final Map<Composite, DrawnPlot> drawnPlots;
/**
* Reference to the currently selected category.
*/
private String currentCategory;
/**
* Reference to the currently selected plot type.
*/
private String currentPlotType;
/**
* The Constructor
*
......@@ -88,6 +115,8 @@ public class CSVPlot implements IPlot {
// Create the map of drawn plots.
drawnPlots = new HashMap<Composite, DrawnPlot>();
featureToIndexMap = new HashMap<String, Integer>();
return;
}
......@@ -134,48 +163,91 @@ public class CSVPlot implements IPlot {
*/
private void load(File file) {
// Load the file using the CSV utilities.
CSVDataLoader dataLoader = new CSVDataLoader();
// Configure the list
ListComponent<String[]> lines = new ListComponent<String[]>();
lines.setName(file.getName());
lines.setDescription(file.getName());
try {
baseProvider = dataLoader.load(file);
} catch (Exception e) {
throw new RuntimeException(e);
// Grab the contents of the file
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
// Skip lines that pure comments
if (!line.startsWith("#")) {
// Clip the line if it has a comment symbol in it to be
// everything before the symbol
if (line.contains("#")) {
int index = line.indexOf("#");
line = line.substring(0, index);
}
// Clean up any crap on the line
String[] lineArray = line.trim().split(",");
String[] trimmedLine = new String[lineArray.length];
// And clean up any crap on each split piece
for (int i = 0; i < lineArray.length; i++) {
trimmedLine[i] = lineArray[i].trim();
}
// Put the lines in the list
lines.add(trimmedLine);
}
}
reader.close();
} catch (IOException e) {
// Complain
e.printStackTrace();
}
// Set the source so the title (and other properties) are set correctly.
baseProvider.setSource(source.toString());
// Get the variables from the base IDataProvider.
List<String> variables = baseProvider.getFeatureList();
int nVariables = variables.size();
// Create a list to hold all available series. Each combination of
// feature names (except for feature vs. itself) should be an allowed
// series. Populate the list with the series names, which should be
// "y-variable vs. x-variable".
List<String> plotTypes = new ArrayList<String>(nVariables * nVariables);
for (int y = 0; y < nVariables; y++) {
String variableY = variables.get(y);
for (int x = 0; x < nVariables; x++) {
if (y != x) {
String type = variableY + " vs. " + variables.get(x);
plotTypes.add(type);
if (!lines.isEmpty()) {
// Assume that the first line has information about the data
String[] variables = lines.remove(0);
int nVariables = variables.length;
for (int i = 0; i < nVariables; i++) {
featureToIndexMap.put(variables[i], new Integer(i));
}
// Create an empty matrix of data
csvData = MatrixUtils.createRealMatrix(lines.size(),
lines.get(0).length);
// Load the data as doubles
for (int i = 0; i < lines.size(); i++) {
double[] values = (double[]) ConvertUtils.convert(lines.get(i),
Double.TYPE);
csvData.setRow(i, values);
}
// Create a list to hold all available series. Each combination of
// feature names (except for feature vs. itself) should be an
// allowed
// series. Populate the list with the series names, which should be
// "y-variable vs. x-variable".
List<String> plotTypes = new ArrayList<String>(nVariables
* nVariables);
for (int y = 0; y < nVariables; y++) {
String variableY = variables[y];
for (int x = 0; x < nVariables; x++) {
if (y != x) {
String type = variableY + " vs. " + variables[x];
plotTypes.add(type);
}
}
}
// Mark the variable as independent. The order in which they are
// marked independent does not really matter, since all are
// "independent" in the end.
baseProvider.setFeatureAsIndependentVariable(variableY);
}
// Put the types in the map of types. Line, scatter, and bar plots
// can
// be created for any of the plot types, so we can re-use the same
// string array.
String[] plotTypesArray = plotTypes.toArray(new String[] {});
types.put("Line", plotTypesArray);
types.put("Scatter", plotTypesArray);
types.put("Bar", plotTypesArray);
// Put the types in the map of types. Line, scatter, and bar plots can
// be created for any of the plot types, so we can re-use the same
// string array.
String[] plotTypesArray = plotTypes.toArray(new String[] {});
types.put("Line", plotTypesArray);
types.put("Scatter", plotTypesArray);
types.put("Bar", plotTypesArray);
}
return;
}
......@@ -269,7 +341,7 @@ public class CSVPlot implements IPlot {
}
}
if (baseProvider != null && typeValid && parent != null
if (/* baseProvider != null && */typeValid && parent != null
&& !parent.isDisposed()) {
// Get the drawn plot associated with the parent Composite, creating
......@@ -290,9 +362,9 @@ public class CSVPlot implements IPlot {
}
// Reset the plot time to the initial time.
double plotTime = baseProvider.getTimes().get(0);
// double plotTime = 0.0;// baseProvider.getTimes().get(0);
// FIXME Won't this affect all of the drawn plots?
baseProvider.setTime(plotTime);
// baseProvider.setTime(plotTime);
// Remove all previous plots.
drawnPlot.clear();
......@@ -305,6 +377,10 @@ public class CSVPlot implements IPlot {
// We need to return the Composite used to render the CSV plot.
child = drawnPlot.editor.getPlotCanvas();
currentCategory = category;
currentPlotType = plotType;
} else {
// Complain that the plot is invalid
throw new Exception("Invalid plot: category = " + category
......@@ -331,10 +407,7 @@ public class CSVPlot implements IPlot {
* The editor in which the CSV plot is rendered.
*/
public final CSVPlotEditor editor;
/**
* The data provider containing the loaded CSV data.
*/
public final CSVDataProvider dataProvider;
/**
* The provider responsible for maintaining the plot configuration.
*/
......@@ -369,14 +442,13 @@ public class CSVPlot implements IPlot {
public DrawnPlot(Composite parent) throws Exception {
// Create the editor and all required providers.
editor = new CSVPlotEditor();
dataProvider = baseProvider;
plotProvider = new PlotProvider();
// Set the plot title based on the file name.
int lastSeparator = dataProvider.getSourceInfo().lastIndexOf("/");
String plotTitle = (lastSeparator > -1 ? dataProvider
.getSourceInfo().substring(lastSeparator + 1)
: dataProvider.getSourceInfo());
int lastSeparator = source.getPath().lastIndexOf("/");
String plotTitle = (lastSeparator > -1 ? source.getPath()
.substring(lastSeparator + 1) : source.getPath());
// Set the title for the new plot provider
plotProvider.setPlotTitle(plotTitle);
......@@ -471,9 +543,7 @@ public class CSVPlot implements IPlot {
*/
public void addSeries(String category, String type) {
// Reset the plot time to the initial time.
double plotTime = dataProvider.getTimes().get(0);
// FIXME Won't this affect all of the drawn plots?
dataProvider.setTime(plotTime);
double plotTime = 0.0;// dataProvider.getTimes().get(0);
// Get the axes to plot
String[] axes = type.split(" ");
......@@ -484,7 +554,7 @@ public class CSVPlot implements IPlot {
String seriesTitle = yAxis + " vs. " + xAxis + " at " + plotTime;
// Create a new series provider
final SeriesProvider seriesProvider = new SeriesProvider();
seriesProvider.setDataProvider(dataProvider);
seriesProvider.setCSVData(csvData, featureToIndexMap);
seriesProvider.setTimeForDataProvider(plotTime);
seriesProvider.setSeriesTitle(seriesTitle);
seriesProvider.setXDataFeature(xAxis);
......@@ -518,7 +588,7 @@ public class CSVPlot implements IPlot {
public void removeSeries(SeriesProvider series) {
ActionTree tree = seriesMap.remove(series);
if (tree != null) {
double plotTime = dataProvider.getTimes().get(0);
double plotTime = 0.0;// dataProvider.getTimes().get(0);
removeSeriesTree.remove(tree);
plotProvider.removeSeries(plotTime, series);
}
......@@ -529,7 +599,7 @@ public class CSVPlot implements IPlot {
* Clears all series from the drawn plot.
*/
public void clear() {
double plotTime = dataProvider.getTimes().get(0);
double plotTime = 0.0;// dataProvider.getTimes().get(0);
for (Entry<SeriesProvider, ActionTree> e : seriesMap.entrySet()) {
plotProvider.removeSeries(plotTime, e.getKey());
}
......@@ -554,4 +624,28 @@ public class CSVPlot implements IPlot {
}
}
/*
* (non-Javadoc)
* @see org.eclipse.ice.viz.service.IPlot#redraw()
*/
@Override
public void redraw() {
// Start off by reloading this IPlot's representative data set.
load();
// Then loop over all drawn plots and re-execute the draw method.
for (final Composite comp : drawnPlots.keySet()) {
comp.getDisplay().asyncExec(new Runnable() {
public void run() {
try {
draw(currentCategory, currentPlotType, comp);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
......@@ -51,6 +51,7 @@ import org.eclipse.ui.part.EditorPart;
* @author Taylor Patterson
* @author Anna Wojtowicz
* @author Jordan Deyton
* @author Alex McCaskey
*/
public class CSVPlotEditor extends EditorPart {
......@@ -62,7 +63,7 @@ public class CSVPlotEditor extends EditorPart {
/**
* The top level composite that holds the editor's contents.
*/
private Composite vizComposite;
public Composite vizComposite;
/**
* The {@code Composite} that contains the time slider.
......@@ -215,9 +216,9 @@ public class CSVPlotEditor extends EditorPart {
intensityGraph.setMax(seriesProvider.getDataMax());
intensityGraph.setMin(seriesProvider.getDataMin());
// Set the data width and data height
intensityGraph.setDataHeight(seriesProvider.getDataHeight());
intensityGraph.setDataWidth(seriesProvider.getDataWidth());
// FIXME Set the data width and data height
// intensityGraph.setDataHeight(seriesProvider.getDataHeight());
// intensityGraph.setDataWidth(seriesProvider.getDataWidth());
// Stick with predefined colormap
intensityGraph.setColorMap(new ColorMap(PredefinedColorMap.JET,
......@@ -226,7 +227,7 @@ public class CSVPlotEditor extends EditorPart {
// Set the contents
lws.setContents(intensityGraph);
intensityGraph.setDataArray(seriesProvider.getYData());
intensityGraph.setDataArray(seriesProvider.getCSVMatrixYData());
// Add controls for setting the min and max values
Composite minMaxComp = new Composite(vizComposite, SWT.NONE);
......@@ -300,15 +301,15 @@ public class CSVPlotEditor extends EditorPart {
if (seriesProviderList == null) {
seriesProviderList = new ArrayList<SeriesProvider>();
}
for (SeriesProvider series : seriesProviderList) {
for (final SeriesProvider series : seriesProviderList) {
CircularBufferDataProvider traceDataProvider = new CircularBufferDataProvider(
final CircularBufferDataProvider traceDataProvider = new CircularBufferDataProvider(
false);
// Sets the size of the buffer
traceDataProvider.setBufferSize(series.getXData().length);
traceDataProvider.setBufferSize(series.getCSVMatrixXData().length);
// Set the data to be plotted
traceDataProvider.setCurrentXDataArray(series.getXData());