Skip to content

Commit

Permalink
Support categories in data analysis time-series viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
yblanken committed Dec 14, 2023
1 parent a7af499 commit 407b70f
Show file tree
Hide file tree
Showing 16 changed files with 556 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public ExportImageAction() {
this(null, Activator.getDescriptor(Activator.IMAGE_EXPORT_IMAGE));
}

public ExportImageAction(ChartPanelComposite plotComposite) {
public ExportImageAction(@Nullable ChartPanelComposite plotComposite) {
this(plotComposite, Activator.getDescriptor(Activator.IMAGE_EXPORT_IMAGE));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package nl.esi.pps.common.emf.synchronizedtiming.jfree;


import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.trace4cps.common.jfreechart.ui.widgets.ChartPanelComposite;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.Title;

import nl.esi.pps.common.emf.synchronizedtiming.ui.Activator;

public class ShowLegendAction extends Action {
private @Nullable ChartPanelComposite chartPanelComposite;

public ShowLegendAction() {
this(null, Activator.getDescriptor(Activator.IMAGE_LEGEND_ONOFF));
}

public ShowLegendAction(@Nullable ChartPanelComposite plotComposite) {
this(plotComposite, Activator.getDescriptor(Activator.IMAGE_LEGEND_ONOFF));
}

public ShowLegendAction(@Nullable ChartPanelComposite chartPanelComposite, @Nullable ImageDescriptor imageDescriptor) {
super("Show Legend", IAction.AS_CHECK_BOX);
setImageDescriptor(imageDescriptor);
setToolTipText("If checked, this chart will show a legend.");
setChartPanelComposite(chartPanelComposite);
}

public void setChartPanelComposite(@Nullable ChartPanelComposite plotComposite) {
this.chartPanelComposite = plotComposite;
update();
}

protected @Nullable ChartPanelComposite getChartPanelComposite() {
return chartPanelComposite;
}

public void update() {
if (chartPanelComposite != null) {
JFreeChart chart = chartPanelComposite.getChart();
LegendTitle legend = chart == null ? null : chart.getLegend();
if (legend != null) {
setEnabled(true);
setChecked(legend.isVisible());
return;
}
}
setEnabled(false);
setChecked(false);
}

@Override
public void run() {
if (chartPanelComposite != null) {
JFreeChart chart = chartPanelComposite.getChart();
if (chart == null) {
return;
}

for (int i = 0; i < chart.getSubtitleCount(); i++) {
Title subtitle = chart.getSubtitle(i);
if (subtitle instanceof LegendTitle) {
subtitle.setVisible(isChecked());
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@

package nl.esi.pps.common.emf.synchronizedtiming.ui;

import static java.lang.String.format;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_DATASET_VIEW;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_EXPORT_IMAGE;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_LEGEND_ONOFF;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_MARGIN_SYNC;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_MARGIN_SYNC_ENABLED;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_TIME_SYNC;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_TIME_SYNC_ENABLED;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_ZOOM_OUT_HORIZONTAL;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_ZOOM_OUT_VERTICAL;
import static nl.esi.pps.common.emf.synchronizedtiming.ui.Activator.IMAGE_ZOOM_VIEW;
import static java.lang.String.format;

import java.awt.Rectangle;
import java.util.Collection;
Expand Down Expand Up @@ -58,12 +56,11 @@
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.plot.Zoomable;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.Title;

import nl.esi.pps.common.emf.synchronizedtiming.TimeSyncSupport;
import nl.esi.pps.common.emf.synchronizedtiming.TimeSyncSupportProvider;
import nl.esi.pps.common.emf.synchronizedtiming.jfree.ExportImageAction;
import nl.esi.pps.common.emf.synchronizedtiming.jfree.ShowLegendAction;

public abstract class SynchronizedTimingViewerPane extends ActionsViewerPane {
protected static final String GROUP_VIEW = "view";
Expand All @@ -83,7 +80,7 @@ public abstract class SynchronizedTimingViewerPane extends ActionsViewerPane {
protected final ZoomOutAction zoomOutAction = new ZoomOutAction();
protected final ZoomToSelectionXAction zoomToSelectionXAction = new ZoomToSelectionXAction();
protected final ZoomToSelectionYAction zoomToSelectionYAction = new ZoomToSelectionYAction();
protected final ShowLegendAction showLegendAction = new ShowLegendAction();
protected @Nullable ViewerShowLegendAction showLegendAction; // Initialized in 'createControl' method.
protected @Nullable ViewerExportImageAction exportImageAction; // Initialized in 'createControl' method.

public SynchronizedTimingViewerPane(IWorkbenchPage page, IWorkbenchPart part) {
Expand All @@ -104,7 +101,7 @@ public SynchronizedTimingViewerPane(IWorkbenchPage page, IWorkbenchPart part) {
return null;
}

private @Nullable ChartPanelComposite getChartPanelComposite() {
@Nullable ChartPanelComposite getChartPanelComposite() {
final ChartPanelViewer chartPanelViewer = getChartPanelViewer();
return chartPanelViewer == null ? null : chartPanelViewer.getChartPanelComposite();
}
Expand Down Expand Up @@ -202,11 +199,10 @@ protected void addNavigationActions() {

protected void addViewActions() {
exportImageAction = new ViewerExportImageAction(getChartPanelComposite());
showLegendAction = new ViewerShowLegendAction(getChartPanelComposite());

getMenuManager().appendToGroup(GROUP_VIEW, exportImageAction);
getMenuManager().appendToGroup(GROUP_VIEW, showLegendAction);

showLegendAction.update();
}

protected class TimeSyncAction extends Action {
Expand Down Expand Up @@ -437,7 +433,7 @@ public void run() {

protected class ViewerExportImageAction extends ExportImageAction {
public ViewerExportImageAction(@Nullable ChartPanelComposite chartPanelComposite) {
super(chartPanelComposite, Activator.getDescriptor(IMAGE_EXPORT_IMAGE));
super(chartPanelComposite);
}

@Override
Expand All @@ -462,48 +458,25 @@ public void run() {
super.run();
}
}

protected class ShowLegendAction extends Action {
public ShowLegendAction() {
super("Show Legend", IAction.AS_CHECK_BOX);
setImageDescriptor(Activator.getDescriptor(IMAGE_LEGEND_ONOFF));
setToolTipText("If checked, this chart will show a legend.");

protected class ViewerShowLegendAction extends ShowLegendAction {
public ViewerShowLegendAction(@Nullable ChartPanelComposite plotComposite) {
super(plotComposite);
}

public void update() {
ChartPanelComposite chartPanelComposite = getChartPanelComposite();
JFreeChart chart = null == chartPanelComposite ? null : chartPanelComposite.getChart();
LegendTitle legend = null == chart ? null : chart.getLegend();
setVisible(null != legend);
setChecked(null != legend && legend.isVisible());
}

protected void setVisible(boolean visible) {
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);

// Also hide the action if disabled
for (IContributionItem item : getToolBarManager().getItems()) {
if (item instanceof ActionContributionItem && ((ActionContributionItem)item).getAction() == ShowLegendAction.this) {
item.setVisible(visible);
if (item instanceof ActionContributionItem && ((ActionContributionItem)item).getAction() == ViewerShowLegendAction.this) {
item.setVisible(enabled);
}
}
for (IContributionItem item : getMenuManager().getItems()) {
if (item instanceof ActionContributionItem && ((ActionContributionItem)item).getAction() == ShowLegendAction.this) {
item.setVisible(visible);
}
}
}

@Override
public void run() {
ChartPanelComposite chartPanelComposite = getChartPanelComposite();
if (null == chartPanelComposite) return;
ChartPanel chartPanel = chartPanelComposite.getChartPanel();
if (null == chartPanel) return;
JFreeChart chart = chartPanel.getChart();
if (null == chart) return;

for (int i = 0; i < chart.getSubtitleCount(); i++) {
Title subtitle = chart.getSubtitle(i);
if (subtitle instanceof LegendTitle) {
subtitle.setVisible(isChecked());
if (item instanceof ActionContributionItem && ((ActionContributionItem)item).getAction() == ViewerShowLegendAction.this) {
item.setVisible(enabled);
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion plugins/nl.esi.pps.tmsc.analysis.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
id="nl.esi.pps.tmsc.analysis.ui.fragment"
point="org.eclipse.e4.workbench.model">
<fragment
apply="initial"
uri="fragment.e4xmi">
</fragment>
</extension>
Expand Down Expand Up @@ -45,6 +44,16 @@
eclass_uri="http://www.esi.nl/pps/tmsc#Dependency"
id="nl.esi.pps.tmsc.analysis.ui.dataanalysis.TimeBoundOutlierDataAnalysisItemContentProvider">
</DataAnalysis>
<DataAnalysis
content_provider="nl.esi.pps.tmsc.analysis.ui.dataanalysis.MetricActivityIsomorphismClassesContentProvider"
eclass_uri="http://www.esi.nl/tmsc/metric#Metric"
id="nl.esi.pps.tmsc.analysis.ui.dataanalysis.MetricActivityIsomorphismClassesContentProvider$Metric">
</DataAnalysis>
<DataAnalysis
content_provider="nl.esi.pps.tmsc.analysis.ui.dataanalysis.MetricActivityIsomorphismClassesContentProvider"
eclass_uri="http://www.esi.nl/tmsc/metric#MetricInstance"
id="nl.esi.pps.tmsc.analysis.ui.dataanalysis.MetricActivityIsomorphismClassesContentProvider$MetricInstance">
</DataAnalysis>
</extension>

</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package nl.esi.pps.tmsc.analysis.ui.dataanalysis

import nl.esi.pps.tmsc.ScopedTMSC
import nl.esi.pps.tmsc.metric.MetricInstance
import nl.esi.pps.tmsc.metric.provider.dataanalysis.MetricDataAnalysisItemContentProvider

import static extension nl.esi.pps.tmsc.analysis.ui.handlers.CreateMetricActivityIsomorphismClassesHelper.*

class MetricActivityIsomorphismClassesContentProvider extends MetricDataAnalysisItemContentProvider {
override getConfigurations(Object object) {
return object.metric.instances.flatMap[scopes].map[configuration].filterNull.toSet
}

override String getTitle(Object object, String configuration) {
return object.metric.name + ' - ' + configuration
}

override isCategorized(Object object, String configuration) {
return true
}

override getCategory(Object object, Object sibling, String configuration) {
if (sibling instanceof MetricInstance) {
val isomorphismClass = sibling.scopes.findFirst[s | s.configuration == configuration]?.isomorphismClass
if (isomorphismClass !== null) {
return 'Isomorphism class ' + isomorphismClass
}
}
return super.getCategory(object, sibling, configuration)
}

protected def String getConfiguration(ScopedTMSC tmsc) {
val isomorphismStage = tmsc.isomorphismStage
if (isomorphismStage === null) {
return null
}
val isomorphismType = tmsc.isomorphismType
if (isomorphismType === null) {
return null
}
return isomorphismStage + ' ' + isomorphismType
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@

package nl.esi.pps.tmsc.analysis.ui.handlers;

import static org.eclipse.lsat.common.queries.QueryableIterable.from;
import static nl.esi.pps.tmsc.analysis.ui.handlers.CreateMetricActivityIsomorphismClassesHelper.createIsomorphismClasses;

import java.text.DecimalFormat;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

import javax.inject.Named;

Expand Down Expand Up @@ -43,19 +40,13 @@

import nl.esi.pps.preferences.PPSPreferences;
import nl.esi.pps.tmsc.ScopedTMSC;
import nl.esi.pps.tmsc.TMSC;
import nl.esi.pps.tmsc.TmscFactory;
import nl.esi.pps.tmsc.analysis.ui.commands.CreateScopedTMSCCommand;
import nl.esi.pps.tmsc.compare.ArchitectureLifecycleStage;
import nl.esi.pps.tmsc.compare.TmscIsomorphismMatcher;
import nl.esi.pps.tmsc.metric.Metric;
import nl.esi.pps.tmsc.rendering.plot.ScopesRenderingStrategy;
import nl.esi.pps.tmsc.util.TmscQueries;

public class CreateMetricActivityIsomorphismClassesHandler extends CreateScopedTMSCCommandHandler {
private static final DecimalFormat INDEX_FORMAT = new DecimalFormat("000");
private static final String INDEX_PROPERTY = "Isomorphism class";

public CreateMetricActivityIsomorphismClassesHandler() {
super("create isomorphism classes of TMSCs");
}
Expand Down Expand Up @@ -107,45 +98,19 @@ protected boolean prepare() {
}

@Override
@SuppressWarnings("deprecation")
protected ScopedTMSC createScopedTMSC(MultiStatus status, IProgressMonitor monitor) {
ScopedTMSC tmsc = super.createScopedTMSC(status, monitor);
// Apply some rendering hints such that this scope isn't grouped by the renderer
ScopesRenderingStrategy.setGroupKey(tmsc, false);

List<List<ScopedTMSC>> isomorphismClasses = TmscIsomorphismMatcher.findIsomorphismClasses(
metric.getInstances().stream().map(strategy::createTMSC).iterator(), stage);
// Apply some rendering hints such that these scopes aren't grouped by the renderer
from(isomorphismClasses).collect(Function.identity()).closure(true, TMSC::getChildScopes)
.forEach(scope -> ScopesRenderingStrategy.setGroupKey(scope, false));

for (int index = 0; index < isomorphismClasses.size(); index++) {
List<ScopedTMSC> isomorphicTMSCs = isomorphismClasses.get(index);
ScopedTMSC isomorphismClassTMSC = TmscFactory.eINSTANCE.createScopedTMSC();
isomorphismClassTMSC.setName(TmscQueries
.toEID(String.format("Isomorphism class %s %d %d", INDEX_FORMAT.format(index + 1),
isomorphicTMSCs.size(), isomorphicTMSCs.get(0).getDependencies().size())));
isomorphismClassTMSC.getProperties().put(INDEX_PROPERTY, INDEX_FORMAT.format(index + 1));
isomorphismClassTMSC.getChildScopes().addAll(isomorphicTMSCs);

// All dependencies of a child scope should also be contained by its parent scope.
isomorphismClassTMSC.getChildScopes().forEach(
childScope -> isomorphismClassTMSC.getDependencies().addAll(childScope.getDependencies()));

// IsomorphismClassTMSC itself is child-scope of tmsc
tmsc.getChildScopes().add(isomorphismClassTMSC);
tmsc.getDependencies().addAll(isomorphismClassTMSC.getDependencies());
for (ScopedTMSC isomorphismClass : createIsomorphismClasses(metric, strategy, stage)) {
TmscQueries.addScopedTMSC(tmsc, isomorphismClass);
}

return tmsc;
}
}

@SuppressWarnings("deprecation")
public static String getIsomorphismClassIndex(TMSC tmsc) {
return (String) tmsc.getProperties().get(INDEX_PROPERTY);
}

private static class StrategyAndStageSelectionDialog extends CreateIntervalActivityStrategy.StrategySelectionDialog {
private ArchitectureLifecycleStage stage = ArchitectureLifecycleStage.IMPLEMENTED;

Expand Down
Loading

0 comments on commit 407b70f

Please sign in to comment.