377377        #  generate a list of colors, one per segment
378378        segment_colors =  get (plotattributes, :linecolor , nothing )
379379        edge_label_array =  Vector {Tuple} ()
380+         edge_label_box_vertices_array =  Vector {Array} ()
380381        if  ! isa (edgelabel, Dict) &&  ! isnothing (edgelabel)
381382            tmp =  Dict ()
382383            if  length (size (edgelabel)) <  2 
392393            end 
393394            edgelabel =  tmp
394395        end 
396+         #  If the edgelabel dictionary is full of length two tuples, then make all of the
397+         #  tuples length three with last element 1. (i.e. a multigraph that has no extra
398+         #  edges).
399+         if  edgelabel isa  Dict
400+             for  key in  keys (edgelabel)
401+                 if  length (key) ==  2 
402+                     edgelabel[(key... , 1 )] =  edgelabel[key]
403+                 end 
404+             end 
405+         end 
395406        edge_has_been_seen =  Dict ()
396407        for  edge in  zip (source, destiny)
397408            edge_has_been_seen[edge] =  0 
@@ -456,16 +467,48 @@ end
456467                        push! (yseg, NaN )
457468                    else 
458469                        xpt, ypt =  if  method !=  :chorddiagram 
459-                             control_point (xsi, xdi ,
460-                                           ysi, ydi ,
470+                             control_point (xsi, x[di] ,
471+                                           ysi, y[di] ,
461472                                          edge_has_been_seen[(si, di)]* curvature_scalar* sign (si -  di))
462473                        else 
463474                            (0.0 , 0.0 )
464475                        end 
465-                         push! (xseg, xsi, xpt, xdi, NaN )
466-                         push! (yseg, ysi, ypt, ydi, NaN )
467-                         _3d &&  push! (zseg, z[si], z[si], z[di], NaN )
468-                         push! (l_wg, wi)
476+                         xpts =  [xsi, xpt, xdi]
477+                         ypts =  [ysi, ypt, ydi]
478+                         t =  range (0 , stop= 1 , length= 3 )
479+                         A =  hcat (xpts, ypts)
480+ 
481+                         itp =  scale (interpolate (A, BSpline (Cubic (Natural (OnGrid ())))), t, 1 : 2 )
482+ 
483+                         tfine =  range (0 , 1 , length= 30 )
484+                         xpts, ypts =  [itp (t,1 ) for  t in  tfine], [itp (t,2 ) for  t in  tfine]
485+                         if  ! isnothing (edgelabel) &&  haskey (edgelabel, (si, di, edge_has_been_seen[(si, di)]))
486+                             q =  control_point (xsi, x[di],
487+                                               ysi, y[di],
488+                                               (edgelabel_offset
489+                                               +  edge_has_been_seen[(si, di)]* curvature_scalar)* sign (si -  di))
490+                             push! (edge_label_array,
491+                                   (q... ,
492+                                    string (edgelabel[(si, di, edge_has_been_seen[(si, di)])]), fontsize))
493+                             edge_label_box_vertices =  (
494+                             annotation_extent (plotattributes,
495+                                               (q[1 ], q[2 ],
496+                                               edgelabel[(si, di, edge_has_been_seen[(si, di)])],
497+                                               0.05 fontsize)))
498+                             if  ! any (isnan .(q))
499+                                 push! (edge_label_box_vertices_array, edge_label_box_vertices)
500+                             end 
501+                         end 
502+                         if  method !=  :chorddiagram  &&  ! _3d
503+                             append! (xseg, push! (xpts, NaN ))
504+                             append! (yseg, push! (ypts, NaN ))
505+                             push! (l_wg, wi)
506+                         else 
507+                             push! (xseg, xsi, xpt, xdi, NaN )
508+                             push! (yseg, ysi, ypt, ydi, NaN )
509+                             _3d &&  push! (zseg, z[si], z[si], z[di], NaN )
510+                             push! (l_wg, wi)
511+                         end 
469512                    end 
470513                else 
471514                    push! (xseg, xsi, xdi, NaN )
@@ -480,14 +523,25 @@ end
480523                nodewidth =  nodewidth_array[si]
481524                if  nodeshape ==  :circle 
482525                    xpts =  [xsi +  nodewidth* cos (θ1)/ 2 ,
483-                             xsi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* cos (θ1),
484-                             xsi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* cos (θ2),
526+                             NaN , NaN , NaN ,
485527                            xsi +  nodewidth* cos (θ2)/ 2 ]
528+                     xpts[2 ] =  mean ([xpts[1 ], xpts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* cos (θ1)
529+                     xpts[3 ] =  mean ([xpts[1 ], xpts[end ]]) +  edge_has_been_seen[(si, di)]* self_edge_size* cos ((θ1 +  θ2)/ 2 )
530+                     xpts[4 ] =  mean ([xpts[1 ], xpts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* cos (θ2)
486531                    ypts =  [ysi +  nodewidth* sin (θ1)/ 2 ,
487-                             ysi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* sin (θ1),
488-                             ysi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* sin (θ2),
532+                             NaN , NaN , NaN ,
489533                            ysi +  nodewidth* sin (θ2)/ 2 ]
534+                     ypts[2 ] =  mean ([ypts[1 ], ypts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* sin (θ1)
535+                     ypts[3 ] =  mean ([ypts[1 ], ypts[end ]]) +  edge_has_been_seen[(si, di)]* self_edge_size* sin ((θ1 +  θ2)/ 2 )
536+                     ypts[4 ] =  mean ([ypts[1 ], ypts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* sin (θ2)
537+ 
538+                     t =  range (0 , stop= 1 , length= 5 )
539+                     A =  hcat (xpts, ypts)
540+ 
541+                     itp =  scale (interpolate (A, BSpline (Cubic (Natural (OnGrid ())))), t, 1 : 2 )
490542
543+                     tfine =  range (0 , 1 , length= 50 )
544+                     xpts, ypts =  [itp (t,1 ) for  t in  tfine], [itp (t,2 ) for  t in  tfine]
491545                else 
492546                    _, _,
493547                    start_point1,
@@ -503,33 +557,59 @@ end
503557                                                      node_vec_vec_xy[si])
504558
505559                    xpts =  [start_point1,
506-                             xsi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* cos (θ1),
507-                             xsi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* cos (θ2),
560+                             NaN , NaN , NaN ,
508561                            end_point1]
562+                     xpts[2 ] =  mean ([xpts[1 ], xpts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* cos (θ1)
563+                     xpts[3 ] =  mean ([xpts[1 ], xpts[end ]]) +  edge_has_been_seen[(si, di)]* self_edge_size* cos ((θ1 +  θ2)/ 2 )
564+                     xpts[4 ] =  mean ([xpts[1 ], xpts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* cos (θ2)
509565                    ypts =  [start_point2,
510-                             ysi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* sin (θ1),
511-                             ysi +  edge_has_been_seen[(si, di)]* (nodewidth +  self_edge_size)* sin (θ2),
566+                             NaN , NaN , NaN ,
512567                            end_point2]
568+                     ypts[2 ] =  mean ([ypts[1 ], ypts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* sin (θ1)
569+                     ypts[3 ] =  mean ([ypts[1 ], ypts[end ]]) +  edge_has_been_seen[(si, di)]* self_edge_size* sin ((θ1 +  θ2)/ 2 )
570+                     ypts[4 ] =  mean ([ypts[1 ], ypts[end ]]) +  0.5 * (0.5  +  edge_has_been_seen[(si, di)])* self_edge_size* sin (θ2)
571+ 
572+                     t =  range (0 , stop= 1 , length= 5 )
573+                     A =  hcat (xpts, ypts)
574+ 
575+                     itp =  scale (interpolate (A, BSpline (Cubic (Natural (OnGrid ())))), t, 1 : 2 )
576+ 
577+                     tfine =  range (0 , 1 , length= 50 )
578+                     xpts, ypts =  [itp (t,1 ) for  t in  tfine], [itp (t,2 ) for  t in  tfine]
513579                end 
514580                append! (xseg, push! (xpts, NaN ))
515581                append! (yseg, push! (ypts, NaN ))
582+                 mid_ind =  div (length (xpts), 2 )
583+                 q =  [xpts[mid_ind] +  edgelabel_offset* cos ((θ1 +  θ2)/ 2 ),
584+                      ypts[mid_ind] +  edgelabel_offset* sin ((θ1 +  θ2)/ 2 )]
585+                 if  ! isnothing (edgelabel) &&  haskey (edgelabel, (si, di, edge_has_been_seen[(si, di)]))
586+                     push! (edge_label_array,
587+                           (q... ,
588+                            string (edgelabel[(si, di, edge_has_been_seen[(si, di)])]), fontsize))
589+                     edge_label_box_vertices =  annotation_extent (plotattributes, (q... ,
590+                                                                 edgelabel[(si, di, edge_has_been_seen[(si, di)])],
591+                                                                 0.05 fontsize))
592+                     if  ! any (isnan .(q))
593+                         push! (edge_label_box_vertices_array, edge_label_box_vertices)
594+                     end 
595+                 end 
516596            end 
517597
518598            if  isa (segment_colors, ColorGradient)
519599                line_z :=  segment_colors[i]
520600            end 
521601            linewidthattr =  get (plotattributes, :linewidth , 1 )
522-             seriestype :=  if  si  ==  di 
602+             seriestype :=  if  method  in  ( :tree ,  :buchheim ,  :chorddiagram ) 
523603                :curves 
524604            else 
525-                 if  curves
526-                     :curves 
527-                 else 
528-                     if  _3d
529-                         :path3d 
605+                 if  _3d
606+                     if  curves
607+                         :curves 
530608                    else 
531-                         :path  
609+                         :path3d  
532610                    end 
611+                 else 
612+                     :path 
533613                end 
534614            end 
535615            linewidth -->  linewidthattr *  edgewidth (si, di, wi)
@@ -542,24 +622,24 @@ end
542622
543623        end 
544624    end 
545- 
546-     for  (i, (si, di, wi)) in  enumerate (zip (source, destiny, weights))
547-         edge_has_been_seen[(si, di)] +=  1 
548-         xsi, ysi, xdi, ydi =  shorten_segment (x[si], y[si], x[di], y[di], shorten)
549-         if  ! isnothing (edgelabel) &&  haskey (edgelabel, (si, di))
550-             @assert  ! _3d  #  TODO : make this work in 3D
551-             q =  control_point (xsi, xdi, ysi, ydi,
552-                               (curvature_scalar +  edgelabel_offset)* sign (si -  di))
553-             push! (edge_label_array,
554-                   (q... , string (edgelabel[(si, di)]), fontsize))
555-             edge_label_box_vertices =  annotation_extent (plotattributes, (q[1 ], q[2 ],
556-                                                edgelabel[(si, di)], 0.05 fontsize))
557-             if  edge_label_box
625+     #  The boxes around edge labels are defined as another list of series that sits on top
626+     #  of the series for the edges.
627+     edge_has_been_seen =  Dict ()
628+     for  edge in  zip (source, destiny)
629+         edge_has_been_seen[edge] =  0 
630+     end 
631+     if  edge_label_box
632+         index =  0 
633+         for  (i, (si, di, wi)) in  enumerate (zip (source, destiny, weights))
634+             edge_has_been_seen[(si, di)] +=  1 
635+             if  ! isnothing (edgelabel) &&  haskey (edgelabel, (si, di, edge_has_been_seen[(si, di)]))
636+                 index +=  1 
558637                @series  begin 
559638                    seriestype :=  :shape 
560639                    fillcolor -->  get (plotattributes, :background_color , :white )
561640                    linewidth :=  0 
562641                    linealpha :=  0 
642+                     edge_label_box_vertices =  edge_label_box_vertices_array[index]
563643                    ([edge_label_box_vertices[1 ][1 ], edge_label_box_vertices[1 ][2 ],
564644                      edge_label_box_vertices[1 ][2 ], edge_label_box_vertices[1 ][1 ],
565645                      edge_label_box_vertices[1 ][1 ]],
0 commit comments