@@ -92,7 +92,6 @@ public class SmartGraphPanel<V, E> extends Pane {
9292 private final Map <Vertex <V >, SmartGraphVertexNode <V >> vertexNodes ;
9393 private final Map <Edge <E , V >, SmartGraphEdgeBase <E , V >> edgeNodes ;
9494 private final Map <Edge <E ,V >, Tuple <Vertex <V >>> connections ;
95- private final Map <Tuple <SmartGraphVertexNode <V >>, Integer > placedEdges = new HashMap <>();
9695 private boolean initialized = false ;
9796 private final boolean edgesWithArrows ;
9897
@@ -166,7 +165,10 @@ public SmartGraphPanel(@NamedArg("graph") Graph<V, E> theGraph,
166165
167166 this .vertexNodes = new HashMap <>();
168167 this .edgeNodes = new HashMap <>();
169- this .connections = new HashMap <>();
168+
169+ // We will explore the insertion order of edges for decreasing the multiplicity of edges between the same
170+ // pair of vertices, when others are removed
171+ this .connections = new LinkedHashMap <>();
170172
171173 // consumers initially are not set. This initialization is not necessary, but we make it explicit
172174 // for the sake of readability
@@ -662,12 +664,16 @@ private SmartGraphEdgeBase<E,V> createEdge(Edge<E, V> edge, SmartGraphVertexNode
662664 /*
663665 Edges will be placed with 'multiplicityIndex' starting at 0 for a single edge between a pair of vertices. This represents a straight edge.
664666 When more than an edge exists, the 'multiplicityIndex' will start at 1, forcing the edges to be curved.
667+
668+ Newer edges have higher multiplicity indices.
669+
670+ Note that, indirectly, multiplicity indices will be "recycled", since they are updated (decremented) when edges are removed.
671+ This is performed in 'updateParallelEdgesOf(edge)'.
665672 */
666673
667674 int maxIndex = getMaxMultiplicityIndexBetween (graphVertexInbound , graphVertexOutbound );
668675
669676 return new SmartGraphEdgeNode <>(edge , graphVertexInbound , graphVertexOutbound , ++maxIndex );
670-
671677 }
672678
673679 private void addVertex (SmartGraphVertexNode <V > v ) {
@@ -836,6 +842,9 @@ private void removeNodes() {
836842 }
837843
838844 connections .remove (e );
845+
846+ // Update the multiplicity of the edges between the removed edge connecting vertices
847+ updateParallelEdgesOf (edgeToRemove );
839848 }
840849
841850 //remove vertices (graphical elements) that were removed from the underlying graph
@@ -861,6 +870,45 @@ private void removeEdge(SmartGraphEdgeBase<E,V> e) {
861870 }
862871 }
863872
873+ /*
874+ * Update the multiplicity of the parallel edges of 'e'.
875+ * This is called from removeNodes(), after an edge is removed. Hence, 'e'
876+ * will be a removed edge. We want to update the multiplicities of the remaining
877+ * edges that still subsist after this one is removed.
878+ *
879+ * This work
880+ */
881+ private void updateParallelEdgesOf (SmartGraphEdgeBase <E ,V > e ) {
882+
883+ SmartGraphVertexNode <V > v = e .getInbound ();
884+ SmartGraphVertexNode <V > w = e .getOutbound ();
885+
886+ // 'getEdgesBetween' returns a collection of ages, ordered by their "age".
887+ List <SmartGraphEdgeBase <E , V >> parallelEdges = getEdgesBetween (v , w );
888+
889+ int numEdges = parallelEdges .size ();
890+ if (numEdges > 0 ) {
891+
892+ // Oldest edge will always have multiplicity 0 (straight line)
893+ parallelEdges .get (0 ).setMultiplicityIndex (0 );
894+
895+ // The remaining edges will have their multiplicities as close to 0 has possible,
896+ // while maintaining their parity (same side of the line axis)
897+ int current = 1 ;
898+ for (int i = 1 ; i < numEdges ; i ++) {
899+ int parity = parallelEdges .get (i ).getMultiplicityIndex () % 2 ;
900+
901+ while (current % 2 != parity ) {
902+ current ++;
903+ }
904+
905+ parallelEdges .get (i ).setMultiplicityIndex (current );
906+ current ++; // Move to the next possible value
907+ }
908+ }
909+
910+ }
911+
864912 private void removeVertex (SmartGraphVertexNode <V > v ) {
865913 getChildren ().remove (v );
866914
@@ -1078,25 +1126,39 @@ private int getTotalEdgesBetweenInModel(Vertex<V> v, Vertex<V> u) {
10781126 return count ;
10791127 }
10801128
1081- /*private int getTotalEdgesBetweenInPanel(SmartGraphVertexNode<V> v, SmartGraphVertexNode<V> u) {
1129+ /**
1130+ * Returns the edges between 'v' and 'u', by "age", starting with the "oldest".
1131+ * This is achieved because we use a LinkedHashMap for the 'connections' collection.
1132+ * The order of 'u' and 'v' is irrelevant.
1133+ *
1134+ * @param v first vertex
1135+ * @param u second vertex
1136+ * @return an ordered (by age) list of edges that exist between 'u' and 'v'
1137+ */
1138+ private List <SmartGraphEdgeBase <E , V >> getEdgesBetween (SmartGraphVertexNode <V > v , SmartGraphVertexNode <V > u ) {
10821139 Vertex <V > V = v .getUnderlyingVertex ();
10831140 Vertex <V > U = u .getUnderlyingVertex ();
10841141
1085- int count = 0;
1142+ List <SmartGraphEdgeBase <E , V >> parallelEdges = new ArrayList <>();
1143+
10861144 for (Map .Entry <Edge <E , V >, Tuple <Vertex <V >>> edgeTupleEntry : this .connections .entrySet ()) {
1087- // Edge<E, V> edge = edgeTupleEntry.getKey();
1145+ Edge <E , V > edge = edgeTupleEntry .getKey ();
10881146 Tuple <Vertex <V >> tuple = edgeTupleEntry .getValue ();
10891147
10901148 if ((tuple .first == V && tuple .second == U ) || (tuple .first == U && tuple .second == V )) {
1091- count++ ;
1149+ parallelEdges . add ( edgeNodes . get ( edge ) ) ;
10921150 }
10931151 }
10941152
1095- return count ;
1096- }*/
1153+ return parallelEdges ;
1154+ }
10971155
1098- /*
1099- * Finds the maximum multiplicity index for current edges between two vertices.
1156+ /**
1157+ * Finds the maximum multiplicity index for current edges between two vertices 'v' and 'u'.
1158+ * The order of 'v' and 'u' is irrelevant.
1159+ * @param v first vertex
1160+ * @param u second vertex
1161+ * @return the maximum multiplicity index for current edges between two vertices 'v' and 'u'
11001162 */
11011163 private int getMaxMultiplicityIndexBetween (SmartGraphVertexNode <V > v , SmartGraphVertexNode <V > u ) {
11021164 int max = -1 ;
0 commit comments