Skip to content

Commit 97d95d9

Browse files
committed
add docs for interface
1 parent deace72 commit 97d95d9

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

docs/make.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ makedocs(; modules=[NetworkLayout],
1111
sitename="NetworkLayout.jl",
1212
format=Documenter.HTML(; prettyurls=get(ENV, "CI", "false") == "true",
1313
canonical="https://juliagraphs.org/NetworkLayout.jl", assets=String[]),
14-
pages=["Home" => "index.md",])
14+
pages=["Home" => "index.md",
15+
"Interface" => "interface.md"])
1516

1617
# if gh_pages branch gets to big, check out
1718
# https://juliadocs.github.io/Documenter.jl/stable/man/hosting/#gh-pages-Branch

docs/src/interface.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
```@meta
2+
CurrentModule = NetworkLayout
3+
```
4+
5+
# Layout Interface
6+
7+
At its core, each layout algorithm is a mapping
8+
```
9+
adj_matrix ↦ node_positions
10+
```
11+
where each algorithm has several parameters. The main goal of the following interface is to keep the separation between parameters and function call.
12+
Each Algorithm is implemented as subtype of [`AbstractLayout`](@ref).
13+
14+
```@docs
15+
AbstractLayout
16+
```
17+
18+
Therefore, each `Algorithm <: AbstractLayout` is a functor and can be passed around as a function `adj_matrix ↦ node_positions` which encapsulates all the parameters. This is handy for plotting libraries such as [GraphMakie.jl](http://juliaplots.org/GraphMakie.jl/previews/PR9/).
19+
20+
There are some additional guidelines:
21+
- All of the parameters should be keyword arguments, i.e. it should be allways
22+
possible to call `Algorithm()` without specifying any parameters.
23+
- Algorithms should allways return `Vector{Point{dim,Ptype}}`. If the type or
24+
dimensions can be altered use the keywords `dim` and `Ptype` for it.
25+
- Some parameters may depend on the specific network (i.e. length of start
26+
positions vector). If possible, there should be a fallback option (i.e.
27+
truncate the list of start positions if network is to small or append with
28+
random values).
29+
30+
## Iterative Layouts
31+
Iterative layouts are a specific type of layouts which produce a sequence of positions rather than a single list of positions. Those algorithms are implemented as subtypes of [`IterativeLayout`](@ref):
32+
33+
```@docs
34+
IterativeLayout
35+
```
36+
37+
One can instantiate an iterable object [`LayoutIterator`](@ref)
38+
```@docs
39+
LayoutIterator
40+
```

src/NetworkLayout.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,62 @@ export LayoutIterator, layout
55
using GeometryBasics
66
using LinearAlgebra: norm
77

8+
"""
9+
abstract type AbstractLayout{Dim,Ptype} end
10+
11+
Supertype for all layouts. Each layout `Algorithm <: AbstractLayout` needs to
12+
implement
13+
14+
layout(algo::Algorithm, adj_matrix)::Vector{Point{Dim,Ptype}}
15+
16+
which takes the adjacency matrix representation of a network and returns a list of
17+
node positions. Each `Algorithm` object holds all of the necessary parameters.
18+
19+
By implementing `layout` the algorithm also inherits the function-like property
20+
21+
Algorithm(; kwargs...)(adj_matrix) -> node_positions
22+
"""
823
abstract type AbstractLayout{Dim,Ptype} end
924

1025
dim(::AbstractLayout{Dim,Ptype}) where {Dim,Ptype} = Dim
1126
ptype(::AbstractLayout{Dim,Ptype}) where {Dim,Ptype} = Ptype
1227

1328
(lay::AbstractLayout)(adj_matrix) = layout(lay, adj_matrix)
1429

30+
"""
31+
abstract type IterativeLayout{Dim,Ptype} <: AbstractLayout{Dim,Ptype} end
32+
33+
Supertype for iterative layouts. Instead of implementing `layout` directly,
34+
subtypes `Algorithm<:IterativeLayout` need to implement the [iterator
35+
interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration)
36+
37+
Base.iterate(iter::LayoutIterator{<:Algorithm})
38+
Base.iterate(iter::LayoutIterator{<:Algorithm}, state)
39+
40+
where the iteration _item_ is a `Vector{Point{Dim,Ptype}}` and the iteration
41+
_state_ depends on the algorithm.
42+
43+
By implementing the iterator interface the `Algorithm` inherits the `layout` and
44+
function-like call
45+
46+
layout(algo::Algorithm, adj_matrix) -> node_postions
47+
Algorithm(; kwargs...)(adj_matrix) -> node_positions
48+
"""
1549
abstract type IterativeLayout{Dim,Ptype} <: AbstractLayout{Dim,Ptype} end
1650

51+
"""
52+
LayoutIterator(algorithm::IterativeLayout, adj_matrix)
53+
54+
This type bundles an [`IterativeLayout`](@ref) with an adjacency matrix to form an
55+
iterable object whose items are the node positions.
56+
57+
## Example
58+
```
59+
for p in LayoutIterator(Stress(), adj_matrix)
60+
# do stuff with positions p
61+
end
62+
```
63+
"""
1764
struct LayoutIterator{T<:IterativeLayout,M<:AbstractMatrix}
1865
algorithm::T
1966
adj_matrix::M

0 commit comments

Comments
 (0)