]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Improve HoverInfoStyle performance for district network diagrams 72/3472/1
authorjsimomaa <jani.simomaa@gmail.com>
Wed, 6 Nov 2019 12:22:34 +0000 (14:22 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 7 Nov 2019 12:41:19 +0000 (12:41 +0000)
gitlab #44

Change-Id: I8c3a399153a024ca1a17cee7f9c396fb470e7f2b
(cherry picked from commit 7c1f539de88c6ca79b2ac6dc891be3f45282abe2)

org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkHoverInfoNode.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DynamicVisualisationContributionsParticipant.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/styles/DistrictNetworkHoverInfoStyle.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/visualisations/DynamicVisualisationsUI.java
org.simantics.district.network/src/org/simantics/district/network/visualisations/DynamicVisualisations.java

index 85c23f4de06a2c66f4e3a520f5871d7f2ee278f1..25956b31aaa701d772a2cc4fb3be0af0e7786c61 100644 (file)
@@ -72,9 +72,10 @@ public class DistrictDiagramViewer extends DiagramViewer {
         AffineTransform tr = new AffineTransform(MapScalingTransform.INSTANCE);
         ctx.add(new MapPainter(tr));
         
-        ctx.add(new NetworkDrawingParticipant(tr));
+        DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant = new DynamicVisualisationContributionsParticipant(tr);
+        ctx.add(new NetworkDrawingParticipant(dynamicVisualisationContributionsParticipant, tr));
         ctx.add(new ElevationServerParticipant(tr));
-        ctx.add(new DynamicVisualisationContributionsParticipant(tr));
+        ctx.add(dynamicVisualisationContributionsParticipant);
         
         // Optimize AffineTransform memory allocations during district diagram rendering
         G2DParentNode spatialRoot = (G2DParentNode) ctx.getSceneGraph().lookupNode(SceneGraphConstants.SPATIAL_ROOT_NODE_ID);
index da2bf32aec1a6ab3170e1386da2dddda8a2e9b7b..77ec735f6d2cc14c9f6013127244b6e82fac3ace 100644 (file)
@@ -7,18 +7,22 @@ import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.simantics.db.Resource;
+import org.simantics.diagram.ui.DiagramModelHints;
 import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement;
 import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
 import org.simantics.district.network.ui.nodes.DistrictNetworkEdgeNode;
 import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
 import org.simantics.district.network.ui.nodes.HoverSensitiveNode;
 import org.simantics.district.network.ui.nodes.NetworkDrawingNode;
+import org.simantics.district.network.ui.participants.DynamicVisualisationContributionsParticipant;
 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
 import org.simantics.g2d.diagram.IDiagram;
 import org.simantics.g2d.diagram.handler.PickContext;
 import org.simantics.g2d.diagram.handler.PickRequest;
 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.g2d.element.ElementHints;
 import org.simantics.g2d.element.IElement;
 import org.simantics.scenegraph.Node;
 import org.simantics.scenegraph.g2d.G2DParentNode;
@@ -47,9 +51,11 @@ public class NetworkDrawingParticipant extends AbstractDiagramParticipant {
     
     private NetworkDrawingNode node;
 
+    private DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant;
     private AffineTransform transform;
     
-    public NetworkDrawingParticipant(AffineTransform transform) {
+    public NetworkDrawingParticipant(DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant, AffineTransform transform) {
+        this.dynamicVisualisationContributionsParticipant = dynamicVisualisationContributionsParticipant;
         this.transform = transform;
     }
 
@@ -72,10 +78,35 @@ public class NetworkDrawingParticipant extends AbstractDiagramParticipant {
 
         List<IElement> snap = diagram.getSnapshot();
 
-        boolean changed = false;
-        changed |= hoverNodes(snap, false, isConnectionTool, currentMousePos);
-        changed |= hoverNodes(pickables, true, isConnectionTool, currentMousePos);
-        return changed;
+        hoverNodes2(pickables, true, isConnectionTool, currentMousePos);
+        // we repaint ourselves once the async calulation is ready
+        return false;
+        
+//        boolean changed = false;
+//        changed |= hoverNodes(snap, false, isConnectionTool, currentMousePos);
+//        changed |= hoverNodes(pickables, true, isConnectionTool, currentMousePos);
+        //return changed;
+    }
+
+    private boolean hoverNodes2(List<IElement> elements, boolean hover, boolean isConnectionTool, Point2D p) {
+        if (elements == null || elements.isEmpty()) {
+            return dynamicVisualisationContributionsParticipant.doHover(false, isConnectionTool);
+        } else {
+            boolean changed = dynamicVisualisationContributionsParticipant.doHover(true, isConnectionTool);
+            if (changed) {
+                // we prefer the first picked element only
+                IElement elem = elements.get(0);
+                G2DParentNode node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+                if (node instanceof DistrictNetworkVertexNode) {
+                } else {
+                    node = elem.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
+                }
+                Resource mapElement = elem.getHint(ElementHints.KEY_OBJECT);
+                Resource runtimeDiagram = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);
+                dynamicVisualisationContributionsParticipant.hoverNode(runtimeDiagram, mapElement, node);
+            }
+            return changed;
+        }
     }
 
     private boolean hoverNodes(List<IElement> elements, boolean hover, boolean isConnectionTool, Point2D p) {
index 7a75ad5f2e4382390f798ebc0ea38ea7c7614da5..07ad2eedb4df1decd66f4ac0e965a76a67d6039c 100644 (file)
@@ -13,9 +13,13 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle;
 import org.simantics.maps.MapScalingTransform;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.NodeException;
 import org.simantics.scenegraph.ParentNode;
 import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.g2d.G2DParentNode;
 import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
 import org.simantics.scenegraph.utils.DPIUtil;
 import org.simantics.scenegraph.utils.NodeUtil;
 import org.simantics.scl.runtime.Lists;
@@ -42,12 +46,10 @@ public class DistrictNetworkHoverInfoNode extends G2DNode implements HoverSensit
 
        private Point2D mousePosition;
        
-       private static AtomicReference<DistrictNetworkHoverInfoNode> activeNode = new AtomicReference<>();
+       private static AtomicReference<G2DParentNode> activeNode = new AtomicReference<>();
 
        @Override
        public void render(Graphics2D g) {
-               if (!hover || activeNode.get() != this)
-                       return;
 
                ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(this, RTreeNode.class);
                DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED) : null;
@@ -59,6 +61,8 @@ public class DistrictNetworkHoverInfoNode extends G2DNode implements HoverSensit
        
        @Override
        public void renderDeferred(Graphics2D g) {
+           if (!hover || activeNode.get() == null)
+               return;
                AffineTransform ot = g.getTransform();
                Font of = g.getFont();
                doRender(g);
@@ -67,7 +71,10 @@ public class DistrictNetworkHoverInfoNode extends G2DNode implements HoverSensit
        }
 
        private void doRender(Graphics2D g) {
-               g.transform(MapScalingTransform.INVERSE);
+           AffineTransform tt = getTransform();
+               g.transform(tt);
+               if (mousePosition == null)
+                   return;
                g.translate(mousePosition.getX(), mousePosition.getY());
                //g.translate(origin.getX(), origin.getY());
                double scale = 1.5 / g.getTransform().getScaleX();
@@ -119,15 +126,15 @@ public class DistrictNetworkHoverInfoNode extends G2DNode implements HoverSensit
 
        @Override
        public boolean hover(boolean hover, boolean isConnectionTool) {
-               hover = hover && activeNode.updateAndGet(current -> current == null ? this : current) == this;
+//             hover = hover && activeNode.updateAndGet(current -> current == null ? this : current) == this;
                boolean changed = hover != this.hover;
                this.hover = hover;
-               
-               if (changed) {
-                       if (!hover) activeNode.updateAndGet(current -> current == this ? null : current);
-                       repaint();
-               }
-               
+//             
+//             if (changed) {
+//                     if (!hover) activeNode.updateAndGet(current -> current == this ? null : current);
+//                     repaint();
+//             }
+//             
                return changed;
        }
        
@@ -139,6 +146,31 @@ public class DistrictNetworkHoverInfoNode extends G2DNode implements HoverSensit
        @Override
        public void delete() {
                super.delete();
-               activeNode.getAndUpdate(current -> current == this ? null : current);
+               activeNode.set(null);
        }
+
+    public void hover2(G2DParentNode hoveredNode) {
+        ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
+        if (root != null) {
+            
+            INode child = ProfileVariables.browseChild(root, "");
+            if(child == null) {
+                throw new NullPointerException("Scenegraph child node was not found: " + "");
+            }
+
+            INode existing = NodeUtil.getChildById(child, DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED);
+            if (existing == null) {
+                if (child instanceof ParentNode<?>) {
+                    existing = ((ParentNode<?>) child).addNode(DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED, DeferredRenderingNode.class);
+                    ((DeferredRenderingNode)existing).setZIndex(Integer.MAX_VALUE);
+                } else {
+                    throw new NodeException("Cannot claim child node for non-parent-node " + child);
+                }
+            }
+        }
+
+        activeNode.set(hoveredNode);
+        repaint();
+    }
+
 }
index 690860620059dc9c7802b2bf7bfa0468c840692b..0e0bace92245003ed5b7fec4f22745a4c9a5ede5 100644 (file)
@@ -1,17 +1,34 @@
 package org.simantics.district.network.ui.participants;
 
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.profile.RuntimeDynamicVisualisationsRequest;
 import org.simantics.district.network.ui.DistrictDiagramViewer;
+import org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoNode;
 import org.simantics.district.network.ui.nodes.DynamicVisualisationContributionsNode;
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle;
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle.StyleResult;
 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.g2d.canvas.ICanvasContext;
 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.layer0.Layer0;
 import org.simantics.scenegraph.g2d.G2DParentNode;
 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
@@ -19,9 +36,15 @@ import org.simantics.utils.datastructures.hints.HintListenerAdapter;
 import org.simantics.utils.datastructures.hints.IHintContext.Key;
 import org.simantics.utils.datastructures.hints.IHintListener;
 import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.ThreadUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DynamicVisualisationContributionsParticipant extends AbstractCanvasParticipant {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationContributionsParticipant.class);
+
     IHintListener hintListener = new HintListenerAdapter() {
         public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
             ICanvasContext cc = getContext();
@@ -34,7 +57,9 @@ public class DynamicVisualisationContributionsParticipant extends AbstractCanvas
     
     private DynamicVisualisationContributionsNode node;
     private AffineTransform transform;
-    
+
+    private DistrictNetworkHoverInfoNode hoverInfoNode;
+
     public DynamicVisualisationContributionsParticipant(AffineTransform tr) {
         this.transform = tr;
     }
@@ -63,6 +88,11 @@ public class DynamicVisualisationContributionsParticipant extends AbstractCanvas
         node.setTransform(transform);
         node.setEnabled(true);
         node.setZIndex(1000);
+        
+        hoverInfoNode = parent.addNode("districtNetworkHoverInfoNode", DistrictNetworkHoverInfoNode.class);
+        hoverInfoNode.setLookupId("districtNetworkHoverInfoNode");
+        hoverInfoNode.setTransform(transform);
+        hoverInfoNode.setZIndex(Integer.MAX_VALUE - 500);
     }
     
     @EventHandler(priority = 0)
@@ -113,4 +143,80 @@ public class DynamicVisualisationContributionsParticipant extends AbstractCanvas
         SizeBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS);
         return options;
     }
+
+    private ScheduledFuture<?> hoverUpdateSchedule;
+    
+    public void hoverNode(Resource runtimeDiagram, Resource mapElement, G2DParentNode hoveredNode) {
+        IThreadWorkQueue thread = getThread();
+        Simantics.getSession().asyncRequest(new ReadRequest() {
+
+            @Override
+            public void run(ReadGraph graph) throws DatabaseException {
+                DynamicVisualisation visualisation = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram));
+                if (visualisation == null)
+                    return;
+                if (hoverUpdateSchedule != null && !hoverUpdateSchedule.isDone()) {
+                    hoverUpdateSchedule.cancel(false);
+                }
+                hoverUpdateSchedule = ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(() -> {
+                    
+                    CompletableFuture<Object> future = new CompletableFuture<>();
+                    try {
+                        Simantics.getSession().syncRequest(new ReadRequest() {
+
+                            @Override
+                            public void run(ReadGraph graph) throws DatabaseException {
+                                boolean keyVariablesVertexHover = visualisation.isKeyVariablesVertexHover();
+                                boolean keyVariablesEdgesHover = visualisation.isKeyVariablesEdgesHover();
+                                
+                                Resource mapElementInstanceOf = graph.getSingleObject(mapElement, Layer0.getInstance(graph).InstanceOf);
+                                DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+                                
+                                boolean doHover = true;
+                                if (mapElementInstanceOf.equals(DN.Vertex) && !keyVariablesVertexHover) {
+                                    doHover = false;
+                                } else if (mapElementInstanceOf.equals(DN.Edge) && !keyVariablesEdgesHover) {
+                                    doHover = false;
+                                }
+                                final boolean finalDoHover = doHover;
+                                
+                                StyleResult results = DistrictNetworkHoverInfoStyle.doCalculateStyleResult(graph, runtimeDiagram, mapElement);
+                                if (results != null) {
+                                    Point2D location = DistrictNetworkHoverInfoStyle.calculatePoint(graph, mapElement);
+                                    thread.asyncExec(() -> {
+                                        if (isRemoved())
+                                            return;
+                                        if (finalDoHover) {
+                                            hoverInfoNode.setLabels(results.getLabels());
+                                            hoverInfoNode.setOrigin(results.getOrigin());
+                                            
+                                            hoverInfoNode.setMousePosition(location);
+                                            hoverInfoNode.hover2(hoveredNode);
+                                        } else {
+                                            hoverInfoNode.hover2(null);
+                                        }
+                                        future.complete(new Object());
+                                    });
+                                } else {
+                                    future.complete(new Object());
+                                }
+                            }
+                        });
+                    } catch (DatabaseException e) {
+                        future.completeExceptionally(e);
+                    }
+                    // this waits until everything is done
+                    try {
+                        future.get();
+                    } catch (InterruptedException | ExecutionException e) {
+                        LOGGER.debug("Interrupted hovering", e);
+                    }
+                }, 0, visualisation.getInterval(), TimeUnit.MILLISECONDS);
+            }
+        });
+    }
+
+    public boolean doHover(boolean hover, boolean isConnectionTool) {
+        return hoverInfoNode.hover(hover, isConnectionTool);
+    }
 }
index 0694da06529f3867ddc0a78cf40a47bc785c00a0..4dac92c1b006f955811e389821af308d1150085d 100644 (file)
@@ -50,7 +50,7 @@ public class DistrictNetworkHoverInfoStyle extends StyleBase<DistrictNetworkHove
        private static final String ACTIONS_MODULE = "Actions";
        private static final String HOVER_CONTRIBUTION = "hoverContribution";
 
-       public class StyleResult {
+       public static class StyleResult {
                Point2D origin;
                List<Tuple3> labels;
 
@@ -81,86 +81,97 @@ public class DistrictNetworkHoverInfoStyle extends StyleBase<DistrictNetworkHove
                Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
                return mappedElement != null ? graph.getPossibleObject(mappedElement, MOD.ElementToComponent) : null;
        }
-       
-       @Override
-       public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry,
-                       Resource mapElement, Variable configuration) throws DatabaseException {
-               DiagramResource DIA = DiagramResource.getInstance(graph);
-               StructuralResource2 STR = StructuralResource2.getInstance(graph);
-
-               String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING);
-               Variable activeVariable = org.simantics.db.layer0.variable.Variables.getPossibleVariable(graph, variableURI);
-               if (activeVariable == null)
-                       return null;
-
-               Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
-               if (module == null)
-                       return null;
-
-               Resource moduleType = graph.getPossibleType(module, STR.Component);
-               if (moduleType == null)
-                       return null;
-               
-               Function1<Variable, List<Tuple3>> function = getUCTextGridFunctionCached(graph, moduleType);
-               if (function == null)
-                       return null;
-               
-               List<Tuple3> result;
-               try {
-                       Variable variable = Variables.getVariable(graph, module);
-                       Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
-                       if (moduleVariable == null)
-                               moduleVariable = variable;
-
-                       result = Simantics.applySCLRead(graph, function, moduleVariable);
-               } catch (PendingVariableException | MissingVariableValueException e) {
-                       result = Collections.singletonList(new Tuple3("<pending>", "", ""));
-               } catch (MissingVariableException e) {
+
+    @Override
+    public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource mapElement,
+            Variable configuration) throws DatabaseException {
+        //return doCalculateStyleResult(graph, runtimeDiagram, mapElement);
+        return new StyleResult(calculatePoint(graph, mapElement), Collections.emptyList());
+    }
+
+    public static StyleResult doCalculateStyleResult(ReadGraph graph, Resource runtimeDiagram, Resource mapElement) throws DatabaseException {
+        DiagramResource DIA = DiagramResource.getInstance(graph);
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+        String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable,
+                Bindings.STRING);
+        Variable activeVariable = org.simantics.db.layer0.variable.Variables.getPossibleVariable(graph, variableURI);
+        if (activeVariable == null)
+            return null;
+
+        Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
+        if (module == null)
+            return null;
+
+        Resource moduleType = graph.getPossibleType(module, STR.Component);
+        if (moduleType == null)
+            return null;
+
+        Function1<Variable, List<Tuple3>> function = getUCTextGridFunctionCached(graph, moduleType);
+        if (function == null)
+            return null;
+
+        List<Tuple3> result;
+        try {
+            Variable variable = Variables.getVariable(graph, module);
+            Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
+            if (moduleVariable == null)
+                moduleVariable = variable;
+
+            result = Simantics.applySCLRead(graph, function, moduleVariable);
+        } catch (PendingVariableException | MissingVariableValueException e) {
+            result = Collections.singletonList(new Tuple3("<pending>", "", ""));
+        } catch (MissingVariableException e) {
             // the requested variable is missing from the UC
             String message = e.getMessage();
             LOGGER.warn("Missing variable for calculating style with function {} {}", function, message);
-            result = Collections.singletonList(new Tuple3("<" + message +">", "", ""));
+            result = Collections.singletonList(new Tuple3("<" + message + ">", "", ""));
         }
-               
-               Point2D point;
-               DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-               if (graph.isInstanceOf(mapElement, DN.Vertex)) {
-                       double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
-                       point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
-               }
-               else if (graph.isInstanceOf(mapElement, DN.Edge)) {
-                       Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
-                       double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
-                       Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
-                       double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
-                       point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2), null);
-               }
-               else {
-                       return null;
-               }
-               
-               return new StyleResult(point, result);
-       }
-       
+
+        Point2D point = calculatePoint(graph, mapElement);
+
+        return new StyleResult(point, result);
+    }
+    
+    public static Point2D calculatePoint(ReadGraph graph, Resource mapElement) throws DatabaseException {
+        Point2D point;
+        DiagramResource DIA = DiagramResource.getInstance(graph);
+        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+        if (graph.isInstanceOf(mapElement, DN.Vertex)) {
+            double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
+            point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
+        } else if (graph.isInstanceOf(mapElement, DN.Edge)) {
+            Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
+            double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
+            Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
+            double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
+            point = DistrictNetworkNodeUtils.calculatePoint2D(
+                    new Point2D.Double((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2), null);
+        } else {
+            return null;
+        }
+        return point;
+    }
+
        @Override
        public void applyStyleForNode(EvaluationContext observer, INode parent, StyleResult results) {
-               if (results == null) {
-                       cleanupStyleForNode(observer, parent);
-                       return;
-               }
-               
-               DistrictNetworkHoverInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkHoverInfoNode.NODE_KEY, DistrictNetworkHoverInfoNode.class, observer);
-               if (node == null)
-                       return;
-               
-               ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
-               if (root != null) {
-                       DeferredRenderingNode deferred = ProfileVariables.claimChild(root, "", HOVER_INFO_DEFERRED, DeferredRenderingNode.class, observer);
-                       deferred.setZIndex(Integer.MAX_VALUE);
-               }
-               
-               node.setLabels(results.getLabels());
-               node.setOrigin(results.getOrigin());
+//             if (results == null) {
+//                     cleanupStyleForNode(observer, parent);
+//                     return;
+//             }
+//             
+//             DistrictNetworkHoverInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkHoverInfoNode.NODE_KEY, DistrictNetworkHoverInfoNode.class, observer);
+//             if (node == null)
+//                     return;
+//             
+//             ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
+//             if (root != null) {
+//                     DeferredRenderingNode deferred = ProfileVariables.claimChild(root, "", HOVER_INFO_DEFERRED, DeferredRenderingNode.class, observer);
+//                     deferred.setZIndex(Integer.MAX_VALUE);
+//             }
+//             
+//             node.setLabels(results.getLabels());
+//             node.setOrigin(results.getOrigin());
        }
        
        @Override
index 5ec61fd79a7609a042ab906d503e984c7679b451..bb608eaad11b3bc5ce9cd07cd14eef0b46cb7b46 100644 (file)
@@ -98,6 +98,9 @@ public class DynamicVisualisationsUI {
     private Composite parent;
 
     private Button disableUpdatesButton;
+    private Button resetVisualisationButton;
+    private Button hoveringVertexEnabledButton;
+    private Button hoveringEdgesEnabledButton;
 
     private List<Supplier<Pair<String, DynamicArrowContribution>>> edgeArrowSuppliers;
 
@@ -248,7 +251,7 @@ public class DynamicVisualisationsUI {
         Group group = new Group(parent, SWT.NONE);
         group.setText("Interval");
         GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
-        GridLayoutFactory.fillDefaults().numColumns(4).margins(5, 5).applyTo(group);
+        GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
         
         createIntervalElements(group);
     }
@@ -264,6 +267,17 @@ public class DynamicVisualisationsUI {
         disableUpdatesButton.setText("Disable updates");
         addSelectionListener(disableUpdatesButton);
 
+        resetVisualisationButton = new Button(parent, SWT.CHECK);
+        resetVisualisationButton.setText("Reset Visualisation");
+        addSelectionListener(resetVisualisationButton);
+        
+        hoveringVertexEnabledButton = new Button(parent, SWT.CHECK);
+        hoveringVertexEnabledButton.setText("Vertex Key Variables on Hover");
+        addSelectionListener(hoveringVertexEnabledButton);
+        
+        hoveringEdgesEnabledButton = new Button(parent, SWT.CHECK);
+        hoveringEdgesEnabledButton.setText("Edge Key Variables on Hover");
+        addSelectionListener(hoveringEdgesEnabledButton);
     }
     
     private void initializeHideElements(Composite parent) {
@@ -611,6 +625,7 @@ public class DynamicVisualisationsUI {
         boolean dynamicSymbolsPumpingStations = dynamicSymbolsPumpingStationsButton.getSelection();
         
         boolean disabled = disableUpdatesButton.getSelection();
+        boolean resetVisualisation = resetVisualisationButton.getSelection();
         Long interval;
         try {
             interval = Long.parseLong(intervalText.getText());
@@ -618,7 +633,10 @@ public class DynamicVisualisationsUI {
             // ignore
             interval = 2000L;
         }
-        long ii = interval;
+        final long finalInterval = interval;
+        
+        boolean hoverVertex = hoveringVertexEnabledButton.getSelection();
+        boolean hoverEdges = hoveringEdgesEnabledButton.getSelection();
         
         Simantics.getSession().asyncRequest(new WriteRequest() {
             
@@ -630,7 +648,7 @@ public class DynamicVisualisationsUI {
                 } else {
                     exist = DynamicVisualisations.createVisualisation(graph, parentResource, templateName);
                 }
-                DynamicVisualisations.setIntervalAndDisabled(graph, exist, ii, disabled);
+                DynamicVisualisations.setIntervalAndDisabled(graph, exist, finalInterval, disabled, resetVisualisation);
                 DynamicVisualisations.setColorContributions(graph, exist, colorCollect);
                 DynamicVisualisations.setColorBarOptions(graph, exist, colorBarOptions);
                 DynamicVisualisations.setSizeContributions(graph, exist, sizeCollect);
@@ -657,6 +675,7 @@ public class DynamicVisualisationsUI {
                         dynamicSymbolsValves,
                         dynamicSymbolsPumpingStations
                     );
+                DynamicVisualisations.setKeyVariablesHover(graph, exist, hoverVertex, hoverEdges);
             }
         });
     }
@@ -1426,6 +1445,9 @@ public class DynamicVisualisationsUI {
                 intervalText.setText(Long.toString(visualisation.getInterval()));
                 disableUpdatesButton.setSelection(visualisation.disabledUpdates());
                 
+                hoveringVertexEnabledButton.setSelection(visualisation.isKeyVariablesVertexHover());
+                hoveringEdgesEnabledButton.setSelection(visualisation.isKeyVariablesEdgesHover());
+                
                 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
                 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
                     
index 249925d11c29431dc8569d002ba10bf36ce29096..cf4feead607fafc8b76f4bf079474a13ffa49651 100644 (file)
@@ -330,9 +330,16 @@ public class DynamicVisualisations {
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_DynamicSymbolsPumpingStations, pumpingStations, Bindings.BOOLEAN);
     }
 
-    public static void setIntervalAndDisabled(WriteGraph graph, Resource visualisation, long interval, boolean disabled) throws DatabaseException {
+    public static void setIntervalAndDisabled(WriteGraph graph, Resource visualisation, long interval, boolean disabled, boolean resetVisualisation) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_Interval, interval, Bindings.LONG);
         graph.claimLiteral(visualisation, DN.Diagram_Visualisations_DisabledUpdates, disabled, Bindings.BOOLEAN);
+        graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ResetVisualisation, resetVisualisation, Bindings.BOOLEAN);
+    }
+
+    public static void setKeyVariablesHover(WriteGraph graph, Resource visualisation, boolean hoverVertex, boolean hoverEdges) throws DatabaseException {
+        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+        graph.claimLiteral(visualisation, DN.Diagram_Visualisations_KeyVariableVertexHover, hoverVertex, Bindings.BOOLEAN);
+        graph.claimLiteral(visualisation, DN.Diagram_Visualisations_KeyVariableEdgeHover, hoverEdges, Bindings.BOOLEAN);
     }
 }