diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b1fa01..52735ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Added +- more keywords take functions + ## Changed - Int64 -> Integer diff --git a/docs/src/basics.md b/docs/src/basics.md index 714eb0d..dc960e6 100644 --- a/docs/src/basics.md +++ b/docs/src/basics.md @@ -116,7 +116,7 @@ add_edge!(g, 1, 4) In Graphs.jl, vertices are always numbered from 1 to `n`. -`g` is now a `{{4, 1} undirected simple Int64 graph}`. +`g` is now a `{4, 4} undirected simple Int64 graph}`. It's time to see some kind of visual representation of the graph we've made. @@ -721,7 +721,7 @@ Graphs.jl has many features for traversing graphs and finding paths. We can look A **path** is a sequence of edges between some start vertex and some end vertex, such that a continuous unbroken route is available. -A **cycle** is a path where the start and end vertices are the same - a closed path. These are also called circuits in some sources. +A **cycle** is a path where the start and end vertices are the same - a closed path. Other vertices in the path occur just once. These are also called circuits in some sources. The `cycle_basis()` function finds all the cycles in a graph (at least, it finds a **basis** of an undirected graph, which is a minimal collection of cycles that can be added to make all the cycles). The result is an array of arrays of vertex numbers. diff --git a/docs/src/syntax.md b/docs/src/syntax.md index 929f4dc..41399b6 100644 --- a/docs/src/syntax.md +++ b/docs/src/syntax.md @@ -197,7 +197,11 @@ end ## The `vertexfunction` and `edgefunction` arguments -The two keyword arguments `vertexfunction` and `edgefunction` allow you to pass control over the drawing process completely to these two functions, ignoring all the other keywords. +The two keyword arguments `vertexfunction` and `edgefunction` allow you to pass control over the drawing process completely to these two functions. + +!!! note + + If you define these functions, all the separate vertex/edge keywords are ignored. ``` vertexfunction = my_vertexfunction(vertex, coordinates) @@ -239,6 +243,26 @@ end end 800 600 ``` +## Functions + +Some keywords accept functions: + +- `edgelabelrotations` +- `edgelabels` +- `edgelines` +- `edgestrokecolors` +- `edgestrokeweights` +- `vertexfillcolors` +- `vertexlabels` +- `vertexshaperotations` +- `vertexshapes` +- `vertexshapesizes` +- `vertexstrokecolors` +- `vertexstrokeweights` + +The `edge-` keywords accept functions with arguments `(edgenumber, sourcevertex, destinationvertex, frompoint, topoint)`. +The `vertex-` keywords accept functions with arguments `(vertex)`. + ## Vertex labels and shapes ### `vertexlabels` @@ -349,7 +373,7 @@ drawgraph(g, layout=shell, end 600 300 ``` -Here, the vertex number is shown by the number of points on each star. +Here, the vertex number is hinted at by the number of points on each star. In the next example, the sizes of the labels and shapes are determined by the degree of each vertex, supplied in a vector. diff --git a/src/drawgraph.jl b/src/drawgraph.jl index b6d5617..b5129c6 100644 --- a/src/drawgraph.jl +++ b/src/drawgraph.jl @@ -102,6 +102,8 @@ function _drawedgelines(from, to, edgesrc, edgedest; linewidth = edgestrokeweights[mod1(edgenumber, end)] elseif edgestrokeweights isa Real linewidth = edgestrokeweights + elseif edgestrokeweights isa Function + linewidth = edgestrokeweights(edgenumber, edgesrc, edgedest, from, to) elseif edgestrokeweights == :none # do nothing end @@ -376,6 +378,8 @@ function _drawvertexshapes(vertex, coordinates::Array{Point,1}; vertexshaperotation = vertexshaperotations[mod1(vertex, end)] elseif vertexshaperotations isa Real vertexshaperotation = vertexshaperotations + elseif vertexshaperotations isa Function + vertexshaperotation = vertexshaperotations elseif vertexshaperotations == :none # do nothing end @@ -484,6 +488,8 @@ function _drawvertexshapes(vertex, coordinates::Array{Point,1}; linewidth = vertexstrokeweights[mod1(vertex, end)] elseif vertexstrokeweights isa Real linewidth = vertexstrokeweights + elseif vertexstrokeweights isa Function + linewidth = vertexstrokeweights(vertex) elseif vertexstrokeweights == :none # do nothing end @@ -504,8 +510,10 @@ function _drawvertexshapes(vertex, coordinates::Array{Point,1}; vertexshapesize = vertexshapesizes[mod1(vertex, end)] elseif vertexshapesizes isa Real vertexshapesize = vertexshapesizes + elseif vertexshapesizes isa Function + vertexshapesize = vertexshapesizes elseif vertexshapesizes == :none - # don't draw it + vertexshapesize = 0.0 end # finally, do some drawing @@ -523,9 +531,20 @@ function _drawvertexshapes(vertex, coordinates::Array{Point,1}; end translate(coordinates[vertex]) - rotate(vertexshaperotation) + if vertexshaperotation isa Function + rotate(vertexshaperotation(vertex)) + else + rotate(vertexshaperotation) + end setline(linewidth) + if vertexshapesize isa Function + s = vertexshapesize(vertex) + elseif iszero(vertexshapesize) + s = 0.0 + else + s = vertexshapesize + end if vertexshape isa Function # TODO fill color or stroke color priority? @layer begin @@ -535,15 +554,15 @@ function _drawvertexshapes(vertex, coordinates::Array{Point,1}; end elseif vertexshape == :square fillcolor isa Colorant && setcolor(fillcolor) - box(O, 2vertexshapesize, 2vertexshapesize, :fill) + box(O, 2s, 2s, :fill) strokecolor isa Colorant && setcolor(strokecolor) - box(O, 2vertexshapesize, 2vertexshapesize, :stroke) + box(O, 2s, 2s, :stroke) else # default is a circle fillcolor isa Colorant && setcolor(fillcolor) - circle(O, vertexshapesize, :fill) + circle(O, s, :fill) strokecolor isa Colorant && setcolor(strokecolor) - circle(O, vertexshapesize, :stroke) + circle(O, s, :stroke) end end end @@ -798,21 +817,22 @@ Luxor `boundingbox`. ``` boundingbox::BoundingBox graph fits inside this BB layout Point[] or function -margin default 20 - -Functions that override all options: +margin default 30 +edgelist draw only these edges -vertexfunction(vtx, coords) -> _ -edgefunction(edgenumber, edgesrc, edgedest, from, to) -> _ +vertexfunction(vtx, coords) -> draw vertices +edgefunction(edgenumber, edgesrc, edgedest, from, to) -> draw edges +``` -Draw only edges in `edgelist`. +Or use these individual keywords: +``` • vertexlabels f • edgelabels f • vertexshapes f • edgelines f -• vertexshapesizes • edgelist -• vertexshaperotations • edgecurvature +• vertexshapesizes f • edgelist +• vertexshaperotations f • edgecurvature • vertexstrokecolors f • edgestrokecolors f -• vertexstrokeweights • edgestrokeweights +• vertexstrokeweights f • edgestrokeweights f • vertexfillcolors f • edgedashpatterns • vertexlabeltextcolors • edgegaps • vertexlabelfontsizes • edgelabelrotations f @@ -894,17 +914,17 @@ The text labels for each vertex. Vertex labels are not drawn by default. Use shape for vertex. If function, `vtx` is vertex number, using current vertex rotation (`vertextshaperotations`), make your own graphic shapes. The function can override rotations and colors. -`vertexshapesizes`: Array | Range | Real +`vertexshapesizes`: Array | Range | Real | Function The size of each vertex shape for :circle :square... -`vertexshaperotations`: Array | Range | Real +`vertexshaperotations`: Array | Range | Real | Function -Rotation of shape. +the rotation of shapes, `vertexstrokecolors`: Array | Colorant | :none | Function (vtx) -> colorant -`vertexstrokeweights`: Array | Range | :none +`vertexstrokeweights`: Array | Range | :none | Function `vertexfillcolors`: Array | Colorant | :none | Function (vtx) -> colorant @@ -938,7 +958,7 @@ Edge lines to be drawn. Colors of edges. Function can be `edgestrokecolors = (n, s, d, f, t) -> HSB(rescale(n, 1, ne(g), 0, 360), 0.9, 0.8))` -`edgestrokeweights` +`edgestrokeweights` Array | Range | Real | Function (n, s, d, from, to)` -> n `edgedashpatterns`: Array of Arrays | Array