diff --git a/src/lines.jl b/src/lines.jl index 13c29fb..157328f 100644 --- a/src/lines.jl +++ b/src/lines.jl @@ -7,6 +7,22 @@ function midpoint(pt1,pt2) return x,y end +function interpolate_bezier(x::Vector,t) + n = length(x)-1 + x_loc = sum(binomial(n,i)*(1-t)^(n-i)*t^i*x[i+1][1] for i in 0:n) + y_loc = sum(binomial(n,i)*(1-t)^(n-i)*t^i*x[i+1][2] for i in 0:n) + return x_loc.value, y_loc.value +end + +interpolate_bezier(x::Compose.CurvePrimitive,t) = + interpolate_bezier([x.anchor0, x.ctrl0, x.ctrl1, x.anchor1], t) + +function interpolate_line(locs_x,locs_y,i,j,t) + x_loc = locs_x[i] + (locs_x[j]-locs_x[i])*t + y_loc = locs_y[i] + (locs_y[j]-locs_y[i])*t + return x_loc, y_loc +end + function graphline(edge_list, locs_x, locs_y, nodesize::Vector{T}, arrowlength, angleoffset) where {T<:Real} num_edges = length(edge_list) lines = Array{Vector{Tuple{Float64,Float64}}}(undef, num_edges) diff --git a/src/plot.jl b/src/plot.jl index 5349993..d29b30a 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -223,22 +223,6 @@ function gplot(g::AbstractGraph{T}, text_locs_y .- nodesize .* (nodelabeldist * sin(nodelabelangleoffset)), map(string, nodelabel), [hcenter], [vcenter]) end - # Create edge labels if provided - edgetexts = nothing - if !isempty(edgelabel) - edge_locs_x = zeros(R1, NE) - edge_locs_y = zeros(R2, NE) - for (e_idx, e) in enumerate(edges(g)) - i = src(e) - j = dst(e) - mid_x = (locs_x[i]+locs_x[j]) / 2.0 - mid_y = (locs_y[i]+locs_y[j]) / 2.0 - edge_locs_x[e_idx] = (is_directed(g) ? (mid_x+locs_x[j]) / 2.0 : mid_x) + edgelabeldistx * NODESIZE - edge_locs_y[e_idx] = (is_directed(g) ? (mid_y+locs_y[j]) / 2.0 : mid_y) + edgelabeldisty * NODESIZE - - end - edgetexts = text(edge_locs_x, edge_locs_y, map(string, edgelabel), [hcenter], [vcenter]) - end # Create lines and arrow heads lines, larrows = nothing, nothing @@ -251,6 +235,28 @@ function gplot(g::AbstractGraph{T}, lines, larrows = build_straight_edges(edges(g), locs_x, locs_y, nodesize, arrowlengthfrac, arrowangleoffset) end + # Create edge labels if provided + edgetexts = nothing + if !isempty(edgelabel) + edge_locs_x = zeros(R1, NE) + edge_locs_y = zeros(R2, NE) + self_loop_idx = 1 + for (e_idx, e) in enumerate(edges(g)) + i, j = src(e), dst(e) + if linetype == "curve" + mid_x, mid_y = interpolate_bezier(curves.primitives[e_idx], 0.5) + elseif src(e) == dst(e) + mid_x, mid_y = interpolate_bezier(curves.primitives[self_loop_idx], 0.5) + self_loop_idx += 1 + else + mid_x, mid_y = interpolate_line(locs_x,locs_y,i,j,0.5) + end + edge_locs_x[e_idx] = mid_x + edgelabeldistx * NODESIZE + edge_locs_y[e_idx] = mid_y + edgelabeldisty * NODESIZE + end + edgetexts = text(edge_locs_x, edge_locs_y, map(string, edgelabel), [hcenter], [vcenter]) + end + # Set plot_size if length(plot_size) != 2 || !isa(plot_size[1], Compose.AbsoluteLength) || !isa(plot_size[2], Compose.AbsoluteLength) error("`plot_size` must be a Tuple of lengths")