Skip to content

Commit

Permalink
Merge pull request #161 from epatters/box-shapes
Browse files Browse the repository at this point in the history
Customize shapes and styles of boxes in Compose/TikZ wiring diagrams
  • Loading branch information
epatters authored May 9, 2020
2 parents 7656a4c + 5d1e62d commit 6f72b9d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 22 deletions.
2 changes: 1 addition & 1 deletion docs/literate/graphics/composejl_wiring_diagrams.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ to_composejl(f⋅g, background_color="lightgray", props=Dict(
# By default, the boxes are rectangular (`:rectangle`). Other available shapes
# include circles (`:circle`) and ellipses (`:ellipse`).

to_composejl(fg, box_shape=:circle)
to_composejl(fg, default_box_shape=:circle)

# ## Output formats

Expand Down
18 changes: 10 additions & 8 deletions docs/literate/graphics/tikz_wiring_diagrams.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,19 @@ to_tikz(plus(X) ⋅ mcopy(X), styles=Dict(
# include circles (`:circle`), ellipses (`:ellipse`), triangles (`:triangle`,
# `:invtriangle`), and trapezoids (`:trapezium`, `:invtrapezium`).

to_tikz(fg, box_shape=:circle)
to_tikz(fg, default_box_shape=:circle)
#-
to_tikz(fg, box_shape=:triangle, rounded_boxes=false)
#-
to_tikz(fg, box_shape=:invtriangle, rounded_boxes=false)
#-
to_tikz(fg, box_shape=:invtriangle, orientation=TopToBottom, rounded_boxes=false)
to_tikz(fg, rounded_boxes=false, box_shapes=Dict(
f => :triangle, g => :invtriangle,
))
#-
to_tikz(fg, box_shape=:trapezium)
to_tikz(fg, orientation=TopToBottom, rounded_boxes=false, box_shapes=Dict(
f => :triangle, g => :invtriangle,
))
#-
to_tikz(fg, box_shape=:invtrapezium)
to_tikz(fg, box_shapes=Dict(
f => :invtrapezium, g => :trapezium,
))

# ## Output formats

Expand Down
4 changes: 2 additions & 2 deletions src/graphics/TikZWiringDiagrams.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ import ..TikZ
orientation::LayoutOrientation = LeftToRight
base_unit::String = "4mm"
labels::Bool = false
labels_pos::Union{String,Float64} = 0.5
labels_pos::Union{String,Real} = 0.5
math_mode::Bool = true
arrowtip::Union{String,Nothing} = nothing
arrowtip_pos::Union{String,Float64} = 0.5
arrowtip_pos::Union{String,Real} = 0.5
rounded_boxes::Bool = true
props::AbstractVector = ["semithick"]
styles::AbstractDict = Dict()
Expand Down
31 changes: 20 additions & 11 deletions src/graphics/WiringDiagramLayouts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@ svector(orient::LayoutOrientation, first, second) =
"""
@with_kw_noshow struct LayoutOptions
orientation::LayoutOrientation = LeftToRight
box_shape::Symbol = :rectangle
default_box_shape::Symbol = :rectangle
box_shapes::AbstractDict = Dict()
box_styles::AbstractDict = Dict()
outer_ports_layout::Symbol = :isotonic
anchor_wires::Union{Bool,AbstractSet,AbstractVector} = [:id,:braid]
base_box_size::Float64 = 2
sequence_pad::Float64 = 2
parallel_pad::Float64 = 1
junction_size::Float64 = 0.25
base_box_size::Real = 2
box_stretch::Real = 1
sequence_pad::Real = 2
parallel_pad::Real = 1
junction_size::Real = 0.25
end

svector(opts::LayoutOptions, args...) = svector(opts.orientation, args...)
Expand Down Expand Up @@ -312,7 +315,7 @@ end
""" Compute the minimum size of a wiring diagram from the number of its ports.
"""
function minimum_diagram_size(nin::Int, nout::Int, opts::LayoutOptions)
default_box_size(nin, nout, opts, length=0) + 2*diagram_padding(opts)
default_box_size(nin, nout, opts, stretch=0) + 2*diagram_padding(opts)
end
function diagram_padding(opts::LayoutOptions)
svector(opts, opts.sequence_pad, opts.parallel_pad)
Expand All @@ -326,9 +329,13 @@ end
By default the box is rectangular, but other shapes are also supported.
"""
function layout_box(inputs::Vector, outputs::Vector, opts::LayoutOptions;
shape::Union{Symbol,Nothing}=nothing, kw...)
layout_box(Val(isnothing(shape) ? opts.box_shape : shape),
inputs, outputs, opts; kw...)
shape::Union{Symbol,Nothing}=nothing,
style::Union{Symbol,Nothing}=nothing, value=nothing, kw...)
shape = get(opts.box_shapes, value) do
isnothing(shape) ? opts.default_box_shape : shape
end
style = get(opts.box_styles, value, style)
layout_box(Val(shape), inputs, outputs, opts; style=style, value=value, kw...)
end

function layout_box(::Val{:rectangle}, inputs::Vector, outputs::Vector,
Expand Down Expand Up @@ -401,10 +408,12 @@ We use the unique formula consistent with the padding for monoidal products,
ensuring that the size of a product of boxes depends only on the total number of
ports, not on the number of boxes.
"""
function default_box_size(nin::Int, nout::Int, opts::LayoutOptions; length=1)
function default_box_size(nin::Int, nout::Int, opts::LayoutOptions;
stretch::Union{Real,Nothing}=nothing)
base_size = opts.base_box_size
stretch = isnothing(stretch) ? opts.box_stretch : stretch
n = max(1, nin, nout)
svector(opts, length*base_size, n*base_size + (n-1)*opts.parallel_pad)
svector(opts, stretch*base_size, n*base_size + (n-1)*opts.parallel_pad)
end

# Port layout
Expand Down

0 comments on commit 6f72b9d

Please sign in to comment.