diff --git a/CHANGELOG.md b/CHANGELOG.md index 9338991..1efcc12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ # Changelog -## current master +## [v1.1.0] current master ### Added +- edgegap can be function + ## Changed ### Removed diff --git a/Project.toml b/Project.toml index 270c576..b11d25b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Karnak" uuid = "cd156443-31ad-4f6f-850f-a93ee5f75905" authors = ["cormullion and contributors"] -version = "1.0.0" +version = "1.1.0" [deps] Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" diff --git a/docs/src/assets/figures/edgegapanimation.gif b/docs/src/assets/figures/edgegapanimation.gif new file mode 100644 index 0000000..8818d5a Binary files /dev/null and b/docs/src/assets/figures/edgegapanimation.gif differ diff --git a/docs/src/syntax.md b/docs/src/syntax.md index 5a8a072..d72feb7 100644 --- a/docs/src/syntax.md +++ b/docs/src/syntax.md @@ -949,9 +949,13 @@ This example draws the graph more than once; once with all the edges, once with end 600 600 ``` -### `edgecurvature` and `edgecaps` +### `edgecurvature` and `edgegaps` -`edgecurvature` determines the curvature of the edges, and `edgegaps` sets the distance between the tip of the arrowhead and the vertex position. Units, as everywhere in Karnak, are points/pixels (1 point is 0.3527mm). +The `edgecurvature` keyword determines the curvature of the edges. + +The `edgegaps` keyword sets the distances between the ends of the edges and the vertex positions. + +Units, as everywhere in Karnak, are points/pixels (1 point is 0.3527mm). ```@example graphsection g = grid((3, 3)) @@ -978,6 +982,49 @@ end end 600 500 ``` +The value for the edge gap (either as supplied in vector, range, or scalar form, or calculated and returned by a function) applies to both ends of an edge. This is a minor issue for cases where, for example, the vertex shapes are different sizes, and the gaps need to be calculated independently for each end of a single edge. You'll have to calculate and draw the edges yourself, as shown in this unnecessarily animated example: + +```julia +using Karnak, Graphs, Colors +function frame(scene, framenumber, g, vertexsizes) + background("black") + eased_n = scene.easingfunction(framenumber - scene.framerange.start, + 0, 1, (scene.framerange.stop + 1) - scene.framerange.start) + a = 10 + vertexsizes[1] * abs(sin(0 + rescale(eased_n, 0, 1, 0, π))) + b = 10 + vertexsizes[2] * abs(sin(π / 4 + rescale(eased_n, 0, 1, 0, π))) + c = 10 + vertexsizes[3] * abs(sin(π / 3 + rescale(eased_n, 0, 1, 0, π))) + d = 10 + vertexsizes[4] * abs(sin(rescale(eased_n, 0, 1, 0, π))) + newvertexsizes = [a, b, c, d] + sethue("gold") + drawgraph(g, + margin=80, + vertexshapesizes=newvertexsizes, + vertexfillcolors=[c for c in Colors.JULIA_LOGO_COLORS |> values], + edgefunction=(args...) -> begin + edgenumber, edgesrc, edgedest, from, to = args + d = distance(from, to) + startpoint = between(from, to, newvertexsizes[edgesrc] / d) + endpoint = between(from, to, 1 - newvertexsizes[edgedest] / d) + arrow(startpoint, endpoint) + end) +end + +function main() + g = complete_digraph(4) + vertexsizes = [20, 35, 50, 60] + amovie = Movie(800, 600, "gap animation") + animate(amovie, + Scene(amovie, (s, f) -> frame(s, f, g, vertexsizes), 1:40), + framerate=15, + creategif=true, + pathname=joinpath(dirname(dirname(pathof(Karnak))) * "/docs/src/assets/figures/edgegapanimation.gif")) +end + +main() +``` + +![edge gap animation](assets/figures/edgegapanimation.gif) + ### `edgestrokecolors` and `edgestrokeweights` ```@example graphsection diff --git a/src/drawgraph.jl b/src/drawgraph.jl index 04d94d7..3625c65 100644 --- a/src/drawgraph.jl +++ b/src/drawgraph.jl @@ -132,6 +132,8 @@ function _drawedgelines(from, to, edgesrc, edgedest; edgegap = edgegaps[mod1(edgenumber, end)] elseif edgegaps isa AbstractRange edgegap = edgegaps[mod1(edgenumber, end)] + elseif edgegaps isa Function + edgegap = edgegaps(edgenumber, edgesrc, edgedest, from, to) elseif edgegaps isa Real edgegap = edgegaps end @@ -911,14 +913,15 @@ All keywords: layout Vector{Point} function from NetworkLayout.jl f(g::Graph) - edgefunction f(edgenumber::Int, edgesrc::Int, edgedest::Int, from::Poi + edgefunction f(edgenumber::Int, edgesrc::Int, edgedest::Int, from::Point) vertexfunction f(vtx::Int, coordinates::Vector{Point}) edgecurvature Float64 edgedashpatterns Vector{Vector}[number] Vector{Number} edgegaps Vector Range - Real + Real + f(edgenumber::Int, edgesrc::Int, edgedest::Int, from::Point) edgelabelcolors Vector{Colorant} Colorant edgelabelfontfaces Vector{Strings}[edgenumber] @@ -933,7 +936,7 @@ All keywords: range Dict{Int, Int} f(edgenumber, edgesrc, edgedest, from::Point, to::Point) - - this function should draw the required text + - this function must draw the required text :none edgelines Vector{Int} range @@ -958,7 +961,7 @@ All keywords: Real :none f(vtx::Int, coord::Point[]) - function should return a numeric value for fontsize + - function must return a numeric value for fontsize vertexlabeloffsetangles Vector Range Real @@ -974,7 +977,7 @@ All keywords: range[vtx::Int] :none f(vtx::Int) - this function should return a string + - this function must return a string vertexlabeltextcolors Vector{Colorant} Colorant f(vtx::Int)