From: lempinen Date: Wed, 7 Dec 2011 11:05:38 +0000 (+0000) Subject: two new chart types: bar and pie X-Git-Tag: simantics-1.6~79 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=41ad5302f5aae276c6036bc6206c84e25b637602;p=simantics%2Fsysdyn.git two new chart types: bar and pie git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@23432 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.jfreechart.ontology/graph.tg b/org.simantics.jfreechart.ontology/graph.tg index 208c3be8..923bca85 100644 Binary files a/org.simantics.jfreechart.ontology/graph.tg and b/org.simantics.jfreechart.ontology/graph.tg differ diff --git a/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph b/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph index d6f115d9..e6a3a70c 100644 --- a/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph +++ b/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph @@ -72,6 +72,7 @@ JFREE.NumberAxis -- JFREE.Dataset.seriesList --> L0.List -- JFREE.Dataset.renderer --> JFREE.Renderer -- JFREE.Dataset.mapToDomainAxis --> JFREE.Axis -- JFREE.Dataset.mapToRangeAxis --> JFREE.Axis -- JFREE.variableRVI --> L0.String -- JFREE.Series.lineWidth --> L0.Integer -- JFREE.color + >-- JFREE.variableRVI --> L0.String -- JFREE.Series.lineWidth --> L0.Integer -- JFREE.Series.exploded --> L0.Boolean -- JFREE.Series.time --> L0.Double -VP = -PROJECT = -MOD = -IMAGE = -COLOR = -ACT = -JFREE = -SYSDYN = - -CBC = SYSDYN.ChartAxisAndVariablesBrowseContext : VP.BrowseContext -CAC = SYSDYN.ChartAxisAndVariablesActionContext : VP.BrowseContext - -CBC.AxisChildRule : VP.ChildRule -CBC.VariableChildRule : VP.ChildRule -CBC.SeriesLabelRule : VP.LabelRule -CBC.AxisLabelRule : VP.LabelRule - -CBC - @VP.customChildRule JFREE.Chart CBC.AxisChildRule - JFREE.Axis : VP.ResourceNodeType - @VP.customChildRule JFREE.Axis CBC.VariableChildRule - JFREE.Series : VP.ResourceNodeType - -CBC - @VP.customLabelRule JFREE.Axis CBC.AxisLabelRule - @VP.customLabelRule JFREE.Series CBC.SeriesLabelRule - -CBC - @VP.dropActionContribution JFREE.Axis ACTIONS.SeriesDropAction 1.0 - @VP.dropActionContribution JFREE.Series ACTIONS.SeriesDropAction 1.0 - @VP.dropActionContribution JFREE.Axis ACTIONS.AxisDropAction 2.0 - @VP.dropActionContribution JFREE.Series ACTIONS.AxisDropAction 2.0 - -CBC - VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution - VP.VisualsContribution.HasNodeType JFREE.Chart - VP.VisualsContribution.HasRule VP.PassThruSorterRule - VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution - VP.VisualsContribution.HasNodeType JFREE.Axis - VP.VisualsContribution.HasRule VP.PassThruSorterRule - - -ACTIONS = CAC.Actions : L0.Library -ACTIONS.SeriesDropAction : ACT.DropAction -ACTIONS.AxisDropAction : ACT.DropAction \ No newline at end of file diff --git a/org.simantics.sysdyn.ontology/graph/ChartViewpoints.pgraph b/org.simantics.sysdyn.ontology/graph/ChartViewpoints.pgraph new file mode 100644 index 00000000..c916c172 --- /dev/null +++ b/org.simantics.sysdyn.ontology/graph/ChartViewpoints.pgraph @@ -0,0 +1,105 @@ +L0 = +VP = +PROJECT = +MOD = +IMAGE = +COLOR = +ACT = +JFREE = +SYSDYN = + +/////////////////////////////////////////////// +// XY Line axis: axis and variables viewpoint +/////////////////////////////////////////////// +CBC = SYSDYN.ChartAxisAndVariablesBrowseContext : VP.BrowseContext +CAC = SYSDYN.ChartAxisAndVariablesActionContext : VP.BrowseContext + +CBC.AxisChildRule : VP.ChildRule +CBC.VariableChildRule : VP.ChildRule +CBC.SeriesLabelRule : VP.LabelRule +CBC.AxisLabelRule : VP.LabelRule + +CBC + @VP.customChildRule JFREE.Chart CBC.AxisChildRule + JFREE.Axis : VP.ResourceNodeType + @VP.customChildRule JFREE.Axis CBC.VariableChildRule + JFREE.Series : VP.ResourceNodeType + +CBC + @VP.customLabelRule JFREE.Axis CBC.AxisLabelRule + @VP.customLabelRule JFREE.Series CBC.SeriesLabelRule + +CBC + @VP.dropActionContribution JFREE.Axis CAC.Actions.SeriesDropAction 1.0 + @VP.dropActionContribution JFREE.Series CAC.Actions.SeriesDropAction 1.0 + @VP.dropActionContribution JFREE.Axis CAC.Actions.AxisDropAction 2.0 + @VP.dropActionContribution JFREE.Series CAC.Actions.AxisDropAction 2.0 + +CBC + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Chart + VP.VisualsContribution.HasRule VP.PassThruSorterRule + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Axis + VP.VisualsContribution.HasRule VP.PassThruSorterRule + + +CAC.Actions : L0.Library +CAC.Actions.SeriesDropAction : ACT.DropAction +CAC.Actions.AxisDropAction : ACT.DropAction + + +/////////////////////////////////////////////// +// Bar chart: Variables viewpoint +/////////////////////////////////////////////// +BSBC = SYSDYN.BarSeriesBrowseContext : VP.BrowseContext +BSAC = SYSDYN.BarSeriesActionContext : VP.BrowseContext + +BSBC.SeriesChildRule : VP.ChildRule +BSBC.SeriesLabelRule : VP.LabelRule + +BSBC + @VP.customChildRule JFREE.Chart BSBC.SeriesChildRule + JFREE.Series + +BSBC + @VP.customLabelRule JFREE.Series BSBC.SeriesLabelRule + +//BSBC +// @VP.dropActionContribution JFREE.Series BSAC.Actions.SeriesDropAction 1.0 + +BSBC + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Chart + VP.VisualsContribution.HasRule VP.PassThruSorterRule + +BSAC.Actions : L0.Library +//BSAC.Actions.SeriesDropAction : ACT.DropAction + + +/////////////////////////////////////////////// +// Pie chart: Variables viewpoint +/////////////////////////////////////////////// +PSBC = SYSDYN.PieSeriesBrowseContext : VP.BrowseContext +PSAC = SYSDYN.PieSeriesActionContext : VP.BrowseContext + +PSBC.SeriesChildRule : VP.ChildRule +PSBC.SeriesLabelRule : VP.LabelRule + +PSBC + @VP.customChildRule JFREE.Chart PSBC.SeriesChildRule + JFREE.Series + +PSBC + @VP.customLabelRule JFREE.Series PSBC.SeriesLabelRule + +//PSBC +// @VP.dropActionContribution JFREE.Series PSAC.Actions.SeriesDropAction 1.0 + +PSBC + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Chart + VP.VisualsContribution.HasRule VP.PassThruSorterRule + +PSAC.Actions : L0.Library +//PSAC.Actions.SeriesDropAction : ACT.DropAction diff --git a/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java b/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java index 4ce26dbd..c8ad7f0f 100644 --- a/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java +++ b/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java @@ -17,6 +17,11 @@ public class SysdynResource { public final Resource AuxiliarySymbol; public final Resource AvailableSharedFunctionLibraries; public final Resource AvailableVariableIndexes; + public final Resource BarSeriesActionContext; + public final Resource BarSeriesActionContext_Actions; + public final Resource BarSeriesBrowseContext; + public final Resource BarSeriesBrowseContext_SeriesChildRule; + public final Resource BarSeriesBrowseContext_SeriesLabelRule; public final Resource BasicExperiment; public final Resource Bottom; public final Resource Browser; @@ -181,6 +186,11 @@ public class SysdynResource { public final Resource NormalExpression; public final Resource Orientation; public final Resource ParameterExpression; + public final Resource PieSeriesActionContext; + public final Resource PieSeriesActionContext_Actions; + public final Resource PieSeriesBrowseContext; + public final Resource PieSeriesBrowseContext_SeriesChildRule; + public final Resource PieSeriesBrowseContext_SeriesLabelRule; public final Resource PlaybackExperiment; public final Resource Polarity; public final Resource PolarityLocation; @@ -289,6 +299,11 @@ public class SysdynResource { public static final String AuxiliarySymbol = "http://www.simantics.org/Sysdyn-1.1/AuxiliarySymbol"; public static final String AvailableSharedFunctionLibraries = "http://www.simantics.org/Sysdyn-1.1/AvailableSharedFunctionLibraries"; public static final String AvailableVariableIndexes = "http://www.simantics.org/Sysdyn-1.1/AvailableVariableIndexes"; + public static final String BarSeriesActionContext = "http://www.simantics.org/Sysdyn-1.1/BarSeriesActionContext"; + public static final String BarSeriesActionContext_Actions = "http://www.simantics.org/Sysdyn-1.1/BarSeriesActionContext/Actions"; + public static final String BarSeriesBrowseContext = "http://www.simantics.org/Sysdyn-1.1/BarSeriesBrowseContext"; + public static final String BarSeriesBrowseContext_SeriesChildRule = "http://www.simantics.org/Sysdyn-1.1/BarSeriesBrowseContext/SeriesChildRule"; + public static final String BarSeriesBrowseContext_SeriesLabelRule = "http://www.simantics.org/Sysdyn-1.1/BarSeriesBrowseContext/SeriesLabelRule"; public static final String BasicExperiment = "http://www.simantics.org/Sysdyn-1.1/BasicExperiment"; public static final String Bottom = "http://www.simantics.org/Sysdyn-1.1/Bottom"; public static final String Browser = "http://www.simantics.org/Sysdyn-1.1/Browser"; @@ -453,6 +468,11 @@ public class SysdynResource { public static final String NormalExpression = "http://www.simantics.org/Sysdyn-1.1/NormalExpression"; public static final String Orientation = "http://www.simantics.org/Sysdyn-1.1/Orientation"; public static final String ParameterExpression = "http://www.simantics.org/Sysdyn-1.1/ParameterExpression"; + public static final String PieSeriesActionContext = "http://www.simantics.org/Sysdyn-1.1/PieSeriesActionContext"; + public static final String PieSeriesActionContext_Actions = "http://www.simantics.org/Sysdyn-1.1/PieSeriesActionContext/Actions"; + public static final String PieSeriesBrowseContext = "http://www.simantics.org/Sysdyn-1.1/PieSeriesBrowseContext"; + public static final String PieSeriesBrowseContext_SeriesChildRule = "http://www.simantics.org/Sysdyn-1.1/PieSeriesBrowseContext/SeriesChildRule"; + public static final String PieSeriesBrowseContext_SeriesLabelRule = "http://www.simantics.org/Sysdyn-1.1/PieSeriesBrowseContext/SeriesLabelRule"; public static final String PlaybackExperiment = "http://www.simantics.org/Sysdyn-1.1/PlaybackExperiment"; public static final String Polarity = "http://www.simantics.org/Sysdyn-1.1/Polarity"; public static final String PolarityLocation = "http://www.simantics.org/Sysdyn-1.1/PolarityLocation"; @@ -571,6 +591,11 @@ public class SysdynResource { AuxiliarySymbol = getResourceOrNull(graph, URIs.AuxiliarySymbol); AvailableSharedFunctionLibraries = getResourceOrNull(graph, URIs.AvailableSharedFunctionLibraries); AvailableVariableIndexes = getResourceOrNull(graph, URIs.AvailableVariableIndexes); + BarSeriesActionContext = getResourceOrNull(graph, URIs.BarSeriesActionContext); + BarSeriesActionContext_Actions = getResourceOrNull(graph, URIs.BarSeriesActionContext_Actions); + BarSeriesBrowseContext = getResourceOrNull(graph, URIs.BarSeriesBrowseContext); + BarSeriesBrowseContext_SeriesChildRule = getResourceOrNull(graph, URIs.BarSeriesBrowseContext_SeriesChildRule); + BarSeriesBrowseContext_SeriesLabelRule = getResourceOrNull(graph, URIs.BarSeriesBrowseContext_SeriesLabelRule); BasicExperiment = getResourceOrNull(graph, URIs.BasicExperiment); Bottom = getResourceOrNull(graph, URIs.Bottom); Browser = getResourceOrNull(graph, URIs.Browser); @@ -735,6 +760,11 @@ public class SysdynResource { NormalExpression = getResourceOrNull(graph, URIs.NormalExpression); Orientation = getResourceOrNull(graph, URIs.Orientation); ParameterExpression = getResourceOrNull(graph, URIs.ParameterExpression); + PieSeriesActionContext = getResourceOrNull(graph, URIs.PieSeriesActionContext); + PieSeriesActionContext_Actions = getResourceOrNull(graph, URIs.PieSeriesActionContext_Actions); + PieSeriesBrowseContext = getResourceOrNull(graph, URIs.PieSeriesBrowseContext); + PieSeriesBrowseContext_SeriesChildRule = getResourceOrNull(graph, URIs.PieSeriesBrowseContext_SeriesChildRule); + PieSeriesBrowseContext_SeriesLabelRule = getResourceOrNull(graph, URIs.PieSeriesBrowseContext_SeriesLabelRule); PlaybackExperiment = getResourceOrNull(graph, URIs.PlaybackExperiment); Polarity = getResourceOrNull(graph, URIs.Polarity); PolarityLocation = getResourceOrNull(graph, URIs.PolarityLocation); diff --git a/org.simantics.sysdyn.ui/adapters.xml b/org.simantics.sysdyn.ui/adapters.xml index 658f0808..dd09c0f4 100644 --- a/org.simantics.sysdyn.ui/adapters.xml +++ b/org.simantics.sysdyn.ui/adapters.xml @@ -10,5 +10,5 @@ VTT Technical Research Centre of Finland - initial API and implementation --> - none 0 fill 1 + none 0 fill 1 \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/plugin.xml b/org.simantics.sysdyn.ui/plugin.xml index fdc1a04b..b576aade 100644 --- a/org.simantics.sysdyn.ui/plugin.xml +++ b/org.simantics.sysdyn.ui/plugin.xml @@ -564,9 +564,41 @@ + + + + + + + + + + + + + + + + @@ -937,9 +969,19 @@ name="Chart Panel Orientation"> + defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewXYLineChartHandler" + id="org.simantics.sysdyn.ui.newXYLineChart" + name="New XY Line Chart"> + + + + emptyList()), + jfree.Dataset_renderer, renderer); + + GraphUtils.create2(g, jfree.CategoryPlot, + l0.HasName, "Category plot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + jfree.Plot_domainAxis, domainAxis, + jfree.Plot_rangeAxis, rangeAxis, + jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)), + l0.ConsistsOf, dataset, + l0.ConsistsOf, domainAxis, + l0.ConsistsOf, rangeAxis); + } + + }); + + return null; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java new file mode 100644 index 00000000..516e49f9 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.Collections; +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.AdaptionUtils; + +/** + * Handler for craeting a new Pie Chart + * @author Teemu Lempinen + * + */ +public class NewPieChartHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + G2DResource g2d = G2DResource.getInstance(g); + + Resource jfreechart = GraphUtils.create2(g, jfree.Chart, + l0.HasName, "PieChart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(g, "Pie Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3); + g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + GraphUtils.create2(g, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Pie Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + Resource dataset = GraphUtils.create2(g, jfree.PieDataset, + l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(), + jfree.Dataset_seriesList, ListUtils.create(g, Collections.emptyList()) + ); + + GraphUtils.create2(g, jfree.PiePlot, + l0.HasName, "PiePlot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + l0.ConsistsOf, dataset + ); + } + + }); + + return null; + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java similarity index 91% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewChartHandler.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java index 85d44c57..46b44408 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewChartHandler.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java @@ -30,17 +30,16 @@ import org.simantics.diagram.stubs.G2DResource; import org.simantics.layer0.Layer0; import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.sysdyn.JFreeChartResource; -import org.simantics.sysdyn.ui.browser.nodes.ChartNode; import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; import org.simantics.ui.SimanticsUI; import org.simantics.ui.utils.AdaptionUtils; /** - * Handler for creating a new {@link ChartNode} in model browser + * Handler for creating a new XYLineChart in model browser * @author Teemu Lempinen * */ -public class NewChartHandler extends AbstractHandler { +public class NewXYLineChartHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { @@ -77,11 +76,9 @@ public class NewChartHandler extends AbstractHandler { l0.PartOf, jfreechart); Resource domainAxis = GraphUtils.create2(g, jfree.NumberAxis, - l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), - l0.HasLabel, "Domain"); + l0.HasName, "NumberAxis" + UUID.randomUUID().toString()); Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis, - l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), - l0.HasLabel, "Range"); + l0.HasName, "NumberAxis" + UUID.randomUUID().toString()); Resource dataset = GraphUtils.create2(g, jfree.XYDataset, l0.HasName, "XYDataset" + UUID.randomUUID().toString(), diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java index 50bd0480..8c678cac 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java @@ -40,6 +40,12 @@ import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; import org.simantics.sysdyn.ui.editor.DiagramViewer; import org.simantics.ui.SimanticsUI; +/** + * Listener for playback simulations. This listener activates and reverts the playback + * profile when a playback simlation is activated or disposed. + * @author Teemu Lempinen + * + */ public class SysdynPlaybackExperimentListener implements IExperimentListener { private Resource model; @@ -215,7 +221,8 @@ public class SysdynPlaybackExperimentListener implements IExperimentListener { Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); if(profile.equals(current)) return; - graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current); + if(current != null) + graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current); graph.claim(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, profile); // Set this profile as the default profile for this diagram diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java index cdb54df4..f16927eb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java @@ -35,6 +35,13 @@ import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; import org.simantics.ui.SimanticsUI; +/** + * Contribution to the main toolbar. PlaybackSliderContribution contains a slider + * that can be used to control the time in a playback experiment + * + * @author Teemu Lempinen + * + */ public class PlaybackSliderContribution extends ToolBarContributionItem { Runnable timeListener; @@ -72,6 +79,7 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { e1.printStackTrace(); } + // Separator ToolItem can contain a composite. Add a composite with a slider to this item ToolItem ti = new ToolItem(parent, SWT.SEPARATOR); Composite composite = new Composite(parent, SWT.NONE); @@ -94,6 +102,8 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { startTime = numbers[0]; endTime = numbers[1]; + + // Create a DesimalFormat for rounding the time final DecimalFormat format = new DecimalFormat(); format.setMinimumFractionDigits(0); format.setMaximumFractionDigits(2); @@ -101,6 +111,8 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { symbols.setDecimalSeparator('.'); symbols.setGroupingSeparator(' '); format.setDecimalFormatSymbols(symbols); + + // Selection listener for the slider s.addSelectionListener(new SelectionListener() { @Override @@ -122,6 +134,7 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { spe.removeTimeListener(timeListener); } + // Time listener for setting the time in the slider if the time is changed somewhere else timeListener = new Runnable() { @Override @@ -134,7 +147,7 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { startTime = spe.getStartTime(); endTime = spe.getEndTime(); } - int value = (int) ((spe.getTime() - startTime) / (endTime - startTime) * 99); + int value = (int) Math.round(((spe.getTime() - startTime) / (endTime - startTime) * 99)); s.setSelection(value); label.setText(format.format(spe.getTime())); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java index ad0a573f..35e7c357 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java @@ -33,75 +33,69 @@ import org.simantics.utils.datastructures.Callback; public abstract class LabelPropertyTabContributor extends PropertyTabContributorImpl { - private boolean isDisposed = false; - - - public void createControl(Composite parent, final IWorkbenchSite site, final ISessionContext context, final WidgetSupportImpl support) { - super.createControl(parent, site, context, support); - - // Add dispose listener to make sure name listening receives the correct isDisposed -value - parent.addDisposeListener(new DisposeListener() { - - @Override - public void widgetDisposed(DisposeEvent e) { - LabelPropertyTabContributor.this.dispose(); - } - }); - } - - @Override + private boolean isDisposed = false; + + + public void createControl(Composite parent, final IWorkbenchSite site, final ISessionContext context, final WidgetSupportImpl support) { + super.createControl(parent, site, context, support); + + // Add dispose listener to make sure name listening receives the correct isDisposed -value + parent.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + LabelPropertyTabContributor.this.dispose(); + } + }); + } + + @Override public void updatePartName(ISelection forSelection, final Callback updateCallback) { - final Resource resource = AdaptionUtils.adaptToSingle(forSelection, Resource.class); - if(resource == null) { - updateCallback.run("Selection properties"); - return; - } - - try { - SimanticsUI.getSession().syncRequest(new Read() { + final Resource resource = AdaptionUtils.adaptToSingle(forSelection, Resource.class); + if(resource == null) { + updateCallback.run("Selection properties"); + return; + } + + SimanticsUI.getSession().asyncRequest(new Read() { - @Override - public String perform(ReadGraph graph) throws DatabaseException { - Layer0 l0 = Layer0.getInstance(graph); - ModelingResources mr = ModelingResources.getInstance(graph); - Resource r = resource; - if(graph.hasStatement(r, mr.ElementToComponent)) { - r = graph.getSingleObject(r, mr.ElementToComponent); - } - String label = graph.getPossibleRelatedValue(r, l0.HasLabel); - if(label != null) - return label; - label = graph.getPossibleRelatedValue(r, l0.HasName); - if(label != null) - return label; - return "No name for selection"; - } - }, new AsyncListener() { + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + Resource r = resource; + if(graph.hasStatement(r, mr.ElementToComponent)) { + r = graph.getSingleObject(r, mr.ElementToComponent); + } + String label = graph.getPossibleRelatedValue(r, l0.HasLabel); + if(label != null) + return label; + label = graph.getPossibleRelatedValue(r, l0.HasName); + if(label != null) + return label; + return "No name for selection"; + } + }, new AsyncListener() { - @Override - public void execute(AsyncReadGraph graph, String result) { - updateCallback.run(result); - } + @Override + public void execute(AsyncReadGraph graph, String result) { + updateCallback.run(result); + } - @Override - public void exception(AsyncReadGraph graph, Throwable throwable) { - - } + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { - @Override - public boolean isDisposed() { - return isDisposed; - } - }); - } catch (DatabaseException e) { - updateCallback.run("Selection error in LabelPropertyTabContributor"); - e.printStackTrace(); - } - + } + + @Override + public boolean isDisposed() { + return isDisposed; + } + }); } - + @Override protected void dispose() { - this.isDisposed = true; + this.isDisposed = true; } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java index d0f4851d..1fb72a78 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java @@ -19,6 +19,7 @@ import java.util.List; import org.eclipse.jface.viewers.ISelection; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; @@ -32,9 +33,13 @@ import org.simantics.simulation.ontology.SimulationResource; import org.simantics.sysdyn.JFreeChartResource; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder; -import org.simantics.sysdyn.ui.trend.chart.properties.ChartAxisAndVariablesTab; import org.simantics.sysdyn.ui.trend.chart.properties.ChartTab; -import org.simantics.sysdyn.ui.trend.chart.properties.GeneralChartPropertiesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.bar.BarGeneralPropertiesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.bar.BarSeriesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.pie.PieGeneralPropertiesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.pie.PieSeriesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.xyline.XYLineAxisAndVariablesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.xyline.XYLineGeneralPropertiesTab; import org.simantics.ui.utils.AdaptionUtils; /** @@ -108,7 +113,7 @@ public class ResourceSelectionProcessor implements SelectionProcessor plots = backend.syncRequest(new ObjectsWithType(r, Layer0.getInstance(backend).ConsistsOf, jfree.Plot)); + if(!plots.isEmpty()) { + Resource plot = plots.iterator().next(); + + if(backend.isInstanceOf(plot, jfree.XYPlot)) { + tabs.add(new ComparableTabContributor( + new XYLineGeneralPropertiesTab(), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new XYLineAxisAndVariablesTab(), + 9, + r, + "Axis and Variables")); + } else if(backend.isInstanceOf(plot, jfree.CategoryPlot)) { + tabs.add(new ComparableTabContributor( + new BarGeneralPropertiesTab(), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new BarSeriesTab(), + 9, + r, + "Variables")); + } else if(backend.isInstanceOf(plot, jfree.PiePlot)) { + tabs.add(new ComparableTabContributor( + new PieGeneralPropertiesTab(), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new PieSeriesTab(), + 9, + r, + "Variables")); + } + + tabs.add(new ComparableTabContributor( + new ChartTab(), + 1, + r, + "Chart")); + return tabs; + + } } } catch (ServiceException e) { diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractAxis.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractAxis.java new file mode 100644 index 00000000..3f6e7bf1 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractAxis.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import java.awt.Color; + +import org.jfree.chart.axis.Axis; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.G2DUtils; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Abstract axis class for all JFreeChart axis + * @author Teemu Lempinen + * + */ +public abstract class AbstractAxis implements IAxis { + + protected Axis axis; + protected String label; + protected Boolean tMarksVisible, tLabelsVisible, labelVisible, lineVisible; + protected Color color; + protected Double min, max; + + /** + * + * @param graph ReadGraph + * @param axisResource resource of type JFreeChart.NumberAxis + */ + public AbstractAxis(ReadGraph graph, Resource axisResource) { + try { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + label = graph.getPossibleRelatedValue(axisResource, l0.HasLabel); + tMarksVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleTickMarks, Bindings.BOOLEAN); + tLabelsVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleTickLabels, Bindings.BOOLEAN); + labelVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleLabel, Bindings.BOOLEAN); + lineVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleAxisLine, Bindings.BOOLEAN); + Resource c = graph.getPossibleObject(axisResource, jfree.color); + color = c == null ? null : G2DUtils.getColor(graph, c); + min = graph.getPossibleRelatedValue(axisResource, jfree.Axis_min, Bindings.DOUBLE); + max = graph.getPossibleRelatedValue(axisResource, jfree.Axis_max, Bindings.DOUBLE); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void dispose() { + + } + + @Override + public Axis getAxis() { + if(tMarksVisible != null && tMarksVisible == false) + axis.setTickMarksVisible(false); + if(tLabelsVisible != null && tLabelsVisible == false) + axis.setTickLabelsVisible(false); + if(lineVisible != null && lineVisible == false) + axis.setAxisLineVisible(false); + + if(color != null) { + axis.setAxisLinePaint(color); + axis.setLabelPaint(color); + axis.setTickLabelPaint(color); + axis.setTickMarkPaint(color); + } + // label exists and its visibility == null or true + if((labelVisible == null || labelVisible == true) && label != null) + axis.setLabel(label); + return axis; + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractDataset.java new file mode 100644 index 00000000..31a91128 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractDataset.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + + +/** + * Abstract dataset class for all JFreeChart datasets + * + * @author Teemu Lempinen + * + */ +public abstract class AbstractDataset implements IDataset { + + protected Resource resource; + + public AbstractDataset(ReadGraph graph, Resource resource) { + this.resource = resource; + } + + @Override + public void dispose() { + + } + + @Override + public Resource getResource() { + return resource; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractPlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractPlot.java new file mode 100644 index 00000000..e38b641a --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractPlot.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.jfree.chart.axis.Axis; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Abstract plot class for all JFreeChart plots + * + * @author Teemu Lempinen + * + */ +public abstract class AbstractPlot implements IPlot { + + protected Resource resource; + protected ArrayList ranges; + protected ArrayList domains; + protected ArrayList datasets; + protected HashMap rangeMappings; + protected HashMap domainMappings; + + public AbstractPlot(ReadGraph graph, Resource resource) { + this.resource = resource; + + try { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + HashMap axisMap = new HashMap(); + ranges = new ArrayList(); + + // Get all range axis + Resource rangeList = graph.getPossibleObject(resource, jfree.Plot_rangeAxisList); + if(rangeList != null) { + for(Resource axisResource : ListUtils.toList(graph, rangeList)) { + IAxis axis = graph.adapt(axisResource, IAxis.class); + if(axis.getAxis() instanceof Axis) { + ranges.add(axis); + axisMap.put(axisResource, axis); + } + } + } + + // Get all domain axis + // There usually is only one domain axis, but this supports also multiple domain axis + domains = new ArrayList(); + for(Resource axisResource : graph.syncRequest(new ObjectsWithType(resource, jfree.Plot_domainAxis, jfree.Axis))) { + IAxis axis = graph.adapt(axisResource, IAxis.class); + if(axis.getAxis() instanceof Axis) { + domains.add(axis); + axisMap.put(axisResource, axis); + } + } + + // Get all datasets and map them to axis + datasets = new ArrayList(); + rangeMappings = new HashMap(); + domainMappings = new HashMap(); + for(Resource datasetResource : graph.syncRequest(new ObjectsWithType(resource, l0.ConsistsOf, jfree.Dataset))) { + IDataset dataset = graph.adapt(datasetResource, IDataset.class); + if(dataset != null) { + datasets.add(dataset); + Resource axisResource = graph.getPossibleObject(datasetResource, jfree.Dataset_mapToRangeAxis); + IAxis axis; + if(axisMap.containsKey(axisResource)) { + axis = axisMap.get(axisResource); + rangeMappings.put(dataset, axis); + } + + axisResource = graph.getPossibleObject(datasetResource, jfree.Dataset_mapToDomainAxis); + if(axisMap.containsKey(axisResource)) { + axis = axisMap.get(axisResource); + domainMappings.put(dataset, axis); + } + } + } + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + @Override + public void dispose() { + for(IAxis axis : ranges) + axis.dispose(); + + for(IAxis axis : domains) + axis.dispose(); + + for(IDataset dataset : datasets) + dataset.dispose(); + } + + @Override + public Resource getResource() { + return resource; + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractRenderer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractRenderer.java new file mode 100644 index 00000000..c38bd23a --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/AbstractRenderer.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Abstract renderer class for all JFreeChart renderers + * @author Teemu Lempinen + * + */ +public abstract class AbstractRenderer implements IRenderer { + + protected Resource resource; + + public AbstractRenderer(ReadGraph graph, Resource resource) { + this.resource = resource; + } + + @Override + public void dispose() { + } + + @Override + public Resource getResource() { + return resource; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/BarRenderer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/BarRenderer.java new file mode 100644 index 00000000..d708ac5f --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/BarRenderer.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + + +/** + * Normal bar renderer + * @author Teemu Lempinen + * + */ +public class BarRenderer extends AbstractRenderer { + + public BarRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + private org.jfree.chart.renderer.category.BarRenderer renderer; + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) + renderer = new org.jfree.chart.renderer.category.BarRenderer(); + return renderer; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryAxis.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryAxis.java new file mode 100644 index 00000000..d31e8ea7 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryAxis.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.jfree.chart.axis.Axis; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Class representing a JFreeChart.CategoryAxis + * + * @author Teemu Lempinen + * + */ +public class CategoryAxis extends AbstractAxis { + + public CategoryAxis(ReadGraph graph, Resource axisResource) { + super(graph, axisResource); + } + + @Override + public Axis getAxis() { + axis = new org.jfree.chart.axis.CategoryAxis(); + return super.getAxis(); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryDataset.java new file mode 100644 index 00000000..d87627c0 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryDataset.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.plot.DefaultDrawingSupplier; +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.chart.renderer.category.BarRenderer; +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.Dataset; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.request.PossibleActiveExperiment; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.adapter.SysdynVariableProperties; +import org.simantics.ui.SimanticsUI; + +/** + * Class representing a JFreeChart.CategoryDataset + * + * @author Teemu Lempinen + * + */ +public class CategoryDataset extends AbstractDataset { + + private List seriesList; + private String realizationURI; + private IRenderer renderer; + private DefaultCategoryDataset dataset; + + public CategoryDataset(ReadGraph graph, Resource resource) { + super(graph, resource); + + try { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + // Find the model where the chart is located + Resource model = resource; + do { + model = graph.getPossibleObject(model, l0.PartOf); + } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel)); + + // Find the variable realization of the current experiment + realizationURI = null; + Resource realization = graph.syncRequest(new PossibleActiveExperiment(model)); + if (realization == null) { + Layer0X L0X = Layer0X.getInstance(graph); + realization = graph.getPossibleObject(model, L0X.HasBaseRealization); + } + if (realization != null) + realizationURI = graph.getURI(realization); + + if(realizationURI == null) + return; // No experiment -> No results + + Resource seriesList = graph.getPossibleObject(resource, jfree.Dataset_seriesList); + if(seriesList != null) + this.seriesList = ListUtils.toList(graph, seriesList); + + Resource rendererResource = graph.getPossibleObject(resource, jfree.Dataset_renderer); + renderer = graph.adapt(rendererResource, IRenderer.class); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + private DatasetListener listener; + + @Override + public Dataset getDataset() { + + if(seriesList == null || seriesList.isEmpty()) + return null; + + if(dataset == null) { + dataset = new DefaultCategoryDataset(); + } + + if(listener == null || listener.isDisposed()) { + listener = new DatasetListener(); + SimanticsUI.getSession().asyncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + ArrayList series = new ArrayList(); + // Get properties for all series + if(seriesList != null) { + for(Resource r : seriesList) { + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + + try { + // Get a variable for the series + Variable v = Variables.getVariable(graph, realizationURI + rvi); + + // Get values + double[] va = v.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY); + + if(va == null || va.length == 0) + continue; + + // Time + Double time = graph.getPossibleRelatedValue(r, jfree.Series_time, Bindings.DOUBLE); + + if(time == null) + time = v.getPossiblePropertyValue(graph, SysdynVariableProperties.TIME, Bindings.DOUBLE); + + // Value + Double value = null; + if(time == null) { + value = va[va.length - 1]; + } else { + double[] ta = v.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY); + for(int i = 0; i < ta.length; i++) { + double t = ta[i]; + if(time <= t) { + value = va[i]; + break; + } + } + + if(value == null) + value = va[va.length - 1]; + } + String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel); // Called to refresh paints when label changes + String name = v.getName(graph); + series.add(new TempSeries(label == null || label.isEmpty() ? name : label, "Current", value)); + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. Move on to the next series + } + } + } + return series; + } + + }, listener); + } +// System.out.println("RETURNING CATEGORY DATASET" + dataset); + return dataset; + } + + @Override + public AbstractRenderer getRenderer() { + return renderer.getRenderer(); + } + + private class DatasetListener implements Listener> { + private boolean disposed = false; + + public void dispose() { + disposed = true; + } + + @Override + public void execute(final ArrayList series) { + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + // Remove all unused series + dataset.clear(); + ((BarRenderer)getRenderer()).getPlot().setDrawingSupplier(new DefaultDrawingSupplier()); + + // Add found series + for(int i = 0; i < series.size(); i++) { + TempSeries s = series.get(i); + dataset.addValue(s.value, s.series, s.name); +// System.out.println("Added " + s.name + ": " + s.value + " to " + dataset); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + }; + + @Override + public void dispose() { + super.dispose(); + if(listener != null) { + listener.dispose(); + listener = null; + } + } + + /** + * Auxiliary class containing all information needed to define a single series + * @author Teemu Lempinen + * + */ + private class TempSeries { + public String name; + public String series; + public Double value; + + public TempSeries(String name, String series, Double value) { + this.name = name; + this.series = series; + this.value = value; + } + + @Override + public String toString() { + return "TempSeries: " + name + ", " + series + ", " + value; + } + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryPlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryPlot.java new file mode 100644 index 00000000..51679325 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/CategoryPlot.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.jfree.chart.axis.CategoryAxis; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.Plot; +import org.jfree.chart.renderer.category.CategoryItemRenderer; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class representing a CategoryPlot for JFreeChart + * @author Teemu Lempinen + * + */ +public class CategoryPlot extends AbstractPlot { + + private org.jfree.chart.plot.CategoryPlot plot; + private Boolean visibleGrid; + + + public CategoryPlot(ReadGraph graph, Resource resource) { + super(graph, resource); + + try { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + // Visual properties + visibleGrid = graph.getPossibleRelatedValue(resource, jfree.Plot_visibleGrid); + } catch(DatabaseException e) { + e.printStackTrace(); + } + + + } + + @Override + public Plot getPlot() { + plot = new org.jfree.chart.plot.CategoryPlot(null, null, null, null); + + /* Support using multiple axis, but prefer using only one domain and + * one range axis + */ + for(int i = 0; i < ranges.size(); i++) { + plot.setRangeAxis(i, (ValueAxis)ranges.get(i).getAxis()); + } + + for(int i = 0; i < domains.size(); i++) { + plot.setDomainAxis(i, (CategoryAxis)domains.get(i).getAxis()); + } + + IAxis axis; + for(int i = 0; i < datasets.size(); i++) { + IDataset dataset = datasets.get(i); + org.jfree.data.category.CategoryDataset ds = (org.jfree.data.category.CategoryDataset)dataset.getDataset(); + plot.setDataset(i, ds); +// System.out.println("setting dataset " + i + ": " + ds); + plot.setRenderer(i, (CategoryItemRenderer)dataset.getRenderer()); + axis = rangeMappings.get(dataset); + if(axis != null && ranges.contains(axis)) + plot.mapDatasetToRangeAxis(i, ranges.indexOf(axis)); + axis = domainMappings.get(dataset); + if(axis != null && ranges.contains(axis)) + plot.mapDatasetToDomainAxis(i, domains.indexOf(axis)); + } + + if(visibleGrid != null) { + plot.setRangeGridlinesVisible(visibleGrid); + plot.setDomainGridlinesVisible(false); + } + + return plot; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java index d6fe5445..9e374b88 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ChartComposite.java @@ -17,6 +17,8 @@ import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.Composite; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -41,6 +43,7 @@ public class ChartComposite extends Composite { private Frame frame; private ChartPanel panel; private Composite composite; + IJFreeChart chart; /** * A new ChartComposite with a definition in chartResourceURI @@ -84,6 +87,16 @@ public class ChartComposite extends Composite { */ private void CreateContent(final Resource chartResource) { composite = this; + + composite.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + if(chart != null) + chart.dispose(); + } + }); + GridLayoutFactory.fillDefaults().applyTo(composite); GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); frame = SWT_AWT.new_Frame(composite); @@ -96,8 +109,10 @@ public class ChartComposite extends Composite { public JFreeChart perform(ReadGraph graph) throws DatabaseException { // Adapt chartResource to a chart (XY, pie, bar, ...) if(graph.isInstanceOf(chartResource, JFreeChartResource.getInstance(graph).Chart)) { - IJFreeChart c = graph.adapt(chartResource, IJFreeChart.class); - return c.getChart(); + if(chart != null) + chart.dispose(); + chart = graph.adapt(chartResource, IJFreeChart.class); + return chart.getChart(); } else { return null; } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ExtendedNumberAxis.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ExtendedNumberAxis.java new file mode 100644 index 00000000..329faadf --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/ExtendedNumberAxis.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.jfree.data.Range; + +/** + * NumberAxis that supports adding only one bound, lower or upper. + * The standard NumberAxis disables auto adjusting if even one of the bounds is set + * + * @author Teemu Lempinen + * + */ +public class ExtendedNumberAxis extends org.jfree.chart.axis.NumberAxis { + private static final long serialVersionUID = 3066266986472919998L; + + private Double lower = null; + private Double upper = null; + /** + * Use own lower and upper bounds to support using only one of them + */ + protected void autoAdjustRange() { + super.autoAdjustRange(); + Range range = getRange(); + Double lower = this.lower == null ? range.getLowerBound() : this.lower; + Double upper = this.upper == null ? range.getUpperBound() : this.upper; + if(lower > upper) + upper = lower + 1; + if(upper - lower < getAutoRangeMinimumSize()) + upper = lower + getAutoRangeMinimumSize(); + + setRange(new Range(lower, upper), false, false); + + } + + public void setLower(Double lower) { + this.lower = lower; + } + + public void setUpper(Double upper) { + this.upper = upper; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java index cf53605c..cf91dd71 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IDataset.java @@ -13,6 +13,7 @@ package org.simantics.sysdyn.ui.trend.chart; import org.jfree.chart.renderer.AbstractRenderer; import org.jfree.data.general.Dataset; +import org.simantics.db.Resource; /** * Interface for JFreeChart.Dataset type resource @@ -36,4 +37,10 @@ public interface IDataset extends IJFreeChartComponent { */ public AbstractRenderer getRenderer(); + /** + * Returns the resource of this dataset + * + * @return + */ + public Resource getResource(); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java index 162c9e0b..39b42e2e 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IJFreeChartComponent.java @@ -24,10 +24,4 @@ public interface IJFreeChartComponent { */ public void dispose(); - /** - * Returns the disposed state of the component - * @return - */ - public boolean isDisposed(); - } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java index 7f92e86d..ec8386ef 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IPlot.java @@ -12,6 +12,7 @@ package org.simantics.sysdyn.ui.trend.chart; import org.jfree.chart.plot.Plot; +import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; /** @@ -30,4 +31,11 @@ public interface IPlot extends IJFreeChartComponent { */ public Plot getPlot(); + /** + * Returns the resource of this plot + * + * @return + */ + public Resource getResource(); + } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IRenderer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IRenderer.java new file mode 100644 index 00000000..df832a45 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/IRenderer.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.jfree.chart.renderer.AbstractRenderer; +import org.simantics.db.Resource; + +/** + * Interface for JFreeChart.Renderer type resource + * @author Teemu Lempinen + * + */ +public interface IRenderer extends IJFreeChartComponent { + + /** + * Returns the JFreeChart AbstractRenderer represented by the associated resource + * + * @return JFreeChart renderer + */ + public AbstractRenderer getRenderer(); + + /** + * Returns the resource of this renderer + * @return + */ + public Resource getResource(); + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java index 87661ceb..661fdf48 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/JFreeChart.java @@ -35,11 +35,10 @@ import org.simantics.sysdyn.JFreeChartResource; public class JFreeChart implements IJFreeChart { private org.jfree.chart.JFreeChart jfreechart; - private boolean disposed = false; private ITitle title; private Boolean legendVisible; - + private HashMap plots; private IPlot firstPlot = null; @@ -79,12 +78,12 @@ public class JFreeChart implements IJFreeChart { if(plots.size() == 0) return null; jfreechart = new org.jfree.chart.JFreeChart(firstPlot.getPlot()); - + // setVisible does not work in TextTitle, have to use this workaround org.jfree.chart.title.TextTitle t = (org.jfree.chart.title.TextTitle)title.getTitle(); if(t.isVisible()) jfreechart.setTitle(t); - + if(legendVisible != null && !legendVisible) { for(Object title : jfreechart.getSubtitles()) { if(title instanceof LegendTitle) @@ -96,16 +95,10 @@ public class JFreeChart implements IJFreeChart { @Override public void dispose() { - disposed = true; - // Call dispose to title and plots to disable their possible listeners title.dispose(); for(IPlot plot : plots.values()) plot.dispose(); } - @Override - public boolean isDisposed() { - return disposed; - } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java index 57bb9721..eda694fe 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/NumberAxis.java @@ -11,17 +11,9 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.trend.chart; -import java.awt.Color; - import org.jfree.chart.axis.Axis; -import org.jfree.data.Range; -import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.G2DUtils; -import org.simantics.layer0.Layer0; -import org.simantics.sysdyn.JFreeChartResource; /** * Class representing a JFreeChart.NumberAxis @@ -29,14 +21,7 @@ import org.simantics.sysdyn.JFreeChartResource; * @author Teemu Lempinen * */ -public class NumberAxis implements IAxis { - - private MyNumberAxis axis; - private String label; - private boolean disposed; - private Boolean tMarksVisible, tLabelsVisible, labelVisible, lineVisible; - private Color color; - private Double min, max; +public class NumberAxis extends AbstractAxis { /** * @@ -44,95 +29,16 @@ public class NumberAxis implements IAxis { * @param axisResource resource of type JFreeChart.NumberAxis */ public NumberAxis(ReadGraph graph, Resource axisResource) { - - try { - Layer0 l0 = Layer0.getInstance(graph); - JFreeChartResource jfree = JFreeChartResource.getInstance(graph); - label = graph.getPossibleRelatedValue(axisResource, l0.HasLabel); - tMarksVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleTickMarks, Bindings.BOOLEAN); - tLabelsVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleTickLabels, Bindings.BOOLEAN); - labelVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleLabel, Bindings.BOOLEAN); - lineVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleAxisLine, Bindings.BOOLEAN); - Resource c = graph.getPossibleObject(axisResource, jfree.color); - color = c == null ? null : G2DUtils.getColor(graph, c); - min = graph.getPossibleRelatedValue(axisResource, jfree.Axis_min, Bindings.DOUBLE); - max = graph.getPossibleRelatedValue(axisResource, jfree.Axis_max, Bindings.DOUBLE); - } catch (DatabaseException e) { - e.printStackTrace(); - } + super(graph, axisResource); } @Override public Axis getAxis() { - axis = new MyNumberAxis(); - - if(tMarksVisible != null && tMarksVisible == false) - axis.setTickMarksVisible(false); - if(tLabelsVisible != null && tLabelsVisible == false) - axis.setTickLabelsVisible(false); - if(lineVisible != null && lineVisible == false) - axis.setAxisLineVisible(false); - - if(color != null) { - axis.setAxisLinePaint(color); - axis.setLabelPaint(color); - axis.setTickLabelPaint(color); - axis.setTickMarkPaint(color); - } - // label exists and its visibility == null or true - if((labelVisible == null || labelVisible == true) && label != null) - axis.setLabel(label); - axis.setLower(min); - axis.setUpper(max); - return axis; + axis = new ExtendedNumberAxis(); + ((ExtendedNumberAxis)axis).setLower(min); + ((ExtendedNumberAxis)axis).setUpper(max); + return super.getAxis(); } - @Override - public void dispose() { - disposed = true; - } - - @Override - public boolean isDisposed() { - return disposed; - } - - /** - * NumberAxis that supports adding only one bound, lower or upper. - * The standard NumberAxis disables auto adjusting if even one of the bounds is set - * - * @author Teemu Lempinen - * - */ - private class MyNumberAxis extends org.jfree.chart.axis.NumberAxis { - private static final long serialVersionUID = 3066266986472919998L; - - private Double lower = null; - private Double upper = null; - /** - * Use own lower and upper bounds to support using only one of them - */ - protected void autoAdjustRange() { - super.autoAdjustRange(); - Range range = getRange(); - Double lower = this.lower == null ? range.getLowerBound() : this.lower; - Double upper = this.upper == null ? range.getUpperBound() : this.upper; - if(lower > upper) - upper = lower + 1; - if(upper - lower < getAutoRangeMinimumSize()) - upper = lower + getAutoRangeMinimumSize(); - - setRange(new Range(lower, upper), false, false); - - } - - public void setLower(Double lower) { - this.lower = lower; - } - - public void setUpper(Double upper) { - this.upper = upper; - } - } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/PieDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/PieDataset.java new file mode 100644 index 00000000..b7956d2a --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/PieDataset.java @@ -0,0 +1,287 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.data.general.Dataset; +import org.jfree.data.general.DefaultPieDataset; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.request.PossibleActiveExperiment; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.diagram.G2DUtils; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.adapter.SysdynVariableProperties; +import org.simantics.ui.SimanticsUI; + +/** + * Class representing a PieDataset in JFreeChart ontology + * @author Teemu Lempinen + * + */ +public class PieDataset extends AbstractDataset { + + private List seriesList; + private String realizationURI; + private DefaultPieDataset dataset; + + private HashMap colorMap; + private HashMap explodedMap; + + public PieDataset(ReadGraph graph, Resource resource) { + super(graph, resource); + + try { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + // Find the model where the chart is located + Resource model = resource; + do { + model = graph.getPossibleObject(model, l0.PartOf); + } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel)); + + // Find the variable realization of the current experiment + realizationURI = null; + Resource realization = graph.syncRequest(new PossibleActiveExperiment(model)); + if (realization == null) { + Layer0X L0X = Layer0X.getInstance(graph); + realization = graph.getPossibleObject(model, L0X.HasBaseRealization); + } + if (realization != null) + realizationURI = graph.getURI(realization); + + if(realizationURI == null) + return; // No experiment -> No results + + Resource seriesList = graph.getPossibleObject(resource, jfree.Dataset_seriesList); + if(seriesList != null) { + this.seriesList = ListUtils.toList(graph, seriesList); + + colorMap = new HashMap(); + explodedMap = new HashMap(); + + for(Resource r : this.seriesList) { + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + + try { + Variable v = Variables.getVariable(graph, realizationURI + rvi); + if(v != null) { + String name = v.getName(graph); + graph.getPossibleRelatedValue(r, l0.HasLabel); // Called to refresh paints when label changes + // Get visual properties + Resource c = graph.getPossibleObject(r, jfree.color); + Color color = c == null ? null : G2DUtils.getColor(graph, c); + colorMap.put(name, color); + Boolean exploded = graph.getPossibleRelatedValue(r, jfree.Series_exploded, Bindings.BOOLEAN); + explodedMap.put(name, exploded); + } + } catch (MissingVariableException e) { + // Invalid or missing rvi, skip this series + continue; + } + } + } + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + /** + * Map of colors for different slices in a pie chart. Name + * indicates the key of the value. + * @return Map of colors for different slices in a pie chart + */ + public HashMap getColorMap() { + return colorMap; + } + + /** + * Map of exploded statuses for slices in a pie chart. Name + * indicates the key of the slice. + * @return + */ + public HashMap getExplodedMap() { + return explodedMap; + } + + @Override + public Dataset getDataset() { + if(seriesList == null || seriesList.isEmpty()) + return null; + + if(dataset == null) { + dataset = new DefaultPieDataset(); + } + + if(listener == null) { + listener = new DatasetListener(); + SimanticsUI.getSession().asyncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + ArrayList series = new ArrayList(); + // Get properties for all series + if(seriesList != null) { + for(Resource r : seriesList) { + String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel); + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + + try { + // Get a variable for the series + Variable v = Variables.getVariable(graph, realizationURI + rvi); + // Get values + double[] va = v.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY); + + if(va == null || va.length == 0) + continue; + + // Time + Double time = graph.getPossibleRelatedValue(r, jfree.Series_time, Bindings.DOUBLE); + + if(time == null) + time = v.getPossiblePropertyValue(graph, SysdynVariableProperties.TIME, Bindings.DOUBLE); + + // Value + Double value = null; + if(time == null) { + value = va[va.length - 1]; + } else { + double[] ta = v.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY); + for(int i = 0; i < ta.length; i++) { + double t = ta[i]; + if(time <= t) { + value = va[i]; + break; + } + } + + if(value == null) + value = va[va.length - 1]; + } + + series.add(new TempSeries(label == null || label.isEmpty() ? v.getName(graph) : label, value)); + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. Move on to the next series + } + } + } + return series; + } + + }, listener); + } + return dataset; + } + + private DatasetListener listener; + + private class DatasetListener implements Listener> { + + private boolean disposed = false; + + @Override + public void execute(final ArrayList series) { + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + // Remove all series + dataset.clear(); + + // Add found series + for(int i = 0; i < series.size(); i++) { + TempSeries s = series.get(i); + dataset.setValue(s.name, s.value); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + + public void dispose() { + disposed = true; + } + } + + @Override + public AbstractRenderer getRenderer() { + // No renderer for pie chart + return null; + } + + @Override + public void dispose() { + super.dispose(); + if(listener != null) { + listener.dispose(); + listener = null; + } + } + + + /** + * Auxiliary class containing all information needed to define a single series + * @author Teemu Lempinen + * + */ + private class TempSeries { + public String name; + public Double value; + + public TempSeries(String name, Double value) { + this.name = name; + this.value = value; + } + + @Override + public String toString() { + return "TempSeries: " + name + ", " + value; + } + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/PiePlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/PiePlot.java new file mode 100644 index 00000000..62cc00d5 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/PiePlot.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import java.awt.Color; +import java.util.HashMap; + +import org.jfree.chart.plot.DefaultDrawingSupplier; +import org.jfree.chart.plot.Plot; +import org.jfree.data.general.Dataset; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Class representing a PiePlot in JFreeChart ontology + * + * @author Teemu Lempinen + * + */ +public class PiePlot extends AbstractPlot { + + org.jfree.chart.plot.PiePlot plot; + + public PiePlot(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + @Override + public Plot getPlot() { + if(plot == null) { + plot = new org.jfree.chart.plot.PiePlot(); + } + + if(!datasets.isEmpty()) { + // We assume that a pie plot has only one dataset + IDataset ds = datasets.get(0); + Dataset dataset = ((PieDataset)ds).getDataset(); + if(dataset instanceof org.jfree.data.general.PieDataset) { + plot.clearSectionPaints(true); + plot.setDrawingSupplier(new DefaultDrawingSupplier()); + plot.setDataset(null); + + org.jfree.data.general.PieDataset pieDataset = (org.jfree.data.general.PieDataset)dataset; + plot.setDataset(pieDataset); + + HashMap colorMap = ((PieDataset)ds).getColorMap(); + for(String name : colorMap.keySet()) + plot.setSectionPaint(name, colorMap.get(name)); + + HashMap explodedMap = ((PieDataset)ds).getExplodedMap(); + for(String name : explodedMap.keySet()) { + Boolean exploded = explodedMap.get(name); + if(Boolean.TRUE.equals(exploded)) + plot.setExplodePercent(name, 0.3); + } + } + } + return plot; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/StackedBarRenderer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/StackedBarRenderer.java new file mode 100644 index 00000000..daf266b8 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/StackedBarRenderer.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Stacked bar renderer + * @author Teemu Lempinen + * + */ +public class StackedBarRenderer extends AbstractRenderer { + + public StackedBarRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + private org.jfree.chart.renderer.category.StackedBarRenderer renderer; + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) + renderer = new org.jfree.chart.renderer.category.StackedBarRenderer(); + return renderer; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java index 3fd7ede1..7386a862 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/TextTitle.java @@ -30,7 +30,6 @@ public class TextTitle implements ITitle { private org.jfree.chart.title.TextTitle textTitle; private RectangleEdge position; private String text; - private boolean disposed; private Boolean visible; public TextTitle(ReadGraph graph, Resource titleResource) { @@ -83,12 +82,6 @@ public class TextTitle implements ITitle { @Override public void dispose() { - disposed = true; - } - - @Override - public boolean isDisposed() { - return disposed; } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java index e87cae31..1246412d 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYDataset.java @@ -13,15 +13,20 @@ package org.simantics.sysdyn.ui.trend.chart; import java.awt.BasicStroke; import java.awt.Color; +import java.awt.Stroke; import java.util.ArrayList; import java.util.List; import javax.swing.SwingUtilities; +import org.jfree.chart.plot.DefaultDrawingSupplier; +import org.jfree.chart.plot.ValueMarker; import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.chart.renderer.xy.AbstractXYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.general.Dataset; import org.jfree.data.xy.DefaultXYDataset; +import org.jfree.ui.Layer; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; @@ -48,17 +53,15 @@ import org.simantics.ui.SimanticsUI; * @author Teemu Lempinen * */ -public class XYDataset implements IDataset { +public class XYDataset extends AbstractDataset { - private boolean disposed; private XYLineAndShapeRenderer renderer; private double[] domainValues; private List seriesList; private String realizationURI; - private Resource resource; public XYDataset(ReadGraph graph, final Resource datasetResource) { - this.resource = datasetResource; + super(graph, datasetResource); try { Layer0 l0 = Layer0.getInstance(graph); @@ -110,7 +113,9 @@ public class XYDataset implements IDataset { } } - DefaultXYDataset dataset; + private DefaultXYDataset dataset; + private DataSetListener datasetListener; + private TimeListener timeListener; @Override public Dataset getDataset() { @@ -120,6 +125,10 @@ public class XYDataset implements IDataset { if(dataset == null) { dataset = new DefaultXYDataset(); + } + + if(datasetListener == null || datasetListener.isDisposed()) { + datasetListener = new DataSetListener(); SimanticsUI.getSession().asyncRequest(new Read>() { @Override @@ -147,7 +156,7 @@ public class XYDataset implements IDataset { // Get values // double[] va = v.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY); - + Object object = v.getPossiblePropertyValue(graph, SysdynVariableProperties.ACTIVE_DATASETS , Bindings.VARIANT); if(object == null || !(object instanceof ArrayList)) return series; @@ -155,10 +164,10 @@ public class XYDataset implements IDataset { for(Object o : datasets) { if(!(o instanceof SysdynDataSet)) continue; - + SysdynDataSet dataset = (SysdynDataSet)o; double[] va = dataset.values; - + // Get domain axis values (time OR other variable) double[] ta; if(domainValues != null) { @@ -203,58 +212,151 @@ public class XYDataset implements IDataset { return series; } - }, new Listener>() { - - @Override - public boolean isDisposed() { - return disposed; - } + }, datasetListener); + } + if(timeListener == null || timeListener.isDisposed()) { + timeListener = new TimeListener(new ValueMarker(0.0)); + SimanticsUI.getSession().asyncRequest(new Read() { @Override - public void execute(final ArrayList series) { - // Modify series in AWT thread to avoid synchronization problems - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - // Remove all series - for(int i = dataset.getSeriesCount() - 1; i >= 0; i-- ) { - dataset.removeSeries(dataset.getSeriesKey(i)); + public Double perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + // Get properties for all series + if(seriesList != null) { + for(Resource r : seriesList) { + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + try { + // Get a variable for the series + Variable v = Variables.getVariable(graph, realizationURI + rvi); + Double time = v.getPossiblePropertyValue(graph, SysdynVariableProperties.TIME , Bindings.DOUBLE); + return time; + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. } - - // Add found series - for(int i = 0; i < series.size(); i++) { - TempSeries s = series.get(i); - dataset.addSeries(s.name, s.values); - getRenderer().setSeriesStroke(i, new BasicStroke((float)s.width)); - if(s.color != null) - getRenderer().setSeriesPaint(i, s.color); - } } - }); + } + return null; } + }, timeListener); + } + return dataset; + } + + + private class DataSetListener implements Listener> { + + private boolean disposed = false; + + public void dispose() { + disposed = true; + } + + @Override + public boolean isDisposed() { + return disposed; + } + + @Override + public void execute(final ArrayList series) { + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + @Override - public void exception(Throwable t) { - t.printStackTrace(); + public void run() { + ((AbstractXYItemRenderer)getRenderer()).getPlot().setDrawingSupplier(new DefaultDrawingSupplier()); + // Remove all series + for(int i = dataset.getSeriesCount() - 1; i >= 0; i-- ) { + dataset.removeSeries(dataset.getSeriesKey(i)); + } + + // Add found series + for(int i = 0; i < series.size(); i++) { + TempSeries s = series.get(i); + dataset.addSeries(s.name, s.values); + getRenderer().setSeriesStroke(i, new BasicStroke((float)s.width)); + getRenderer().setSeriesPaint(i, s.color); + } } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + } + + + private class TimeListener implements Listener { + + private ValueMarker marker; + private boolean disposed = false; + public TimeListener(ValueMarker marker) { + this.marker = marker; + } + + public void dispose() { + this.disposed = true; + } + + @Override + public boolean isDisposed() { + return disposed; + } + + @Override + public void execute(final Double time) { + // Modify in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot(); + + int i = 0; + for(i = 0; i < plot.getDatasetCount(); i++) { + if(plot.getDataset(i).equals(dataset)) + break; + } + + plot.removeDomainMarker(marker); + if(time != null) { + Stroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, 10.0f, new float[] {5.0f, 3.0f, 1.0f, 3.0f}, 0.0f); + marker = new ValueMarker(time, Color.red, dashStroke); + plot.addDomainMarker(i, marker, Layer.FOREGROUND); + } + + } }); - - } - return dataset; + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + } @Override public void dispose() { - disposed = true; - } + if(timeListener != null) { + timeListener.dispose(); + timeListener = null; + } - @Override - public boolean isDisposed() { - return disposed; + if(datasetListener != null) { + datasetListener.dispose(); + datasetListener = null; + } } + /** * Auxiliary class containing all information needed to define a single series * @author Teemu Lempinen diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java index 59978204..a64f9cf1 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/XYPlot.java @@ -11,19 +11,13 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.trend.chart; -import java.util.ArrayList; -import java.util.HashMap; - import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.Plot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYDataset; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; -import org.simantics.db.common.request.ObjectsWithType; -import org.simantics.db.common.utils.ListUtils; import org.simantics.db.exception.DatabaseException; -import org.simantics.layer0.Layer0; import org.simantics.sysdyn.JFreeChartResource; /** @@ -32,126 +26,61 @@ import org.simantics.sysdyn.JFreeChartResource; * @author Teemu Lempinen * */ -public class XYPlot implements IPlot { +public class XYPlot extends AbstractPlot { private org.jfree.chart.plot.XYPlot plot; - private ArrayList ranges; - private ArrayList domains; - private ArrayList datasets; - private HashMap rangeMappings; - private HashMap domainMappings; - private boolean disposed; private Boolean visibleGrid; - + + public XYPlot(ReadGraph graph, Resource plotResource) { + super(graph, plotResource); try { - Layer0 l0 = Layer0.getInstance(graph); JFreeChartResource jfree = JFreeChartResource.getInstance(graph); - - HashMap axisMap = new HashMap(); - ranges = new ArrayList(); - - // Get all range axis - Resource rangeList = graph.getPossibleObject(plotResource, jfree.Plot_rangeAxisList); - if(rangeList != null) { - for(Resource axisResource : ListUtils.toList(graph, rangeList)) { - IAxis axis = graph.adapt(axisResource, IAxis.class); - if(axis.getAxis() instanceof ValueAxis) { - ranges.add(axis); - axisMap.put(axisResource, axis); - } - } - } - - // Get all domain axis - // There usually is only one domain axis, but this supports also multiple domain axis - domains = new ArrayList(); - for(Resource axisResource : graph.syncRequest(new ObjectsWithType(plotResource, jfree.Plot_domainAxis, jfree.Axis))) { - IAxis axis = graph.adapt(axisResource, IAxis.class); - if(axis.getAxis() instanceof ValueAxis) { - domains.add(axis); - axisMap.put(axisResource, axis); - } - } - - // Get all datasets and map them to axis - datasets = new ArrayList(); - rangeMappings = new HashMap(); - domainMappings = new HashMap(); - for(Resource datasetResource : graph.syncRequest(new ObjectsWithType(plotResource, l0.ConsistsOf, jfree.Dataset))) { - IDataset dataset = graph.adapt(datasetResource, IDataset.class); - if(dataset.getDataset() != null && dataset.getDataset() instanceof XYDataset) { - datasets.add(dataset); - Resource axisResource = graph.getPossibleObject(datasetResource, jfree.Dataset_mapToRangeAxis); - IAxis axis; - if(axisMap.containsKey(axisResource)) { - axis = axisMap.get(axisResource); - rangeMappings.put(dataset, axis); - } - - axisResource = graph.getPossibleObject(datasetResource, jfree.Dataset_mapToDomainAxis); - if(axisMap.containsKey(axisResource)) { - axis = axisMap.get(axisResource); - domainMappings.put(dataset, axis); - } - } - } - // Visual properties visibleGrid = graph.getPossibleRelatedValue(plotResource, jfree.Plot_visibleGrid); - - } catch (DatabaseException e) { + } catch(DatabaseException e) { e.printStackTrace(); } + } @Override public Plot getPlot() { + if(plot == null) + plot = new org.jfree.chart.plot.XYPlot(null, null, null, null); - plot = new org.jfree.chart.plot.XYPlot(null, null, null, null); + plot.clearDomainAxes(); + plot.clearRangeAxes(); for(int i = 0; i < ranges.size(); i++) { plot.setRangeAxis(i, (ValueAxis)ranges.get(i).getAxis()); } - + for(int i = 0; i < domains.size(); i++) { plot.setDomainAxis(i, (ValueAxis)domains.get(i).getAxis()); } - + + IAxis axis; for(int i = 0; i < datasets.size(); i++) { IDataset dataset = datasets.get(i); plot.setDataset(i, (XYDataset)dataset.getDataset()); plot.setRenderer(i, (XYItemRenderer)dataset.getRenderer()); - plot.mapDatasetToRangeAxis(i, ranges.indexOf(rangeMappings.get(dataset))); - plot.mapDatasetToDomainAxis(i, domains.indexOf(domainMappings.get(dataset))); + axis = rangeMappings.get(dataset); + if(axis != null && ranges.contains(axis)) + plot.mapDatasetToRangeAxis(i, ranges.indexOf(axis)); + axis = domainMappings.get(dataset); + if(axis != null && ranges.contains(axis)) + plot.mapDatasetToDomainAxis(i, domains.indexOf(axis)); } + + if(visibleGrid == null) + visibleGrid = true; + + plot.setRangeGridlinesVisible(visibleGrid); + plot.setDomainGridlinesVisible(visibleGrid); - if(visibleGrid != null) { - plot.setRangeGridlinesVisible(visibleGrid); - plot.setDomainGridlinesVisible(visibleGrid); - } return plot; } - - @Override - public void dispose() { - disposed = true; - - // Dispose all axis and datasets - for(IAxis axis : ranges) - axis.dispose(); - - for(IAxis axis : domains) - axis.dispose(); - - for(IDataset dataset : datasets) - dataset.dispose(); - } - - @Override - public boolean isDisposed() { - return disposed; - } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisDropAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisDropAction.java index 7d3872cc..e6590aa0 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisDropAction.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/AxisDropAction.java @@ -22,7 +22,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.DropActionFactory; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.JFreeChartResource; -import org.simantics.sysdyn.ui.trend.chart.properties.AxisAndVariablesExplorerComposite; +import org.simantics.sysdyn.ui.trend.chart.properties.xyline.AxisAndVariablesExplorerComposite; import org.simantics.ui.SimanticsUI; import org.simantics.ui.utils.AdaptionUtils; diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesChildRule.java new file mode 100644 index 00000000..a12f844e --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesChildRule.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.graphexplorer; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Child rule for obtaining series in a chart. + * Assumes that the chart has only one plot and that plot has only one dataset + * @author Teemu Lempinen + * + */ +public class SeriesChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList result = new ArrayList(); + if(!(parent instanceof Resource)) + return result; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + /* + * 1. we assume that there is only one plot + * 2. we assume that the only plot has only one dataset + */ + Resource plot = graph.syncRequest(new PossibleObjectWithType((Resource)parent, l0.ConsistsOf, jfree.Plot)); + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + + Resource seriesList = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + if(seriesList != null) + for(Resource series : ListUtils.toList(graph, seriesList)) { + result.add(series); + } + return result; + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return new ArrayList(); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesDropAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesDropAction.java index e0bd0d63..241394bb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesDropAction.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/graphexplorer/SeriesDropAction.java @@ -24,12 +24,12 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.DropActionFactory; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.JFreeChartResource; -import org.simantics.sysdyn.ui.trend.chart.properties.ChartAxisAndVariablesTab; +import org.simantics.sysdyn.ui.trend.chart.properties.xyline.XYLineAxisAndVariablesTab; import org.simantics.ui.SimanticsUI; import org.simantics.ui.utils.AdaptionUtils; /** - * Drop action for explorer in {@link ChartAxisAndVariablesTab}. This action is used for dropping + * Drop action for explorer in {@link XYLineAxisAndVariablesTab}. This action is used for dropping * both series on axis or another sries * * @author Teemu Lempinen diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TitleFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TitleFactory.java new file mode 100644 index 00000000..d9a081f8 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TitleFactory.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * TextFactory for chart title + * @author Teemu Lempinen + * + */ +public class TitleFactory extends ReadFactoryImpl { + @Override + public String perform(ReadGraph graph, Resource chart) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle)); + if(title == null) + return ""; + else { + String label = graph.getPossibleRelatedValue(title, l0.HasLabel, Bindings.STRING); + return label == null ? "" : label; + } + } +} \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TitleModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TitleModifier.java new file mode 100644 index 00000000..d47fbcdd --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/TitleModifier.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * TitleModifier for chart title + * @author Teemu Lempinen + * + */ +public class TitleModifier extends TextModifyListenerImpl { + + @Override + public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle)); + if(title == null) { + title = GraphUtils.create2(graph, jfree.TextTitle, + jfree.Title_position, jfree.Top); + } + graph.claimLiteral(title, l0.HasLabel, text); + } + +} \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarGeneralPropertiesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarGeneralPropertiesTab.java new file mode 100644 index 00000000..8d4d6e34 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarGeneralPropertiesTab.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties.bar; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanPropertyFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanSelectionListener; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.sysdyn.ui.trend.chart.properties.TitleFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.TitleModifier; + +/** + * General properties of a bar chart + * @author Teemu Lempinen + * + */ +public class BarGeneralPropertiesTab extends LabelPropertyTabContributor { + + private ScrolledComposite sc; + private Composite composite; + private Button hgrid, htitle, hlegend; + private TrackedText name, title; + private Combo type; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + // Scrolled composite containing all of the properties in this tab + sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + composite = new Composite(sc, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // General properties + Group general = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(general); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(general); + general.setText("General"); + + // Name + Label label = new Label(general, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Name:"); + + Composite c = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(c); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(c); + + name = new org.simantics.browsing.ui.swt.widgets.TrackedText(c, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget()); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Type + label = new Label(c, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Type:"); + + type = new Combo(c, SWT.BORDER | SWT.READ_ONLY); + type.setItems(new String[] {"Normal", "Stacked"}); + type.select(0); + + // Title (Which is different than name) + label = new Label(general, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Title:"); + + title = new org.simantics.browsing.ui.swt.widgets.TrackedText(general, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(title.getWidget()); + title.setTextFactory(new TitleFactory()); + title.addModifyListener(new TitleModifier()); + title.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Group for hide options + Group hideGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(hideGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup); + hideGroup.setText("Hide"); + + hgrid = new Button(hideGroup, support, SWT.CHECK); + hgrid.setText("Grid"); + hgrid.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleGrid, true)); + hgrid.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleGrid)); + htitle = new Button(hideGroup, support, SWT.CHECK); + htitle.setText("Title"); + htitle.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible, true)); + htitle.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible)); + hlegend = new Button(hideGroup, support, SWT.CHECK); + hlegend.setText("Legend"); + hlegend.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Chart_visibleLegend, true)); + hlegend.addSelectionListener(new BooleanSelectionListener(context, null, JFreeChartResource.URIs.Chart_visibleLegend)); + + sc.setContent(composite); + Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarSeriesPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarSeriesPropertyComposite.java new file mode 100644 index 00000000..3b463a7e --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarSeriesPropertyComposite.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties.bar; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIModifier; + +/** + * Composite for modifying properties of a series in a bar chart + * @author Teemu Lempinen + * + */ +public class BarSeriesPropertyComposite extends Composite { + + private TrackedText variable, label; + + public BarSeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + Label label = new Label(this, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + variable = new TrackedText(this, support, SWT.BORDER); + variable.setTextFactory(new RVIFactory()); + variable.addModifyListener(new RVIModifier(variable.getWidget(), support)); + variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); + + // Label to be displayed in chart for this series + label = new Label(this, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + this.label = new TrackedText(this, support, SWT.BORDER); + this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget()); + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarSeriesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarSeriesTab.java new file mode 100644 index 00000000..4dd81ff1 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/bar/BarSeriesTab.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties.bar; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor; +import org.simantics.sysdyn.ui.trend.chart.ChartUtils; +import org.simantics.sysdyn.ui.trend.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.ui.utils.AdaptionUtils; +import org.simantics.utils.datastructures.ArrayMap; + +/** + * Tab containing the series of a bar chart + * @author Teemu Lempinen + * + */ +public class BarSeriesTab extends LabelPropertyTabContributor implements Widget { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + private Button add, remove; + private Resource chartResource; + + + public BarSeriesTab() { + additionalSupport = new WidgetSupportImpl(); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + support.register(this); + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying variables in a bar chart + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(SysdynResource.URIs.BarSeriesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + // Buttons for adding and removing variables from a pie plot + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + add = new Button(buttonComposite, additionalSupport, SWT.NONE); + add.setText("Add"); + add.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + BarSeriesPropertyComposite spc = new BarSeriesPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE); + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + + additionalSupport.fireInput(context, selection); + } + + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + Resource dataset = null; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if(input == null) { + if(chartResource != null) { + Resource plot = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Plot)); + if(plot != null) + dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + } + } else { + if(graph.isInstanceOf(input, jfree.Series)) { + dataset = graph.getPossibleObject(input, l0.PartOf); + } + } + + if(dataset != null) { + // Create series with no rvi + Resource series = ChartUtils.createSeries(graph, dataset, null); + graph.claimLiteral(series, jfree.Series_exploded, false); + } + } + } + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } + } + + @Override + public void setInput(ISessionContext context, Object input) { + chartResource = AdaptionUtils.adaptToSingle(input, Resource.class); + } + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieGeneralPropertiesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieGeneralPropertiesTab.java new file mode 100644 index 00000000..2bfe94b9 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieGeneralPropertiesTab.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties.pie; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanPropertyFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanSelectionListener; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.sysdyn.ui.trend.chart.properties.TitleFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.TitleModifier; + +/** + * General properties of a pie chart + * @author Teemu Lempinen + * + */ +public class PieGeneralPropertiesTab extends LabelPropertyTabContributor { + + private ScrolledComposite sc; + private Composite composite; + private Button htitle, hlegend; + private TrackedText name, title; + private Combo type; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + // Scrolled composite containing all of the properties in this tab + sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + composite = new Composite(sc, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // General properties + Group general = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(general); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(general); + general.setText("General"); + + // Name + Label label = new Label(general, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Name:"); + + Composite c = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(c); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(c); + + name = new org.simantics.browsing.ui.swt.widgets.TrackedText(c, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget()); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Type + label = new Label(c, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Type:"); + + type = new Combo(c, SWT.BORDER | SWT.READ_ONLY); + type.setItems(new String[] {"Normal", "Stacked"}); + type.select(0); + + // Title (Which is different than name) + label = new Label(general, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Title:"); + + title = new org.simantics.browsing.ui.swt.widgets.TrackedText(general, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(title.getWidget()); + title.setTextFactory(new TitleFactory()); + title.addModifyListener(new TitleModifier()); + title.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Group for hide options + Group hideGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(hideGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup); + hideGroup.setText("Hide"); + + htitle = new Button(hideGroup, support, SWT.CHECK); + htitle.setText("Title"); + htitle.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible, true)); + htitle.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible)); + hlegend = new Button(hideGroup, support, SWT.CHECK); + hlegend.setText("Legend"); + hlegend.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Chart_visibleLegend, true)); + hlegend.addSelectionListener(new BooleanSelectionListener(context, null, JFreeChartResource.URIs.Chart_visibleLegend)); + + sc.setContent(composite); + Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieSeriesPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieSeriesPropertyComposite.java new file mode 100644 index 00000000..642f070d --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieSeriesPropertyComposite.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties.pie; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanPropertyFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanSelectionListener; +import org.simantics.sysdyn.ui.trend.chart.properties.ColorPicker; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIModifier; + +/** + * Composite containing the properties of a series + * @author Teemu Lempinen + * + */ +public class PieSeriesPropertyComposite extends Composite { + + private TrackedText variable, label; + + public PieSeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + Label label = new Label(this, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + variable = new TrackedText(this, support, SWT.BORDER); + variable.setTextFactory(new RVIFactory()); + variable.addModifyListener(new RVIModifier(variable.getWidget(), support)); + variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); + + // Label to be displayed in chart for this series + label = new Label(this, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + this.label = new TrackedText(this, support, SWT.BORDER); + this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget()); + + // Color + label = new Label(this, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + Composite colorPicker = new ColorPicker(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + + // Exploded + label = new Label(this, SWT.NONE); + label.setText(""); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + Button exploded = new Button(this, support, SWT.CHECK); + exploded.setText("Exploded"); + exploded.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Series_exploded)); + exploded.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Series_exploded)); + GridDataFactory.fillDefaults().applyTo(exploded.getWidget()); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieSeriesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieSeriesTab.java new file mode 100644 index 00000000..96a5fd40 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/pie/PieSeriesTab.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend.chart.properties.pie; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor; +import org.simantics.sysdyn.ui.trend.chart.ChartUtils; +import org.simantics.sysdyn.ui.trend.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.ui.utils.AdaptionUtils; +import org.simantics.utils.datastructures.ArrayMap; + +/** + * Tab for modifying series in a pie chart configuration + * @author Teemu Lempinen + * + */ +public class PieSeriesTab extends LabelPropertyTabContributor { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + private Button add, remove; + + public PieSeriesTab() { + additionalSupport = new WidgetSupportImpl(); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying variables of a pie chart + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(SysdynResource.URIs.PieSeriesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + + // Buttons for adding and removing variables from a pie plot + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + add = new Button(buttonComposite, additionalSupport, SWT.NONE); + add.setText("Add"); + add.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + + PieSeriesPropertyComposite spc = new PieSeriesPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE); + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + + additionalSupport.fireInput(context, selection); + } + + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource dataset; + if(graph.isInstanceOf(input, jfree.Series)) { + dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) { + // Create series with no rvi + Resource series = ChartUtils.createSeries(graph, dataset, null); + graph.claimLiteral(series, jfree.Series_exploded, false); + } + } + } + } + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } + } + + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisAndVariablesExplorerComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/AxisAndVariablesExplorerComposite.java similarity index 95% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisAndVariablesExplorerComposite.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/AxisAndVariablesExplorerComposite.java index f15c9f06..a3ee7e6a 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisAndVariablesExplorerComposite.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/AxisAndVariablesExplorerComposite.java @@ -9,7 +9,7 @@ * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ -package org.simantics.sysdyn.ui.trend.chart.properties; +package org.simantics.sysdyn.ui.trend.chart.properties.xyline; import java.util.ArrayList; import java.util.Map; diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/AxisPropertyComposite.java similarity index 91% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisPropertyComposite.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/AxisPropertyComposite.java index 882dd10b..d029ddf4 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/AxisPropertyComposite.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/AxisPropertyComposite.java @@ -9,7 +9,7 @@ * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ -package org.simantics.sysdyn.ui.trend.chart.properties; +package org.simantics.sysdyn.ui.trend.chart.properties.xyline; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.layout.GridDataFactory; @@ -27,9 +27,12 @@ import org.simantics.layer0.Layer0; import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.trend.chart.properties.AxisHidePropertyComposite; +import org.simantics.sysdyn.ui.trend.chart.properties.ColorPicker; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; /** - * Composite for displaying axis properties in {@link ChartAxisAndVariablesTab} + * Composite for displaying axis properties in {@link XYLineAxisAndVariablesTab} * * @author Teemu Lempinen * diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/SeriesPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/SeriesPropertyComposite.java similarity index 90% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/SeriesPropertyComposite.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/SeriesPropertyComposite.java index b1f94d34..4b09224c 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/SeriesPropertyComposite.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/SeriesPropertyComposite.java @@ -9,7 +9,7 @@ * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ -package org.simantics.sysdyn.ui.trend.chart.properties; +package org.simantics.sysdyn.ui.trend.chart.properties.xyline; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; @@ -34,10 +34,15 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.trend.chart.properties.ColorPicker; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIModifier; +import org.simantics.sysdyn.ui.trend.chart.properties.TrackedSpinner; import org.simantics.ui.utils.AdaptionUtils; /** - * Composite for displaying series properties in {@link ChartAxisAndVariablesTab} + * Composite for displaying series properties in {@link XYLineAxisAndVariablesTab} * * @author Teemu Lempinen * @@ -63,7 +68,7 @@ public class SeriesPropertyComposite extends Composite { variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); - // Label to be displayed in chart for this series (usually same as the variable + // Label to be displayed in chart for this series label = new Label(this, SWT.NONE); label.setText("Label:"); GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartAxisAndVariablesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/XYLineAxisAndVariablesTab.java similarity index 96% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartAxisAndVariablesTab.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/XYLineAxisAndVariablesTab.java index 7c33faaa..530d611a 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/ChartAxisAndVariablesTab.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/XYLineAxisAndVariablesTab.java @@ -9,7 +9,7 @@ * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ -package org.simantics.sysdyn.ui.trend.chart.properties; +package org.simantics.sysdyn.ui.trend.chart.properties.xyline; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; @@ -54,14 +54,14 @@ import org.simantics.utils.datastructures.ArrayMap; * @author Teemu Lempinen * */ -public class ChartAxisAndVariablesTab extends LabelPropertyTabContributor { +public class XYLineAxisAndVariablesTab extends LabelPropertyTabContributor { private GraphExplorerComposite explorer; private ScrolledComposite propertyContainer; private Button addAxis, addVariable, remove; private WidgetSupportImpl additionalSupport; - public ChartAxisAndVariablesTab() { + public XYLineAxisAndVariablesTab() { additionalSupport = new WidgetSupportImpl(); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/GeneralChartPropertiesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/XYLineGeneralPropertiesTab.java similarity index 82% rename from org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/GeneralChartPropertiesTab.java rename to org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/XYLineGeneralPropertiesTab.java index 25d486c3..ea64a17d 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/GeneralChartPropertiesTab.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/chart/properties/xyline/XYLineGeneralPropertiesTab.java @@ -9,7 +9,7 @@ * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ -package org.simantics.sysdyn.ui.trend.chart.properties; +package org.simantics.sysdyn.ui.trend.chart.properties.xyline; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.layout.GridDataFactory; @@ -27,25 +27,28 @@ import org.simantics.browsing.ui.swt.widgets.Button; import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; import org.simantics.browsing.ui.swt.widgets.TrackedText; -import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; -import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; import org.simantics.browsing.ui.swt.widgets.impl.Widget; import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; -import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; import org.simantics.db.common.request.PossibleObjectWithType; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.layer0.Layer0; -import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; import org.simantics.sysdyn.JFreeChartResource; import org.simantics.sysdyn.ui.properties.LabelPropertyTabContributor; +import org.simantics.sysdyn.ui.trend.chart.properties.AxisHidePropertyComposite; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanPropertyFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.BooleanSelectionListener; +import org.simantics.sysdyn.ui.trend.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.RVIModifier; +import org.simantics.sysdyn.ui.trend.chart.properties.TitleFactory; +import org.simantics.sysdyn.ui.trend.chart.properties.TitleModifier; import org.simantics.ui.utils.AdaptionUtils; /** @@ -54,12 +57,11 @@ import org.simantics.ui.utils.AdaptionUtils; * @author Teemu Lempinen * */ -public class GeneralChartPropertiesTab extends LabelPropertyTabContributor implements Widget { +public class XYLineGeneralPropertiesTab extends LabelPropertyTabContributor implements Widget { private ScrolledComposite sc; private Composite composite; - private org.simantics.browsing.ui.swt.widgets.TrackedText name, title; - private TrackedText xlabel, xvariable, xmin, xmax; + private TrackedText name, title, xlabel, xvariable, xmin, xmax; private Combo type; private Button hgrid, htitle, hlegend; private WidgetSupportImpl domainAxisSupport = new WidgetSupportImpl(); @@ -219,46 +221,6 @@ public class GeneralChartPropertiesTab extends LabelPropertyTabContributor imple }); } - /** - * TextFactory for chart title - * @author Teemu Lempinen - * - */ - private class TitleFactory extends ReadFactoryImpl { - @Override - public String perform(ReadGraph graph, Resource chart) throws DatabaseException { - Layer0 l0 = Layer0.getInstance(graph); - JFreeChartResource jfree = JFreeChartResource.getInstance(graph); - Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle)); - if(title == null) - return ""; - else { - String label = graph.getPossibleRelatedValue(title, l0.HasLabel, Bindings.STRING); - return label == null ? "" : label; - } - } - } - - /** - * TitleModifier for chart title - * @author Teemu Lempinen - * - */ - private class TitleModifier extends TextModifyListenerImpl { - - @Override - public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException { - Layer0 l0 = Layer0.getInstance(graph); - JFreeChartResource jfree = JFreeChartResource.getInstance(graph); - Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle)); - if(title == null) { - title = GraphUtils.create2(graph, jfree.TextTitle, - jfree.Title_position, jfree.Top); - } - graph.claimLiteral(title, l0.HasLabel, text); - } - - } /** * Validator for validating that an input is double diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java index e2d8cdeb..39f85dcb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java @@ -78,7 +78,7 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen // Empty selection or pinned trend -> Do nothing if(selection.isEmpty() || Boolean.TRUE.equals(PinTrend.getState())) return; - + if(selection instanceof IStructuredSelection) { // Remove all previously added result listeners from model if(!resultListeners.isEmpty()) { @@ -185,7 +185,7 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen * @throws DatabaseException */ private void updateDatasets(ReadGraph graph, Collection variables) throws DatabaseException { - + ArrayList datasets = new ArrayList(); for(Variable variable : variables) { // Get all active datasets for the variable and add them to the result @@ -193,7 +193,7 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen if(activeDataSets != null && !activeDataSets.isEmpty()) datasets.addAll(activeDataSets); } - + selectionChanged(datasets); } @@ -215,7 +215,7 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen } catch (DatabaseException e) { return dataSets; } - + // Remove the first '.' if(rvi.length() > 1) rvi = rvi.substring(1); @@ -233,14 +233,16 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen Collection activeResults = model.getAndUpdateActiveResults(g); for(SysdynResult sysdynResult : activeResults) { for(String currvi : rvis.keySet()) { - SysdynDataSet sds = sysdynResult.getDataSet(currvi.substring(1).replace("/", ".")); - if(sds != null) { - try { - sds.name = rvis.get(currvi).substring(1).replace("/", "."); - } catch (NullPointerException e) { - e.printStackTrace(); + if(currvi != null && currvi.length() > 0) { + SysdynDataSet sds = sysdynResult.getDataSet(currvi.substring(1).replace("/", ".")); + if(sds != null) { + try { + sds.name = rvis.get(currvi).substring(1).replace("/", "."); + } catch (NullPointerException e) { + e.printStackTrace(); + } + dataSets.add(sds); } - dataSets.add(sds); } } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java index e77511bc..131bb200 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java @@ -230,7 +230,7 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider { * @return */ protected VariableValueSubscription registerSubscription(ExternalRead request, Listener procedure, String property) { - if(SysdynVariableProperties.TIME.equals(property) && experiment instanceof SysdynPlaybackExperiment) { + if(SysdynVariableProperties.TIME.equals(property)) { // Current time is requested from experiment VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure); experiment.addVariableValueSubscription(subscription); @@ -275,7 +275,7 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider { return new ConstantPropertyVariable(this, name, exp.getTime(), Datatypes.DOUBLE); } else { // Experiment is not compatible, return time = 0 - return new ConstantPropertyVariable(this, name, 0, Datatypes.DOUBLE); + return null; } } else if(SysdynVariableProperties.VALUES.equals(name)) { // Get the values of this variable from the currently active experiment