]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Add support for saving visualisation templates 94/3194/1
authorjsimomaa <jani.simomaa@gmail.com>
Wed, 4 Sep 2019 06:37:30 +0000 (09:37 +0300)
committerjsimomaa <jani.simomaa@gmail.com>
Wed, 4 Sep 2019 06:37:30 +0000 (09:37 +0300)
TODO:
* Disabling dynamic updates
* "Gappless" color/size values from maps
* Show/Hide ticks of color bars
* Perfomance tuning

gitlab #59
APROS-15038
APROS-15527
APROS-15528

Change-Id: Idbb7284b552630ca23c8efbf3ec858c834385345

org.simantics.district.network.ontology/graph/DistrictNetwork.pgraph
org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph
org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/visualisations/DynamicVisualisationsUI.java
org.simantics.district.network/src/org/simantics/district/network/DistrictNetworkUtil.java
org.simantics.district.network/src/org/simantics/district/network/profile/ActiveDynamicVisualisationsRequest.java [new file with mode: 0644]
org.simantics.district.network/src/org/simantics/district/network/profile/DynamicVisualisationsRequest.java
org.simantics.district.network/src/org/simantics/district/network/profile/RuntimeDynamicVisualisationsRequest.java
org.simantics.district.network/src/org/simantics/district/network/visualisations/model/DynamicVisualisation.java

index 128904c801bbdd9d3bc08840620fdd02bad2fa04..bb3130eb5307c5d42309c1c4a0b93bfb6395100c 100644 (file)
@@ -232,6 +232,9 @@ DN.Diagram.Visualisations <T L0.Entity
     >-- DN.Diagram.Visualisations.SizeBarSize
         @defProperty "Size Bar Size" L0.String
 
+DN.Diagram.Visualisations.ColorContribution <T L0.Entity
+DN.Diagram.Visualisations.SizeContribution <T L0.Entity
+
 DN.Diagram.Visualisations.colorContributions <R L0.HasProperty
 DN.Diagram.Visualisations.sizeContributions <R L0.HasProperty
 
index a1ce3a0acbbd1ab0fc619dcaf23ac734fd8ad650..2e259ef7bee17e801e45266cd05cb0fc46f3a0f9 100644 (file)
@@ -108,6 +108,7 @@ DN.Diagram
         L0.HasLabel "Draw Map"
     >-- DN.Diagram.hasVisualisation --> DN.Diagram.Visualisations <R L0.HasProperty
         L0.HasLabel "Visualisation"
+    >-- DN.Diagram.hasActiveVisualisation --> DN.Diagram.Visualisations <R L0.HasProperty
     >-- DN.Diagram.profileUpdateInterval ==> "Long" <R L0.HasProperty : SEL.GenericParameterType
         L0.HasLabel "Profile update interval"
     @L0.assert DN.Diagram.elementColoringGradientHue
index 5bcf491bf81655928330ef7d423a31254fc80eed..e27aef7c3a129165f0bb9f1628090666eb03fe8d 100644 (file)
@@ -31,6 +31,7 @@ public class DistrictNetworkResource {
     public final Resource Diagram_Visualisations_ColorBarLocation_Inverse;
     public final Resource Diagram_Visualisations_ColorBarSize;
     public final Resource Diagram_Visualisations_ColorBarSize_Inverse;
+    public final Resource Diagram_Visualisations_ColorContribution;
     public final Resource Diagram_Visualisations_ShowColorBarTicks;
     public final Resource Diagram_Visualisations_ShowColorBarTicks_Inverse;
     public final Resource Diagram_Visualisations_ShowColorBars;
@@ -43,6 +44,7 @@ public class DistrictNetworkResource {
     public final Resource Diagram_Visualisations_SizeBarLocation_Inverse;
     public final Resource Diagram_Visualisations_SizeBarSize;
     public final Resource Diagram_Visualisations_SizeBarSize_Inverse;
+    public final Resource Diagram_Visualisations_SizeContribution;
     public final Resource Diagram_Visualisations_colorContributionContributorName;
     public final Resource Diagram_Visualisations_colorContributionContributorName_Inverse;
     public final Resource Diagram_Visualisations_colorContributionDefaultColorMap;
@@ -117,6 +119,8 @@ public class DistrictNetworkResource {
     public final Resource Diagram_elementColoringGradientHue_Inverse;
     public final Resource Diagram_elementColoringGradientSaturation;
     public final Resource Diagram_elementColoringGradientSaturation_Inverse;
+    public final Resource Diagram_hasActiveVisualisation;
+    public final Resource Diagram_hasActiveVisualisation_Inverse;
     public final Resource Diagram_hasVisualisation;
     public final Resource Diagram_hasVisualisation_Inverse;
     public final Resource Diagram_nodeScaleBias;
@@ -487,6 +491,7 @@ public class DistrictNetworkResource {
         public static final String Diagram_Visualisations_ColorBarLocation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarLocation/Inverse";
         public static final String Diagram_Visualisations_ColorBarSize = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarSize";
         public static final String Diagram_Visualisations_ColorBarSize_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarSize/Inverse";
+        public static final String Diagram_Visualisations_ColorContribution = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorContribution";
         public static final String Diagram_Visualisations_ShowColorBarTicks = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBarTicks";
         public static final String Diagram_Visualisations_ShowColorBarTicks_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBarTicks/Inverse";
         public static final String Diagram_Visualisations_ShowColorBars = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBars";
@@ -499,6 +504,7 @@ public class DistrictNetworkResource {
         public static final String Diagram_Visualisations_SizeBarLocation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarLocation/Inverse";
         public static final String Diagram_Visualisations_SizeBarSize = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarSize";
         public static final String Diagram_Visualisations_SizeBarSize_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarSize/Inverse";
+        public static final String Diagram_Visualisations_SizeContribution = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeContribution";
         public static final String Diagram_Visualisations_colorContributionContributorName = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionContributorName";
         public static final String Diagram_Visualisations_colorContributionContributorName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionContributorName/Inverse";
         public static final String Diagram_Visualisations_colorContributionDefaultColorMap = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultColorMap";
@@ -573,6 +579,8 @@ public class DistrictNetworkResource {
         public static final String Diagram_elementColoringGradientHue_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientHue/Inverse";
         public static final String Diagram_elementColoringGradientSaturation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientSaturation";
         public static final String Diagram_elementColoringGradientSaturation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientSaturation/Inverse";
+        public static final String Diagram_hasActiveVisualisation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasActiveVisualisation";
+        public static final String Diagram_hasActiveVisualisation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasActiveVisualisation/Inverse";
         public static final String Diagram_hasVisualisation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasVisualisation";
         public static final String Diagram_hasVisualisation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasVisualisation/Inverse";
         public static final String Diagram_nodeScaleBias = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleBias";
@@ -953,6 +961,7 @@ public class DistrictNetworkResource {
         Diagram_Visualisations_ColorBarLocation_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarLocation_Inverse);
         Diagram_Visualisations_ColorBarSize = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarSize);
         Diagram_Visualisations_ColorBarSize_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarSize_Inverse);
+        Diagram_Visualisations_ColorContribution = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorContribution);
         Diagram_Visualisations_ShowColorBarTicks = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBarTicks);
         Diagram_Visualisations_ShowColorBarTicks_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBarTicks_Inverse);
         Diagram_Visualisations_ShowColorBars = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBars);
@@ -965,6 +974,7 @@ public class DistrictNetworkResource {
         Diagram_Visualisations_SizeBarLocation_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarLocation_Inverse);
         Diagram_Visualisations_SizeBarSize = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarSize);
         Diagram_Visualisations_SizeBarSize_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarSize_Inverse);
+        Diagram_Visualisations_SizeContribution = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeContribution);
         Diagram_Visualisations_colorContributionContributorName = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionContributorName);
         Diagram_Visualisations_colorContributionContributorName_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionContributorName_Inverse);
         Diagram_Visualisations_colorContributionDefaultColorMap = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultColorMap);
@@ -1039,6 +1049,8 @@ public class DistrictNetworkResource {
         Diagram_elementColoringGradientHue_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientHue_Inverse);
         Diagram_elementColoringGradientSaturation = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientSaturation);
         Diagram_elementColoringGradientSaturation_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientSaturation_Inverse);
+        Diagram_hasActiveVisualisation = getResourceOrNull(graph, URIs.Diagram_hasActiveVisualisation);
+        Diagram_hasActiveVisualisation_Inverse = getResourceOrNull(graph, URIs.Diagram_hasActiveVisualisation_Inverse);
         Diagram_hasVisualisation = getResourceOrNull(graph, URIs.Diagram_hasVisualisation);
         Diagram_hasVisualisation_Inverse = getResourceOrNull(graph, URIs.Diagram_hasVisualisation_Inverse);
         Diagram_nodeScaleBias = getResourceOrNull(graph, URIs.Diagram_nodeScaleBias);
index cc5b24e1652e69427b1c6a34a919f6e869cbc044..f0305fad2ce9ca663a10feab158abf90d2bb5b87 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.district.network.ui;
 
 import java.awt.Color;
 import java.awt.geom.AffineTransform;
+import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
@@ -15,6 +16,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
 import org.simantics.diagram.ui.DiagramModelHints;
 import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
 import org.simantics.district.network.ui.participants.DNPointerInteractor;
 import org.simantics.district.network.ui.participants.DynamicVisualisationContributionsParticipant;
 import org.simantics.district.network.ui.participants.ElevationServerParticipant;
@@ -261,7 +263,7 @@ public class DistrictDiagramViewer extends DiagramViewer {
 
     private static class MapBackgroundColorListener implements Listener<RGB.Integer> {
 
-        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+        private static final Logger LOGGER = LoggerFactory.getLogger(MapBackgroundColorListener.class);
 
         private Consumer<RGB.Integer> callback;
         private Supplier<Boolean> isDisposed;
@@ -295,7 +297,12 @@ public class DistrictDiagramViewer extends DiagramViewer {
 
         @Override
         public ColorBarOptions perform(ReadGraph graph) throws DatabaseException {
-            return DistrictNetworkUtil.colorBarOptions(graph, parameter);
+            DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+            Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+            if (activeVisualisation != null) {
+                return DistrictNetworkUtil.colorBarOptions(graph, activeVisualisation);
+            }
+            return ColorBarOptions.useDefault();
         }
     }
 
@@ -307,13 +314,18 @@ public class DistrictDiagramViewer extends DiagramViewer {
 
         @Override
         public Map<String, DynamicColorContribution> perform(ReadGraph graph) throws DatabaseException {
-            return DistrictNetworkUtil.colorContributions(graph, parameter);
+            DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+            Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+            if (activeVisualisation != null) {
+                return DistrictNetworkUtil.colorContributions(graph, activeVisualisation);
+            }
+            return Collections.emptyMap();
         }
     }
     
     private static class ColoringObjectsListener implements Listener<Map<String,DynamicColorContribution>> {
 
-        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+        private static final Logger LOGGER = LoggerFactory.getLogger(ColoringObjectsListener.class);
 
         private Consumer<Map<String,DynamicColorContribution>> callback;
         private Supplier<Boolean> isDisposed;
@@ -341,7 +353,7 @@ public class DistrictDiagramViewer extends DiagramViewer {
     
     private static class ColorBarOptionsListener implements Listener<ColorBarOptions> {
 
-        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+        private static final Logger LOGGER = LoggerFactory.getLogger(ColorBarOptionsListener.class);
 
         private Consumer<ColorBarOptions> callback;
         private Supplier<Boolean> isDisposed;
@@ -375,13 +387,18 @@ public class DistrictDiagramViewer extends DiagramViewer {
 
         @Override
         public SizeBarOptions perform(ReadGraph graph) throws DatabaseException {
-            return DistrictNetworkUtil.sizeBarOptions(graph, parameter);
+            DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+            Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+            if (activeVisualisation != null) {
+                return DistrictNetworkUtil.sizeBarOptions(graph, activeVisualisation);
+            }
+            return SizeBarOptions.useDefault();
         }
     }
 
     private static class SizeBarOptionsListener implements Listener<SizeBarOptions> {
 
-        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+        private static final Logger LOGGER = LoggerFactory.getLogger(SizeBarOptionsListener.class);
 
         private Consumer<SizeBarOptions> callback;
         private Supplier<Boolean> isDisposed;
@@ -415,13 +432,18 @@ public class DistrictDiagramViewer extends DiagramViewer {
 
         @Override
         public Map<String, DynamicSizeContribution> perform(ReadGraph graph) throws DatabaseException {
-            return DistrictNetworkUtil.sizeContributions(graph, parameter);
+            DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+            Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+            if (activeVisualisation != null) {
+                return DistrictNetworkUtil.sizeContributions(graph, activeVisualisation);
+            }
+            return Collections.emptyMap();
         }
     }
     
     private static class SizingObjectsListener implements Listener<Map<String,DynamicSizeContribution>> {
 
-        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+        private static final Logger LOGGER = LoggerFactory.getLogger(SizingObjectsListener.class);
 
         private Consumer<Map<String,DynamicSizeContribution>> callback;
         private Supplier<Boolean> isDisposed;
index 4fe3d591ec9b2dbced9cfeac8084e3b7f5d8212d..031e502963f544b057c14e71c09a277c191d3d97 100644 (file)
@@ -7,10 +7,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
 import org.eclipse.swt.SWT;
@@ -22,17 +26,21 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.IEditorPart;
 import org.simantics.Simantics;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.common.NamedResource;
 import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
 import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
 import org.simantics.district.network.profile.DynamicVisualisationsRequest;
 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
@@ -71,6 +79,10 @@ public class DynamicVisualisationsUI extends Composite {
     private Combo colorLocationCombo;
     private Combo colorSizeCombo;
 
+    private Combo templateSelectionCombo;
+
+    private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
+
     public DynamicVisualisationsUI(Composite parent, int style) {
         super(parent, style);
 
@@ -81,6 +93,34 @@ public class DynamicVisualisationsUI extends Composite {
         GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
         GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(this);
         
+        Composite selectionComposite = new Composite(this, SWT.NONE);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
+        
+        Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
+        templateNameLabel.setText("Visualisation template");
+        templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
+        templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
+            
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
+                for (NamedResource template : visualisations) {
+                    if (item.equals(template.getName())) {
+                        Simantics.getSession().asyncRequest(new WriteRequest() {
+                            
+                            @Override
+                            public void perform(WriteGraph graph) throws DatabaseException {
+                                DistrictNetworkUtil.setActiveVisualisation(graph, diagramResource, template.getResource());
+                            }
+                        });
+                        break;
+                    }
+                }
+            }
+        });
+        
         Composite coloringObjectsComposite = new Composite(this, SWT.NONE);
         GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
@@ -101,6 +141,90 @@ public class DynamicVisualisationsUI extends Composite {
         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
         initializeSizeBars(sizeBarsComposite);
         
+        Button saveVisualisationTemplateButton = new Button(this, SWT.NONE);
+        saveVisualisationTemplateButton.setText("Save");
+        saveVisualisationTemplateButton.setEnabled(visualisation == null || visualisation.getVisualisationResource() != null);
+        saveVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
+            
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
+            }
+        });
+        
+        Button saveVisualisationTemplateAsButton = new Button(this, SWT.NONE);
+        saveVisualisationTemplateAsButton.setText("Save as visualisation template");
+        saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
+            
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
+            }
+        });
+        
+    }
+    
+    private void showSaveVisualisationTemplateDialog(Shell shell) {
+        
+        InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
+            
+            @Override
+            public String isValid(String newText) {
+                if (newText == null || newText.isEmpty())
+                    return "Name cannot be empty";
+                return null;
+            }
+        });
+        
+        if (dialog.open() == Dialog.OK) {
+            String name = dialog.getValue();
+            persistVisualisationTemplate(name, Optional.empty());
+        }
+    }
+
+    private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) {
+        
+        List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+
+        String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
+        String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
+        
+        ColorBarOptions colorBarOptions = new ColorBarOptions()
+                .showColorBars(showColorButton.getSelection())
+                .showColorBarsTicks(colorTicksButton.getSelection())
+                .withLocation(ColorBarsLocation.valueOf(colorLocation))
+                .withSize(ColorBarsSize.valueOf(colorSize));
+        
+        List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+        
+        String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
+        String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
+        
+        SizeBarOptions sizeBarOptions = new SizeBarOptions()
+                .showSizeBars(showSizeButton.getSelection())
+                .showSizeBarsTicks(sizeTicksButton.getSelection())
+                .withLocation(SizeBarsLocation.valueOf(sizeLocation))
+                .withSize(SizeBarsSize.valueOf(sizeSize));
+        
+        Simantics.getSession().asyncRequest(new WriteRequest() {
+            
+            @Override
+            public void perform(WriteGraph graph) throws DatabaseException {
+                DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+                Resource exist;
+                if (existing.isPresent()) {
+                    exist = existing.get();
+                } else {
+                    exist = DistrictNetworkUtil.createVisualisation(graph, diagramResource, templateName);
+                }
+                
+                DistrictNetworkUtil.setColorContributions(graph, exist, colorCollect);
+                
+                DistrictNetworkUtil.setColorBarOptions(graph, exist, colorBarOptions);
+                DistrictNetworkUtil.setSizeContributions(graph, exist, sizeCollect);
+                DistrictNetworkUtil.setSizeBarOptions(graph, exist, sizeBarOptions);
+            }
+        });
     }
 
     private void initializeColoringObjects(Composite parent) {
@@ -112,7 +236,7 @@ public class DynamicVisualisationsUI extends Composite {
         {
             createColoringObjectHeaderRow(group);
         }
-        List<Supplier<Pair<String, DynamicColorContribution>>> suppliers = new ArrayList<>();
+        colorSuppliers = new ArrayList<>();
         {
             try {
                 Collection<DynamicColoringObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicColoringObject>>() {
@@ -124,11 +248,11 @@ public class DynamicVisualisationsUI extends Composite {
                 });
                 
                 for (DynamicColoringObject object : result) {
-                    suppliers.add(createColoringObjectRow(group, object));
+                    colorSuppliers.add(createColoringObjectRow(group, object));
                 }
 
             } catch (DatabaseException e) {
-                e.printStackTrace();
+                LOGGER.error("Could not create coloring objecst", e);
             }
         }
         {
@@ -138,12 +262,12 @@ public class DynamicVisualisationsUI extends Composite {
                 
                 @Override
                 public void widgetSelected(SelectionEvent e) {
-                    List<Pair<String, DynamicColorContribution>> collect = suppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+                    List<Pair<String, DynamicColorContribution>> collect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
                     Simantics.getSession().asyncRequest(new WriteRequest() {
                         
                         @Override
                         public void perform(WriteGraph graph) throws DatabaseException {
-                            DistrictNetworkUtil.setColorContributions(graph, DynamicVisualisationsUI.this.diagramResource, collect);
+                            DistrictNetworkUtil.setColorContributions(graph, visualisation.getVisualisationResource(), collect);
                         }
                     });
                 }
@@ -189,6 +313,12 @@ public class DynamicVisualisationsUI extends Composite {
     private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
     private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
 
+    private VisualisationsListener visualisationsListener;
+
+    private Collection<NamedResource> visualisations;
+
+    private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
+
     private static class ColoringObjectRow {
         
         private final Label label;
@@ -236,6 +366,12 @@ public class DynamicVisualisationsUI extends Composite {
 //                    break;
 //                }
 //            }
+            usedButton.setSelection(colorContribution.isUsed());
+            defaultButton.setSelection(colorContribution.isUseDefault());
+            
+            minText.setEnabled(!colorContribution.isUseDefault());
+            maxText.setEnabled(!colorContribution.isUseDefault());
+            colorMapCombo.setEnabled(!colorContribution.isUseDefault());
         }
     }
 
@@ -319,57 +455,85 @@ public class DynamicVisualisationsUI extends Composite {
         
         Button defaultButton = new Button(parent, SWT.CHECK);
         GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
+        defaultButton.addSelectionListener(new SelectionAdapter() {
+            
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                int index = variableCombo.getSelectionIndex();
+                if (index >= 0) {
+                    String key = variableCombo.getItem(index);
+                    DynamicColorContribution cont = colorContributions.get(key);
+                    
+                    minText.setText(Double.toString(cont.getDefaultMin()));
+                    minText.setEnabled(!defaultButton.getSelection());
+                    maxText.setText(Double.toString(cont.getDefaultMax()));
+                    maxText.setEnabled(!defaultButton.getSelection());
+                    unit.setText(cont.getUnit());
+                    
+                    colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
+                    colorMapCombo.select(0);
+                    colorMapCombo.setEnabled(!defaultButton.getSelection());
+                }
+            }
+        });
         
         variableCombo.addSelectionListener(new SelectionAdapter() {
             
             @Override
             public void widgetSelected(SelectionEvent e) {
                 // handle update for others
-                
-                DynamicColorContribution cont = colorContributions.get(variableCombo.getText());
-                
-                if (minText.getText().isEmpty()) {
-                    minText.setText(Double.toString(cont.getDefaultMin()));
-                }
-                if (maxText.getText().isEmpty()) {
-                    maxText.setText(Double.toString(cont.getDefaultMax()));
+                int index = variableCombo.getSelectionIndex();
+                if (index >= 0) {
+                    String key = variableCombo.getItem(index);
+                    DynamicColorContribution cont = colorContributions.get(key);
+                    
+                    if (minText.getText().isEmpty()) {
+                        minText.setText(Double.toString(cont.getDefaultMin()));
+                    }
+                    if (maxText.getText().isEmpty()) {
+                        maxText.setText(Double.toString(cont.getDefaultMax()));
+                    }
+                    unit.setText(cont.getUnit());
+                    
+                    colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
+                    colorMapCombo.select(0);
+                    
+                    defaultButton.setSelection(true);
                 }
-                unit.setText(cont.getUnit());
-                
-                colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
-                colorMapCombo.select(0);
-                
-                defaultButton.setSelection(true);
             }
         });
-
+        
         coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
 
         return new Supplier<Pair<String, DynamicColorContribution>>() {
 
             @Override
             public Pair<String, DynamicColorContribution> get() {
-                DynamicColorContribution cont = colorContributions.get(variableCombo.getText());
-                if (cont != null) {
-                    String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
-                    try {
-                        Map<String, DynamicColorMap> colorMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicColorMap>>() {
-    
-                            @Override
-                            public Map<String, DynamicColorMap> perform(ReadGraph graph) throws DatabaseException {
-                                return DynamicVisualisationsContributions.dynamicColorMaps(graph);
-                            }
-                        });
-                        DynamicColorMap dColorMap = colorMaps.get(colorMap);
-                        String label = variableCombo.getItem(variableCombo.getSelectionIndex());
-                        
-                        DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
-                        dcc.setUsed(usedButton.getSelection());
-                        dcc.setUseDefault(defaultButton.getSelection());
-                        
-                        return Pair.make(object.getColoringObject().getName(), dcc);
-                    } catch (DatabaseException e) {
-                        LOGGER.error("Could not get DynamicColorContribution", e);
+                int selectionIndex = variableCombo.getSelectionIndex();
+                if (selectionIndex >= 0) {
+                    String key = variableCombo.getItem(selectionIndex);
+                    DynamicColorContribution cont = colorContributions.get(key);
+                    if (cont != null) {
+                        String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
+                        try {
+                            Map<String, DynamicColorMap> colorMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicColorMap>>() {
+        
+                                @Override
+                                public Map<String, DynamicColorMap> perform(ReadGraph graph) throws DatabaseException {
+                                    return DynamicVisualisationsContributions.dynamicColorMaps(graph);
+                                }
+                            });
+                            DynamicColorMap dColorMap = colorMaps.get(colorMap);
+                            String label = variableCombo.getItem(variableCombo.getSelectionIndex());
+                            
+                            DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
+                            dcc.setUsed(usedButton.getSelection());
+                            dcc.setUseDefault(defaultButton.getSelection());
+                            
+                            return Pair.make(object.getColoringObject().getName(), dcc);
+                        } catch (DatabaseException e) {
+                            LOGGER.error("Could not get DynamicColorContribution", e);
+                        }
                     }
                 }
                 return null;
@@ -448,8 +612,8 @@ public class DynamicVisualisationsUI extends Composite {
             @Override
             public void widgetSelected(SelectionEvent e) {
                 // handle update for others
-                
-                DynamicSizeContribution cont = sizeContributions.get(variableCombo.getText());
+                String key = variableCombo.getItem(variableCombo.getSelectionIndex());
+                DynamicSizeContribution cont = sizeContributions.get(key);
                 
                 if (minText.getText().isEmpty()) {
                     minText.setText(Double.toString(cont.getDefaultMin()));
@@ -472,27 +636,31 @@ public class DynamicVisualisationsUI extends Composite {
 
             @Override
             public Pair<String, DynamicSizeContribution> get() {
-                DynamicSizeContribution cont = sizeContributions.get(variableCombo.getText());
-                if (cont != null) {
-                    String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
-                    try {
-                        Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
-    
-                            @Override
-                            public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
-                                return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
-                            }
-                        });
-                        DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
-                        String label = variableCombo.getItem(variableCombo.getSelectionIndex());
-                        
-                        DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
-                        dsc.setUsed(usedButton.getSelection());
-                        dsc.setUseDefault(defaultButton.getSelection());
-                        
-                        return Pair.make(object.getSizingObject().getName(), dsc);
-                    } catch (DatabaseException e) {
-                        LOGGER.error("Could not get DynamicColorContribution", e);
+                int selectionIndex = variableCombo.getSelectionIndex();
+                if (selectionIndex >= 0) {
+                    String key = variableCombo.getItem(selectionIndex);
+                    DynamicSizeContribution cont = sizeContributions.get(key);
+                    if (cont != null) {
+                        String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
+                        try {
+                            Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
+        
+                                @Override
+                                public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
+                                    return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
+                                }
+                            });
+                            DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
+                            String label = variableCombo.getItem(variableCombo.getSelectionIndex());
+                            
+                            DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
+                            dsc.setUsed(usedButton.getSelection());
+                            dsc.setUseDefault(defaultButton.getSelection());
+                            
+                            return Pair.make(object.getSizingObject().getName(), dsc);
+                        } catch (DatabaseException e) {
+                            LOGGER.error("Could not get DynamicColorContribution", e);
+                        }
                     }
                 }
                 return null;
@@ -537,18 +705,21 @@ public class DynamicVisualisationsUI extends Composite {
                 // persist changes
                 IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
                 if (activeEditor instanceof IResourceEditorPart) {
-                    Resource diagram = ((IResourceEditorPart) activeEditor).getResourceInput().getResource();
+                    
+                    String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
+                    String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
+                    
                     ColorBarOptions options = new ColorBarOptions()
                             .showColorBars(showColorButton.getSelection())
                             .showColorBarsTicks(colorTicksButton.getSelection())
-                            .withLocation(ColorBarsLocation.valueOf(colorLocationCombo.getText().toUpperCase()))
-                            .withSize(ColorBarsSize.valueOf(colorSizeCombo.getText().toUpperCase()));
+                            .withLocation(ColorBarsLocation.valueOf(colorLocation))
+                            .withSize(ColorBarsSize.valueOf(colorSize));
 
                     Simantics.getSession().asyncRequest(new WriteRequest() {
                         
                         @Override
                         public void perform(WriteGraph graph) throws DatabaseException {
-                            DistrictNetworkUtil.setColorBarOptions(graph, diagram, options);
+                            DistrictNetworkUtil.setColorBarOptions(graph, visualisation.getVisualisationResource(), options);
                         }
                     });
                 }
@@ -570,7 +741,7 @@ public class DynamicVisualisationsUI extends Composite {
     
     private void createObjectSizes(Composite parent) {
         
-        List<Supplier<Pair<String, DynamicSizeContribution>>> suppliers = new ArrayList<>(); 
+        sizeSuppliers = new ArrayList<>(); 
         try {
             Collection<DynamicSizingObject> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicSizingObject>>() {
 
@@ -581,10 +752,10 @@ public class DynamicVisualisationsUI extends Composite {
             });
             
             for (DynamicSizingObject object : resultSizing) {
-                suppliers.add(createSizingObjectRow(parent, object));
+                sizeSuppliers.add(createSizingObjectRow(parent, object));
             }
         } catch (DatabaseException e) {
-            e.printStackTrace();
+            LOGGER.error("Could not create object sizes", e);
         }
         
         {
@@ -594,12 +765,12 @@ public class DynamicVisualisationsUI extends Composite {
                 
                 @Override
                 public void widgetSelected(SelectionEvent e) {
-                    List<Pair<String, DynamicSizeContribution>> collect = suppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+                    List<Pair<String, DynamicSizeContribution>> collect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
                     Simantics.getSession().asyncRequest(new WriteRequest() {
                         
                         @Override
                         public void perform(WriteGraph graph) throws DatabaseException {
-                            DistrictNetworkUtil.setSizeContributions(graph, DynamicVisualisationsUI.this.diagramResource, collect);
+                            DistrictNetworkUtil.setSizeContributions(graph, visualisation.getVisualisationResource(), collect);
                         }
                     });
                 }
@@ -630,7 +801,7 @@ public class DynamicVisualisationsUI extends Composite {
         
         label = new Label(parent, SWT.NONE);
         label.setText("Size");
-        sizeSizeCombo = new Combo(parent, SWT.NONE);
+        sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
         sizeSizeCombo.setItems(Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new));
         
         Button applyButton = new Button(parent, SWT.READ_ONLY);
@@ -643,18 +814,21 @@ public class DynamicVisualisationsUI extends Composite {
                 // persist changes
                 IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
                 if (activeEditor instanceof IResourceEditorPart) {
-                    Resource diagram = ((IResourceEditorPart) activeEditor).getResourceInput().getResource();
+                    
+                    String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
+                    String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
+                    
                     SizeBarOptions options = new SizeBarOptions()
                             .showSizeBars(showSizeButton.getSelection())
                             .showSizeBarsTicks(sizeTicksButton.getSelection())
-                            .withLocation(SizeBarsLocation.valueOf(sizeLocationCombo.getText().toUpperCase()))
-                            .withSize(SizeBarsSize.valueOf(sizeSizeCombo.getText().toUpperCase()));
+                            .withLocation(SizeBarsLocation.valueOf(sizeLocation))
+                            .withSize(SizeBarsSize.valueOf(sizeSize));
 
                     Simantics.getSession().asyncRequest(new WriteRequest() {
                         
                         @Override
                         public void perform(WriteGraph graph) throws DatabaseException {
-                            DistrictNetworkUtil.setSizeBarOptions(graph, diagram, options);
+                            DistrictNetworkUtil.setSizeBarOptions(graph, visualisation.getVisualisationResource(), options);
                         }
                     });
                 }
@@ -670,13 +844,48 @@ public class DynamicVisualisationsUI extends Composite {
     }
 
     private void updateListening() {
-        if (listener != null) {
+        if (visualisationsListener != null)
+            visualisationsListener.dispose();
+        visualisationsListener = new VisualisationsListener(this);
+        Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), visualisationsListener);
+        
+        if (listener != null)
             listener.dispose();
-        }
         listener = new VisualisationListener(this);
-        Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), listener);
+        Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(diagramResource), listener);
     }
 
+    private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
+
+        private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
+
+        private boolean disposed;
+        private DynamicVisualisationsUI ui;
+        
+        public VisualisationsListener(DynamicVisualisationsUI ui) {
+            this.ui = ui;
+        }
+
+        @Override
+        public void execute(Collection<NamedResource> result) {
+            ui.updateVisualisations(result);
+        }
+
+        @Override
+        public void exception(Throwable t) {
+            LOGGER.error("Could not listen visualisation", t);
+        }
+
+        @Override
+        public boolean isDisposed() {
+            return disposed || ui.isDisposed();
+        }
+
+        public void dispose() {
+            this.disposed = true;
+        }
+    }
+    
     private static class VisualisationListener implements Listener<DynamicVisualisation> {
 
         private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
@@ -710,69 +919,90 @@ public class DynamicVisualisationsUI extends Composite {
 
     public void updateVisualisation(DynamicVisualisation result) {
         this.visualisation = result;
-        Display.getDefault().asyncExec(() -> {
-            if (getParent().isDisposed())
-                return;
-            
-            Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
-            for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
+        if (visualisation != null) {
+            Display.getDefault().asyncExec(() -> {
+                if (getParent().isDisposed())
+                    return;
                 
-                ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
-                if (coloringObjectRow != null) {
-                    
-                    coloringObjectRow.update(entry.getValue());
+                
+                String[] items = templateSelectionCombo.getItems();
+                for (int i = 0; i < items.length; i++) {
+                    if (visualisation.getName().equals(items[i])) {
+                        templateSelectionCombo.select(i);
+                        break;
+                    }
+                }
+                
+                Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
+                for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
                     
-                } else {
-                    LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
+                    ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
+                    if (coloringObjectRow != null) {
+                        
+                        coloringObjectRow.update(entry.getValue());
+                        
+                    } else {
+                        LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
+                    }
                 }
-            }
-            ColorBarOptions colorOptions = visualisation.getColorBarOptions();
-            showColorButton.setSelection(colorOptions.isShowColorBars());
-            colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
-            for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
-                String item = colorLocationCombo.getItem(i);
-                if (item.equals(colorOptions.getLocation().toString())) {
-                    colorLocationCombo.select(i);
-                    break;
+                ColorBarOptions colorOptions = visualisation.getColorBarOptions();
+                showColorButton.setSelection(colorOptions.isShowColorBars());
+                colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
+                for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
+                    String item = colorLocationCombo.getItem(i);
+                    if (item.equals(colorOptions.getLocation().toString())) {
+                        colorLocationCombo.select(i);
+                        break;
+                    }
                 }
-            }
-            for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
-                String item = colorSizeCombo.getItem(i);
-                if (item.equals(colorOptions.getSize().toString())) {
-                    colorSizeCombo.select(i);
-                    break;
+                for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
+                    String item = colorSizeCombo.getItem(i);
+                    if (item.equals(colorOptions.getSize().toString())) {
+                        colorSizeCombo.select(i);
+                        break;
+                    }
                 }
-            }
-            
-            Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
-            for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
                 
-                SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
-                if (sizingObjectRow != null) {
-                    
-                    sizingObjectRow.update(entry.getValue());
+                Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
+                for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
                     
-                } else {
-                    LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
+                    SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
+                    if (sizingObjectRow != null) {
+                        
+                        sizingObjectRow.update(entry.getValue());
+                        
+                    } else {
+                        LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
+                    }
                 }
-            }
-            SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
-            showSizeButton.setSelection(sizeOptions.isShowSizeBars());
-            sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
-            for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
-                String item = sizeLocationCombo.getItem(i);
-                if (item.equals(sizeOptions.getLocation().toString())) {
-                    sizeLocationCombo.select(i);
-                    break;
+                SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
+                showSizeButton.setSelection(sizeOptions.isShowSizeBars());
+                sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
+                for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
+                    String item = sizeLocationCombo.getItem(i);
+                    if (item.equals(sizeOptions.getLocation().toString())) {
+                        sizeLocationCombo.select(i);
+                        break;
+                    }
                 }
-            }
-            for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
-                String item = sizeSizeCombo.getItem(i);
-                if (item.equals(sizeOptions.getSize().toString())) {
-                    sizeSizeCombo.select(i);
-                    break;
+                for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
+                    String item = sizeSizeCombo.getItem(i);
+                    if (item.equals(sizeOptions.getSize().toString())) {
+                        sizeSizeCombo.select(i);
+                        break;
+                    }
                 }
-            }
+            });
+        }
+    }
+
+    public void updateVisualisations(Collection<NamedResource> result) {
+        this.visualisations = result;
+        
+        Display.getDefault().asyncExec(() -> {
+            if (getParent().isDisposed())
+                return;
+            templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
         });
     }
 }
index 22aa7266bb7bec89d5170395d24718062ac1e973..6a7b453799f725c15e56b5d43d9e0ba5782aafcc 100644 (file)
@@ -402,9 +402,8 @@ public class DistrictNetworkUtil {
         return results;
     }
 
-    public static ColorBarOptions colorBarOptions(ReadGraph graph, Resource diagram) throws DatabaseException {
+    public static ColorBarOptions colorBarOptions(ReadGraph graph, Resource visualisation) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
         if (visualisation != null) {
             String colorBarLocation = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ColorBarLocation, Bindings.STRING);
             String colorBarSize = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ColorBarSize, Bindings.STRING);
@@ -421,25 +420,26 @@ public class DistrictNetworkUtil {
         return ColorBarOptions.useDefault();
     }
 
-    public static void setColorBarOptions(WriteGraph graph, Resource diagram, ColorBarOptions options) throws DatabaseException {
+    public static void setColorBarOptions(WriteGraph graph, Resource visualisation, ColorBarOptions options) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
-        if (visualisation == null) {
-            Layer0 L0 = Layer0.getInstance(graph);
-            visualisation = graph.newResource();
-            graph.claim(visualisation, L0.InstanceOf, DN.Diagram_Visualisations);
-            graph.claimLiteral(visualisation, L0.HasName, "Visualisation");
-            graph.claim(diagram, DN.Diagram_hasVisualisation, visualisation);
-        }
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ColorBarLocation, options.getLocation().toString(), Bindings.STRING);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ColorBarSize, options.getSize().toString(), Bindings.STRING);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowColorBars, options.isShowColorBars(), Bindings.BOOLEAN);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowColorBarTicks, options.isShowColorBarsTicks(), Bindings.BOOLEAN);
     }
+    
+    public static Resource createVisualisation(WriteGraph graph, Resource diagram, String visualisationName) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+        Resource visualisation = graph.newResource();
+        graph.claim(visualisation, L0.InstanceOf, DN.Diagram_Visualisations);
+        graph.claimLiteral(visualisation, L0.HasName, visualisationName);
+        graph.claim(diagram, DN.Diagram_hasVisualisation, visualisation);
+        return visualisation;
+    }
 
-    public static SizeBarOptions sizeBarOptions(ReadGraph graph, Resource diagram) throws DatabaseException {
+    public static SizeBarOptions sizeBarOptions(ReadGraph graph, Resource visualisation) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
         if (visualisation != null) {
             String sizeBarLocation = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_SizeBarLocation, Bindings.STRING);
             String sizeBarSize = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_SizeBarSize, Bindings.STRING);
@@ -456,25 +456,16 @@ public class DistrictNetworkUtil {
         return SizeBarOptions.useDefault();
     }
 
-    public static void setSizeBarOptions(WriteGraph graph, Resource diagram, SizeBarOptions options) throws DatabaseException {
+    public static void setSizeBarOptions(WriteGraph graph, Resource visualisation, SizeBarOptions options) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
-        if (visualisation == null) {
-            Layer0 L0 = Layer0.getInstance(graph);
-            visualisation = graph.newResource();
-            graph.claim(visualisation, L0.InstanceOf, DN.Diagram_Visualisations);
-            graph.claimLiteral(visualisation, L0.HasName, "Visualisation");
-            graph.claim(diagram, DN.Diagram_hasVisualisation, visualisation);
-        }
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_SizeBarLocation, options.getLocation().toString(), Bindings.STRING);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_SizeBarSize, options.getSize().toString(), Bindings.STRING);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowSizeBars, options.isShowSizeBars(), Bindings.BOOLEAN);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowSizeBarTicks, options.isShowSizeBarsTicks(), Bindings.BOOLEAN);
     }
 
-    public static Map<String, DynamicColorContribution> colorContributions(ReadGraph graph, Resource diagram) throws DatabaseException {
+    public static Map<String, DynamicColorContribution> colorContributions(ReadGraph graph, Resource visualisation) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
         if (visualisation == null) {
             return Collections.emptyMap();
         }
@@ -504,19 +495,15 @@ public class DistrictNetworkUtil {
         return contributions;
     }
     
-    public static void setColorContributions(WriteGraph graph, Resource diagram, List<Pair<String, DynamicColorContribution>> collect) throws DatabaseException {
+    public static void setColorContributions(WriteGraph graph, Resource visualisation, List<Pair<String, DynamicColorContribution>> collect) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
-        if (visualisation == null) {
-            Layer0 L0 = Layer0.getInstance(graph);
-            visualisation = graph.newResource();
-            graph.claim(visualisation, L0.InstanceOf, DN.Diagram_Visualisations);
-            graph.claimLiteral(visualisation, L0.HasName, "Visualisation");
-            graph.claim(diagram, DN.Diagram_hasVisualisation, visualisation);
-        }
+        Layer0 L0 = Layer0.getInstance(graph);
+        
         graph.deny(visualisation, DN.Diagram_Visualisations_colorContributions);
         for (Pair<String, DynamicColorContribution> coll : collect) {
             Resource colorContribution = graph.newResource();
+            graph.claim(colorContribution, L0.InstanceOf, DN.Diagram_Visualisations_ColorContribution);
+            graph.claimLiteral(colorContribution, L0.HasName, coll.first);
             
             DynamicColorContribution contr = coll.second;
             graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionContributorName, coll.first);
@@ -536,9 +523,8 @@ public class DistrictNetworkUtil {
         }
     }
 
-    public static Map<String, DynamicSizeContribution> sizeContributions(ReadGraph graph, Resource diagram) throws DatabaseException {
+    public static Map<String, DynamicSizeContribution> sizeContributions(ReadGraph graph, Resource visualisation) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
         if (visualisation == null) {
             return Collections.emptyMap();
         }
@@ -568,36 +554,38 @@ public class DistrictNetworkUtil {
         return contributions;
     }
     
-    public static void setSizeContributions(WriteGraph graph, Resource diagram, List<Pair<String, DynamicSizeContribution>> collect) throws DatabaseException {
+    public static void setSizeContributions(WriteGraph graph, Resource visualisation, List<Pair<String, DynamicSizeContribution>> collect) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisation = graph.getPossibleObject(diagram, DN.Diagram_hasVisualisation);
-        if (visualisation == null) {
-            Layer0 L0 = Layer0.getInstance(graph);
-            visualisation = graph.newResource();
-            graph.claim(visualisation, L0.InstanceOf, DN.Diagram_Visualisations);
-            graph.claimLiteral(visualisation, L0.HasName, "Visualisation");
-            graph.claim(diagram, DN.Diagram_hasVisualisation, visualisation);
-        }
+        Layer0 L0 = Layer0.getInstance(graph);
+
         graph.deny(visualisation, DN.Diagram_Visualisations_sizeContributions);
         for (Pair<String, DynamicSizeContribution> coll : collect) {
-            Resource colorContribution = graph.newResource();
+            Resource sizeContribution = graph.newResource();
+            graph.claim(sizeContribution, L0.InstanceOf, DN.Diagram_Visualisations_SizeContribution);
+            graph.claimLiteral(sizeContribution, L0.HasName, coll.first);
             
             DynamicSizeContribution contr = coll.second;
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionContributorName, coll.first);
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionLabel, contr.getLabel());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionModuleName, contr.getModuleName());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionModuleAttribute, contr.getAttributeName());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionUnit, contr.getUnit());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionVariableGain, contr.getVariableGain());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionVariableBias, contr.getVariableBias());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionDefaultSizeMap, contr.getDefaultSizeMap().getLabel());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionDefaultMin, contr.getDefaultMin());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionDefaultMax, contr.getDefaultMax());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionUsed, contr.isUsed());
-            graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_sizeContributionUseDefault, contr.isUseDefault());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionContributorName, coll.first);
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionLabel, contr.getLabel());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionModuleName, contr.getModuleName());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionModuleAttribute, contr.getAttributeName());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionUnit, contr.getUnit());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionVariableGain, contr.getVariableGain());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionVariableBias, contr.getVariableBias());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionDefaultSizeMap, contr.getDefaultSizeMap().getLabel());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionDefaultMin, contr.getDefaultMin());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionDefaultMax, contr.getDefaultMax());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionUsed, contr.isUsed());
+            graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionUseDefault, contr.isUseDefault());
             
-            graph.claim(visualisation, DN.Diagram_Visualisations_sizeContributions, colorContribution);
+            graph.claim(visualisation, DN.Diagram_Visualisations_sizeContributions, sizeContribution);
         }
     }
 
+    public static void setActiveVisualisation(WriteGraph graph, Resource diagram, Resource visualisationTemplate) throws DatabaseException {
+        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+        graph.deny(diagram, DN.Diagram_hasActiveVisualisation);
+        graph.claim(diagram, DN.Diagram_hasActiveVisualisation, visualisationTemplate);
+    }
+
 }
diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/ActiveDynamicVisualisationsRequest.java b/org.simantics.district.network/src/org/simantics/district/network/profile/ActiveDynamicVisualisationsRequest.java
new file mode 100644 (file)
index 0000000..52cfd61
--- /dev/null
@@ -0,0 +1,43 @@
+package org.simantics.district.network.profile;
+
+import java.util.Map;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.layer0.Layer0;
+
+/**
+ * @author Jani Simomaa
+ */
+public class ActiveDynamicVisualisationsRequest extends ResourceRead<DynamicVisualisation> {
+
+    public ActiveDynamicVisualisationsRequest(Resource diagram) {
+        super(diagram);
+    }
+
+    @Override
+    public DynamicVisualisation perform(ReadGraph graph) throws DatabaseException {
+        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+        Resource visualisationResource = graph.getPossibleObject(resource, DN.Diagram_hasActiveVisualisation);
+        if (visualisationResource != null) {
+            String name = graph.getRelatedValue(visualisationResource, Layer0.getInstance(graph).HasName);
+            Map<String, DynamicColorContribution> colorContributions = DistrictNetworkUtil.colorContributions(graph, visualisationResource);
+            ColorBarOptions colorBarOptions = DistrictNetworkUtil.colorBarOptions(graph, visualisationResource);
+            Map<String, DynamicSizeContribution> sizeContributions = DistrictNetworkUtil.sizeContributions(graph, visualisationResource);
+            SizeBarOptions sizeBarOptions = DistrictNetworkUtil.sizeBarOptions(graph, visualisationResource);
+            DynamicVisualisation visualisation = new DynamicVisualisation(name, visualisationResource, colorContributions, colorBarOptions, sizeContributions, sizeBarOptions);
+            return visualisation; 
+        }
+        return null;
+    }
+
+}
index c4d9d209a5e70420ffb4fe128a2cf5ed26fba82f..3c187a10db8045b3b2c996b523f0826cb052c77b 100644 (file)
@@ -1,43 +1,38 @@
 package org.simantics.district.network.profile;
 
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.district.network.DistrictNetworkUtil;
 import org.simantics.district.network.ontology.DistrictNetworkResource;
-import org.simantics.district.network.visualisations.model.ColorBarOptions;
-import org.simantics.district.network.visualisations.model.DynamicColorContribution;
-import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
-import org.simantics.district.network.visualisations.model.DynamicVisualisation;
-import org.simantics.district.network.visualisations.model.SizeBarOptions;
 import org.simantics.layer0.Layer0;
 
 /**
  * @author Jani Simomaa
  */
-public class DynamicVisualisationsRequest extends ResourceRead<DynamicVisualisation> {
+public class DynamicVisualisationsRequest extends ResourceRead<Collection<NamedResource>> {
 
     public DynamicVisualisationsRequest(Resource diagram) {
         super(diagram);
     }
 
     @Override
-    public DynamicVisualisation perform(ReadGraph graph) throws DatabaseException {
+    public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        Resource visualisationResource = graph.getPossibleObject(resource, DN.Diagram_hasVisualisation);
-        if (visualisationResource != null) {
-            String name = graph.getRelatedValue(visualisationResource, Layer0.getInstance(graph).HasName);
-            Map<String, DynamicColorContribution> colorContributions = DistrictNetworkUtil.colorContributions(graph, resource);
-            ColorBarOptions colorBarOptions = DistrictNetworkUtil.colorBarOptions(graph, resource);
-            Map<String, DynamicSizeContribution> sizeContributions = DistrictNetworkUtil.sizeContributions(graph, resource);
-            SizeBarOptions sizeBarOptions = DistrictNetworkUtil.sizeBarOptions(graph, resource);
-            DynamicVisualisation visualisation = new DynamicVisualisation(name, colorContributions, colorBarOptions, sizeContributions, sizeBarOptions);
-            return visualisation; 
+        Collection<Resource> visualisationResources = graph.getObjects(resource, DN.Diagram_hasVisualisation);
+        List<NamedResource> results = new ArrayList<>();
+        if (visualisationResources != null && !visualisationResources.isEmpty()) {
+            for (Resource visualisationResource : visualisationResources) {
+                String name = graph.getRelatedValue(visualisationResource, Layer0.getInstance(graph).HasName);
+                results.add(new NamedResource(name, visualisationResource));
+            }
         }
-        return null;
+        return results;
     }
 
 }
index a29b311ed2098788e126666276d3d3d36b9d8809..05ed85bd47e4c90b31323fab0de19415b3562b53 100644 (file)
@@ -22,7 +22,7 @@ public class RuntimeDynamicVisualisationsRequest extends ResourceRead<DynamicVis
         DiagramResource DIA = DiagramResource.getInstance(graph);
         Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration);
         if (diagram != null) {
-            return graph.syncRequest(new DynamicVisualisationsRequest(diagram), TransientCacheAsyncListener.instance());
+            return graph.syncRequest(new ActiveDynamicVisualisationsRequest(diagram), TransientCacheAsyncListener.instance());
         }
         return null;
     }
index ea88e9de397fa7fecf168a64f86eb34a7c998c6a..24cf9bed9a6bb2acaa97349e09eec29aaff99c4e 100644 (file)
@@ -2,23 +2,35 @@ package org.simantics.district.network.visualisations.model;
 
 import java.util.Map;
 
+import org.simantics.db.Resource;
+
 public class DynamicVisualisation {
 
     private String name;
+    private Resource visualisationResource;
 
     private Map<String, DynamicColorContribution> colorContributions;
     private ColorBarOptions colorBarOptions;
     private Map<String, DynamicSizeContribution> sizeContributions;
     private SizeBarOptions sizeBarOptions;
     
-    public DynamicVisualisation(String name, Map<String, DynamicColorContribution> colorContributions, ColorBarOptions colorBarOptions, Map<String, DynamicSizeContribution> sizeContributions, SizeBarOptions sizeBarOptions) {
+    public DynamicVisualisation(String name, Resource visualisationResource, Map<String, DynamicColorContribution> colorContributions, ColorBarOptions colorBarOptions, Map<String, DynamicSizeContribution> sizeContributions, SizeBarOptions sizeBarOptions) {
         this.name = name;
+        this.visualisationResource = visualisationResource;
         this.colorContributions = colorContributions;
         this.colorBarOptions = colorBarOptions;
         this.sizeContributions = sizeContributions;
         this.sizeBarOptions = sizeBarOptions;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public Resource getVisualisationResource() {
+        return visualisationResource;
+    }
+
     public Map<String, DynamicColorContribution> getColorContributions() {
         return colorContributions;
     }