Skip to content

Commit

Permalink
release 0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
cormullion committed Dec 25, 2022
1 parent f0edb16 commit 785a20a
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 123 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/Manifest.toml
docs/build/*
.DS_Store
*.pages
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Changelog

## [v0.4.0] - 2022-06-??
## [v0.4.0] - 2022-12-25

### Added

## Changed

- font choice better

### Removed

### Deprecated
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Colors = "0.12"
Graphs = "1"
Luxor = "3"
NetworkLayout = "0.4.4"
Reexport = "0.2, 1.0"
Reexport = "0.2, 1.0, 1.1, 1.2"
SimpleWeightedGraphs = "1"
julia = "1.5"

Expand Down
1 change: 1 addition & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ Graphs = "1.6"
julia = "^1.5"
Luxor = "3"
NetworkLayout = "0.4.4"
SimpleWeightedGraphs = "1.2"
56 changes: 54 additions & 2 deletions docs/src/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ familiar with the basics of programming in Julia.
pages are built by Documenter.jl, and the code to draw
them is included here. SVG is used because it's good for
line drawings, but you can use Karnak.jl in any
Luxor environment, such as PNG - which is the
Luxor environment, such as PNG - which is the
recommended format to use if the drawings get very
complex, since large SVGs can tax web browsers.

Expand Down Expand Up @@ -824,7 +824,7 @@ It's useful to know how to visit all vertices just once.

You can do this for DiGraphs if you can find a cycle that's the same length as the graph. However, there might be a lot of possibilities, since there could be many such cycles. This example uses `simplecycles()` to find all of them (there are over 400 for this graph), so only the first one with the right length is used.

``` @example graphsection
```@example graphsection
@drawsvg begin
background("grey10")
g = complete_digraph(6)
Expand All @@ -845,6 +845,58 @@ drawgraph(g, layout = spring,
end 800 400
```

## Trees

A tree is a connected graph with no cycles. A *rooted tree* is a tree graph in which one vertex has been designated as the root, or origin. Rooted tree graphs can be drawn using the Buchheim layout algorithm (named after the developer, Christoph Buchheim).

In the next example, we start with a *binary tree*, in which each vertex has at most two vertices - but we add one more vertex so that it's no longer a binary tree.

```@raw html
<details closed><summary>Code for this figure</summary>
```

This code generates the figure below.

```@example graphsection
using Karnak, Luxor, Graphs, NetworkLayout, Colors
d = @drawsvg begin
background("grey10")
sethue("purple")
fontsize(12)
bt = binary_tree(4)
g = SimpleDiGraph(collect(edges(bt)))
# add another vertex
add_vertex!(g)
add_edge!(g, 7, 16)
drawgraph(g,
layout=buchheim,
margin=20,
edgestrokeweights=2,
edgegaps=12,
vertexlabels = 1:nv(g),
vertexshapes=:circle,
vertexfillcolors=[RGB(Luxor.julia_red...),
RGB(Luxor.julia_purple...),
RGB(Luxor.julia_green...),
RGB(Luxor.julia_blue...)],
vertexshapesizes=12,
vertexlabeltextcolors=colorant"white",
)
end 600 350
```

```@raw html
</details>
```

```@example graphsection
d # hide
```

## Shortest paths: the A* algorithm

One way to find the shortest path between two vertices is to use the `a_star()` function, and provide the graph, the start vertex, and the end vertex. The function returns a list of edges.
Expand Down
129 changes: 128 additions & 1 deletion docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,134 @@ find(x::Int64) = stations[x]

# Examples

This section contains a few examples showing how to use `drawgraph()` to visualize a few graphs.
This chapter contains a few examples showing how to use `drawgraph()` to visualize a few graphs.

## Julia source tree

This example takes a Julia expression and displays it as a tree.

```@example
using Karnak, Graphs, NetworkLayout, Colors
# shamelessly stolen from Professor David Sanders' Tree !
add_numbered_vertex!(g) = (add_vertex!(g); top = nv(g))
function walk_tree!(g, labels, ex, show_call = true)
top_vertex = add_numbered_vertex!(g)
where_start = 1 # which argument to start with
if !(show_call) && ex.head == :call
f = ex.args[1] # the function name
push!(labels, f)
where_start = 2 # drop "call" from tree
else
push!(labels, ex.head)
end
for i in where_start:length(ex.args)
if isa(ex.args[i], Expr)
child = walk_tree!(g, labels, ex.args[i], show_call)
add_edge!(g, top_vertex, child)
else
n = add_numbered_vertex!(g)
add_edge!(g, top_vertex, n)
push!(labels, ex.args[i])
end
end
return top_vertex
end
function walk_tree(ex::Expr, show_call = false)
g = DiGraph()
labels = Any[]
walk_tree!(g, labels, ex, show_call)
return (g, labels)
end
# build graph and labels
expression = :(2 + sin(30) * cos(15) / 2π - log(-1.02^exp(-1)))
g, labels = walk_tree(expression)
@drawsvg begin
background("grey10")
sethue("gold")
fontface("JuliaMono-Black")
drawgraph(g,
margin=60,
layout = buchheim,
vertexlabels = labels,
vertexshapes = :circle,
vertexshapesizes = 20,
edgefunction = (n, s, d, f, t) -> begin
move(f)
line(t)
strokepath()
end,
vertexlabelfontsizes = 15,
vertexlabelfontfaces = "JuliaMono-Bold",
vertexlabeltextcolors = colorant"black")
fontsize(15)
text(string(expression), boxbottomcenter() + (0, -20), halign=:center)
end
```

## Julia type tree

This example tries to draw a type hierarchy diagram. The Buchheim layout algorithm can take a list of “vertex widths” that are normalized and then used to assign sufficient space for each label.

```@example
using Karnak, Graphs, NetworkLayout, InteractiveUtils
add_numbered_vertex!(g) = add_vertex!(g)
function build_type_tree(g, T, level=0)
add_numbered_vertex!(g)
push!(labels, T)
for t in subtypes(T)
build_type_tree(g, t, level + 1)
add_edge!(g,
findfirst(isequal(T), labels),
findfirst(isequal(t), labels))
end
end
function manhattanline(pt1, pt2)
mp = midpoint(pt1, pt2)
poly([pt1,
Point(pt1.x, mp.y),
Point(pt1.x, mp.y),
Point(pt2.x, mp.y),
Point(pt2.x, mp.y),
Point(pt2.x, pt2.y - get_fontsize())
], :stroke)
end
g = DiGraph()
labels = []
build_type_tree(g, Real)
labels = map(string, labels)
@drawsvg begin
background("white")
sethue("black")
fontsize(9)
# adjust for centered labels
nodesizes = Float64[]
for l in eachindex(labels)
push!(nodesizes, textextents(string(labels[l]))[3] +
textextents(string(labels[mod1(l + 1, end)]))[3])
end
drawgraph(g, margin=50,
layout=Buchheim(nodesize=nodesizes),
vertexfunction=(v, c) -> text(labels[v], c[v], halign=:center),
edgefunction=(n, s, d, f, t) -> manhattanline(f, t)
)
end 1200 550
```

It can be quite difficult to get the final output to look perfect.

## The London Tube

Expand Down
61 changes: 0 additions & 61 deletions examples/trees.jl

This file was deleted.

52 changes: 0 additions & 52 deletions examples/typetree.jl

This file was deleted.

Loading

0 comments on commit 785a20a

Please sign in to comment.