blob: 306e4164978aa3547669227c4d28d8e65e17150d [file] [log] [blame]
// RelativeValueHistoryPlotter.java
package org.eclipse.stem.ui.reports.views;
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.graph.DynamicLabel;
import org.eclipse.stem.core.graph.DynamicNodeLabel;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.model.Decorator;
import org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryExtendedListener;
import org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryProvider;
import org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryProviderAdapter;
import org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryProviderAdapterFactory;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabel;
import org.eclipse.stem.jobs.simulation.ISimulation;
import org.eclipse.stem.jobs.simulation.ISimulationListener;
import org.eclipse.stem.jobs.simulation.SimulationEvent;
import org.eclipse.stem.jobs.simulation.SimulationState;
import org.eclipse.stem.ui.preferences.PreferenceConstants;
import org.eclipse.stem.ui.reports.Activator;
import org.eclipse.stem.ui.widgets.PropertySelector;
import org.eclipse.stem.ui.widgets.PropertySelector.PropertySelectionEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
/**
* This class represents
*/
public class PhaseSpaceHistoryPlotter extends ReportControl implements
RelativeValueHistoryExtendedListener, ISimulationListener {
PhaseSpaceCanvas phaseSpaceCanvas;
PropertySelector propertySelectorX;
PropertySelector propertySelectorY;
ItemPropertyDescriptor selectedProperty1;
ItemPropertyDescriptor selectedProperty2;
private static final String X_AXIS_LABEL = "X Axis";
private static final String Y_AXIS_LABEL = "Y Axis";
boolean plotUpdateScheduled = false;
/**
* @param parent
*/
public PhaseSpaceHistoryPlotter(final Composite parent) {
super(parent, SWT.None);
createContents();
} // RelativeValueHistoryPlotter
/**
* Create the contents of the plotter
*/
private void createContents() {
setLayout(new FormLayout());
identifiableTitle = new Label(this, SWT.NONE);
phaseSpaceCanvas = new PhaseSpaceCanvas(this);
propertySelectorX = new PropertySelector(this, SWT.NONE, true);
propertySelectorX.setDisplayLabel(X_AXIS_LABEL);
propertySelectorY = new PropertySelector(this, SWT.NONE, true);
propertySelectorY.setDisplayLabel(Y_AXIS_LABEL);
removeButton = new Button(this, SWT.NONE);
removeButton.setText(REMOVE_TEXT);
final FormData titleFormData = new FormData();
identifiableTitle.setLayoutData(titleFormData);
titleFormData.top = new FormAttachment(0, 0);
titleFormData.left = new FormAttachment(0, 0);
titleFormData.right = new FormAttachment(100, 0);
final FormData chartFormData = new FormData();
phaseSpaceCanvas.setLayoutData(chartFormData);
chartFormData.top = new FormAttachment(identifiableTitle, 0);
chartFormData.bottom = new FormAttachment(propertySelectorY, 0);
chartFormData.left = new FormAttachment(0, 0);
chartFormData.right = new FormAttachment(100, 0);
// Property Selector
final FormData propertySelectorFormDataY = new FormData();
// propertySelectorFormData.top = new FormAttachment(timeSeriesCanvas,
// 0);
propertySelectorFormDataY.bottom = new FormAttachment(100, 0);
propertySelectorFormDataY.left = new FormAttachment(0, 0);
propertySelectorFormDataY.right = new FormAttachment(30, 0);
propertySelectorY.setLayoutData(propertySelectorFormDataY);
// Property Selector
final FormData propertySelectorFormDataX = new FormData();
// propertySelectorFormDataX.top = new FormAttachment(propertySelectorY,
// 0);
propertySelectorFormDataX.bottom = new FormAttachment(100, 0);
propertySelectorFormDataX.left = new FormAttachment(propertySelectorY,
0);
propertySelectorFormDataX.right = new FormAttachment(60, 0);
propertySelectorX.setLayoutData(propertySelectorFormDataX);
// RemoveButton
final FormData removeButtonFormData = new FormData();
// propertySelectorFormDataX.top = new FormAttachment(propertySelectorY,
// 0);
removeButtonFormData.bottom = new FormAttachment(100, 0);
removeButtonFormData.left = new FormAttachment(propertySelectorX, 0);
removeButtonFormData.right = new FormAttachment(90, 0);
removeButton.setLayoutData(removeButtonFormData);
final PhaseSpaceHistoryPlotter self = this;
// X listener
propertySelectorX
.addPropertySelectionListener(new PropertySelector.PropertySelectionListener() {
/**
* @see org.eclipse.stem.ui.widgets.PropertySelector.PropertySelectionListener#propertySelected(org.eclipse.stem.ui.widgets.PropertySelector.PropertySelectionEvent)
*/
public void propertySelected(
final PropertySelectionEvent propertySelectionEvent) {
selectedDecorator = propertySelectionEvent
.getDecorator();
// get the X property from the event
selectedProperty2 = propertySelectionEvent
.getProperty();
String selectedId = propertySelectionEvent.getId();
List<DynamicLabel>allLabels = decoratorToLabelsMap.get(selectedDecorator);
for(DynamicLabel lab:allLabels) {
if(lab instanceof DiseaseModelLabel &&
((DiseaseModelLabel)lab).getPopulationModelLabel().getPopulationIdentifier().equals(selectedId))
{selectedDynamicLabel = lab;break;}
}
if(selectedDynamicLabel != null) {
RelativeValueHistoryProviderAdapter rhvp = (RelativeValueHistoryProviderAdapter) RelativeValueHistoryProviderAdapterFactory.INSTANCE
.adapt(selectedDynamicLabel,RelativeValueHistoryProvider.class);
switchToRVHP(rhvp);
self.phaseSpaceCanvas.setDataSourceAndRedraw(rhvp, selectedProperty2, selectedProperty1);
}
}
});
// Y listener
propertySelectorY
.addPropertySelectionListener(new PropertySelector.PropertySelectionListener() {
/**
* @see org.eclipse.stem.ui.widgets.PropertySelector.PropertySelectionListener#propertySelected(org.eclipse.stem.ui.widgets.PropertySelector.PropertySelectionEvent)
*/
public void propertySelected(
final PropertySelectionEvent propertySelectionEvent) {
selectedDecorator = propertySelectionEvent
.getDecorator();
// get the Y property from the event
selectedProperty1 = propertySelectionEvent
.getProperty();
String selectedId = propertySelectionEvent.getId();
List<DynamicLabel>allLabels = decoratorToLabelsMap.get(selectedDecorator);
for(DynamicLabel lab:allLabels) {
if(lab instanceof DiseaseModelLabel &&
((DiseaseModelLabel)lab).getPopulationModelLabel().getPopulationIdentifier().equals(selectedId))
{selectedDynamicLabel = lab;break;}
}
if(selectedDynamicLabel != null) {
RelativeValueHistoryProviderAdapter rhvp = (RelativeValueHistoryProviderAdapter) RelativeValueHistoryProviderAdapterFactory.INSTANCE
.adapt(selectedDynamicLabel,
RelativeValueHistoryProvider.class);
switchToRVHP(rhvp);
self.phaseSpaceCanvas.setDataSourceAndRedraw(rhvp, selectedProperty2, selectedProperty1);
}
}
});
removeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(
@SuppressWarnings("unused") final SelectionEvent e) {
fireRemoveEvent(identifiable);
remove();
}
});
} // createContents
/**
* to remove the control e.g. by a remove button event
*/
@Override
@SuppressWarnings("cast")
public void remove() {
removeListeners.clear();
switchToRVHP(null);
relativeValueHistoryExtended(null);
identifiableTitle.setText("");
propertySelectorX
.setDecorators((List<Decorator>) Collections.EMPTY_LIST);
propertySelectorY
.setDecorators((List<Decorator>) Collections.EMPTY_LIST);
dispose();
}
/**
* @param identifiable
* the {@link Identifiable} to be the source of the data to be
* plotted.
*/
@Override
public void setIdentifiable(final Identifiable identifiable) {
// Same Identifiable?
if (this.identifiable == identifiable) {
// Yes
return;
} // if
this.identifiable = identifiable;
final List<Decorator> decorators = new ArrayList<Decorator>();
decoratorToLabelsMap = new HashMap<Decorator, List<DynamicLabel>>();
identifiableTitle.setText(identifiable.getDublinCore().getTitle());
// Get the dynamic labels associated with this Identifiable
// A node?
if (identifiable instanceof Node) {
// Yes
final Node node = (Node) identifiable;
for (final NodeLabel nodeLabel : node.getLabels()) {
// Updated by a decorator?
if (nodeLabel instanceof DynamicNodeLabel) {
// Yes
final DynamicNodeLabel dynamicNodeLabel = (DynamicNodeLabel) nodeLabel;
// Can it provide relative values?
final RelativeValueHistoryProviderAdapter rvhp = (RelativeValueHistoryProviderAdapter) RelativeValueHistoryProviderAdapterFactory.INSTANCE
.adapt(nodeLabel,
RelativeValueHistoryProvider.class);
if (rvhp != null) {
// Yes
final Decorator decorator = dynamicNodeLabel
.getDecorator();
if (decorator != null) {
if(decoratorToLabelsMap.get(decorator)!=null) {
List<DynamicLabel>list = decoratorToLabelsMap.get(decorator);
list.add(dynamicNodeLabel);
} else {
ArrayList<DynamicLabel>newList = new ArrayList<DynamicLabel>();
newList.add(dynamicNodeLabel);
decoratorToLabelsMap.put(decorator, newList);
}
if (!decorators.contains(decorator)) {
decorators.add(decorator);
}
} else {
Activator.logError("DynamicLabel \""
+ dynamicNodeLabel.getDublinCore()
.getTitle()
+ "\" does not have a Decorator", null);
}
} // if RelativeValueHistoryProviderAdapter
} // if DynamicNodeLabel
} // for each NodeLabel
} // if Node
// new node... update the decorators
propertySelectorX.setDecorators(decorators);
propertySelectorY.setDecorators(decorators);
try {
// try to set the displayed decorator by the users ui label
// preferences
final Preferences preferences = org.eclipse.stem.ui.Activator
.getDefault().getPluginPreferences();
final String yPreference = preferences
.getString(PreferenceConstants.INITIAL_ATTRIBUTE_NAME_STRING_PREFERENCE);
final String xPreference = preferences
.getString(PreferenceConstants.INITIAL_ATTRIBUTE_NAME_STRING_PREFERENCE2);
// we do not care about the return value, it's ok if the preference
// is not there.
propertySelectorY.setDisplayedProperty(yPreference);
propertySelectorX.setDisplayedProperty(xPreference);
} catch (final Exception e) {
// if it fails do nothing
}
} // setIdentifiable
/**
* @see org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryExtendedListener#relativeValueHistoryExtended(org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryProviderAdapter)
*/
public void relativeValueHistoryExtended(
final RelativeValueHistoryProviderAdapter rvhp) {
// The event notification doesn't come from the UI thread so we need to
// add a Runnable to the UI thread's execution queue to give the new
// source to the chart
// If a plot update is already scheduled, then don't add another to the queue
if (plotUpdateScheduled) {
return;
}
final Display display = Display.getDefault();
if (!display.isDisposed()) {
// Yes
try {
plotUpdateScheduled = true;
display.asyncExec(new Runnable() {
public void run() {
try {
phaseSpaceCanvas.setDataSourceAndRedraw(rvhp,
selectedProperty2, selectedProperty1);
} finally {
plotUpdateScheduled = false;
}
} // run
}); // display.asyncExec
} // try
catch (final Exception e) {
// Ignore there could be a race condition with the display being
// disposed when the system is shut down with a running
// simulation.
} // catch Exception
} // if
}// relativeValueHistoryExtended
/**
* @see org.eclipse.stem.jobs.simulation.ISimulationListener#simulationChanged(org.eclipse.stem.jobs.simulation.SimulationEvent)
*/
@SuppressWarnings("cast")
public void simulationChanged(final SimulationEvent event) {
// reset event
if (event.getSimulationState() == SimulationState.RESET) {
// Yes
phaseSpaceCanvas.resetData();
} // if
// Is the Simulation stopping (i.e. being deleted?)
if (event.getSimulationState() == SimulationState.STOPPED) {
// Yes
simulation.removeSimulationListener(this);
simulation = null;
switchToRVHP(null);
relativeValueHistoryExtended(null);
identifiableTitle.setText("");
propertySelectorX
.setDecorators((List<Decorator>) Collections.EMPTY_LIST);
propertySelectorY
.setDecorators((List<Decorator>) Collections.EMPTY_LIST);
} // if
} // simulationChanged
/**
* Initialize the control from a
* {@link org.eclipse.stem.jobs.simulation.Simulation} instance.
*
* @param simulation
* the {@link org.eclipse.stem.jobs.simulation.Simulation}
* whose state will be visualized in the control.
*/
@Override
protected void initializeFromSimulation(final ISimulation simulation) {
simulationNameLabel.setText(simulation.getName());
propertySelectorX.setSimulation(simulation);
propertySelectorY.setSimulation(simulation);
} // initializeFromSimulation
/**
*
*/
@Override
public void refresh2() {
// nothing
} // refresh2
/**
* @see org.eclipse.swt.widgets.Widget#dispose()
*/
@Override
public void dispose() {
super.dispose();
if (this.rvhp != null) {
// Yes
rvhp.removeExtensionListener(this);
} // if
} // dispose
/**
* @see org.eclipse.stem.ui.reports.views.ReportControl#getIdentifiable()
*/
@Override
public Identifiable getIdentifiable() {
return identifiable;
}
/**
* This Control is associated with an Identifiable
* @see org.eclipse.stem.ui.reports.views.ReportControl#getControlType()
*/
public String getControlType() {
return ReportControlFactory.IDENTIFABLE_TYPE;
}
} // RelativeValueHistoryPlotter