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