Diagrama: A diagram drawing library
Digrama is a library for drawing diagrams on top of pict.
1 Diagrama API Reference
(require diagrama) | package: diagrama-lib |
Warning: The API presented here is unstable, and may change without warning.
Diagrams are pict-convertible?. When diagrams are drawn the whole image is shifted such that the minimum x and y coordinate are shifted to the origin. When diagrams are converted to pict?s the starting coordinates are always (0,0).
1.1 Basic diagram constructors
procedure
p : pict-convertible? align : (or/c 'lt 'ct 'rt 'lc 'cc 'rc 'lb 'cb 'rb) = 'cc
The fill-style is the same as the same argument from draw-path.
> (define unit-line-right (let () (define p (new dc-path%)) (send p move-to 0 0) (send p line-to 1 0) (path p))) > unit-line-right
> (after (move-to 3 0) unit-line-right)
> (after (units 36) (move-to 3 0) unit-line-right)
> (after (units 36) (move-to 3 0) (color "red") unit-line-right)
> (line-to 3 2)
procedure
d : real?
procedure
(line-right d) → diagram?
d : real?
procedure
d : real?
procedure
d : real?
> (line-right 5)
> (line-up 5)
> (after (move-to 3 3) (line-right 5))
procedure
d : real?
procedure
(move-right d) → diagram?
d : real?
procedure
d : real?
procedure
d : real?
procedure
(tag-location name [x y]) → diagram?
name : any/c x : real? = #f y : real? = #f
procedure
(move-to-tag name) → diagram?
name : any/c
procedure
(line-to-tag name [#:h-first h-fit]) → diagram?
name : any/c h-fit : any/c = #t
> (after (tag-location 'here 3 3) (move-to 0 0) (line-to-tag 'here))
procedure
(line-between start end [#:h-first h-fit]) → diagram
start : any/c end : any/c h-fit : any/c = #t
> (after (tag-location 'here 1 2) (tag-location 'there 4 0) (line-between 'here 'there))
> (define l (line-right 1)) > l
> (after (units 36) l)
> (after (units 36) (color "red") (line-right 2))
procedure
(line-width l) → diagram?
l : (real-in 0 255)
> (define l (line-right 3)) > l
> (after l unit-grid)
> (after l (units 24) unit-grid)
> (after (units 24) l unit-grid)
> (after (save l) (move-down 1) (save l) (move-down 1) (save l) unit-grid)
1.2 Diagram composition
> (after (line-up 3) (line-right 3) (line-down 3) (line-left 3))
> (after (img (disk 36 #:color "white")) (line-right 3))
> (before (img (disk 36 #:color "white")) (line-right 3))
procedure
(save/bounds d ...) → diagram?
d : diagram?
> (after (line-right 3) (split (after (line-up 3) (line-right 3)) (after (line-down 3) (line-right 3))) (line-down 3))
> (after (units 36) (<* (line-up 1) (line-down 1) (line-left 1) (line-right 1)) (line-right 1))
procedure
(start-at #:ud ud #:lr lr d ...) → diagram
ud : (or/c 'up 'down) lr : (or/c 'left 'right) d : diagram?
syntax
(for/after (for-clauses ...) body-or-break ... body)
syntax
(for*/after (for-clauses ...) body-or-break ... body)
syntax
(for/*> (for-clauses ...) body-or-break ... body)
syntax
(for*/*> (for-clauses ...) body-or-break ... body)
syntax
(for/<* (for-clauses ...) body-or-break ... body)
syntax
(for*/<* (for-clauses ...) body-or-break ... body)
1.3 Reflecting on the drawing state
There are several ways to directly inspect the current drawing state. These are all fairly low level operations that are most likely useful for making new combinators, or when making pict?’s that scale to the current unit size (for example unit-grid and start-at are defined with these).
procedure
(with-line-width builder) → diagram?
builder : (-> (real-in 0 255) diagram?)
> (define unit-circle (with-unit (compose img circle))) > unit-circle
> (after (units 24) unit-circle)
> (scale (after (units 24) (for*/fold ([p nothing]) ([x (in-range 3)] [y (in-range 3)]) (after p (move-to x y) unit-circle)) unit-grid) 2)
1.4 Circuit Helpers
(require diagrama/circuit) | package: diagrama-lib |
diagrama/circuit has helpers for drawing circuit diagrams. Note that it is easy to accidentally draw lines on top of gates: before is designed to help with this.
procedure
(or-gate [ #:in1 n1 #:in2 n2 #:in3 n3 #:out out #:tag-in1 tag1 #:tag-in2 tag2 #:tag-in3 tag3 #:tag-out tag4]) → diagram? n1 : any/c = #f n2 : any/c = #f n3 : any/c = #f out : any/c = #f tag1 : any/c = #f tag2 : any/c = #f tag3 : any/c = #f tag4 : any/c = #f
procedure
(and-gate [ #:in1 n1 #:in2 n2 #:in3 n3 #:out out #:tag-in1 tag1 #:tag-in2 tag2 #:tag-in3 tag3 #:tag-out tag4]) → diagram? n1 : any/c = #f n2 : any/c = #f n3 : any/c = #f out : any/c = #f tag1 : any/c = #f tag2 : any/c = #f tag3 : any/c = #f tag4 : any/c = #f
procedure
(buffer [ #:in2 n2 #:out out #:tag-in2 tag2 #:tag-out tag4]) → diagram? n2 : any/c = #f out : any/c = #f tag2 : any/c = #f tag4 : any/c = #f
procedure
(register [ #:in2 n2 #:out out #:tag-in2 tag2 #:tag-out tag4]) → diagram? n2 : any/c = #f out : any/c = #f tag2 : any/c = #f tag4 : any/c = #f
The drawn gate is centered at the current location.
> (define layer-1-x 6) > (define layer-2-x 3) > (define input-1 (tag-location 'input-1 0 0)) > (define input-2 (tag-location 'input-2 0 2))
> (define top-gate (after (move-down 1) (move-right layer-1-x) (and-gate #:out #t #:tag-out 'and-out #:tag-in1 'and-A #:tag-in3 'and-B)))
> (define lower-gate (after (move-down 5) (move-right layer-1-x) (or-gate #:tag-out 'or-out #:tag-in1 'or-A #:tag-in3 'or-B)))
> (define last-gate (after (move-down 1) (move-right layer-2-x) (and-gate #:tag-in1 'and-in #:tag-in3 'or-in #:tag-out 'result)))
> (define (connect-input input g1 g2 split-point) (after (move-to-tag input) (line-right split-point) (split (line-to-tag g1) (line-to-tag g2 #:h-first #f))))
> (define xor (after input-1 input-2 (move-to-tag 'input-1) (save top-gate) (save lower-gate) (move-to-tag 'and-out) last-gate (connect-input 'input-1 'and-A 'or-A 3) (connect-input 'input-2 'and-B 'or-B 2) (line-between 'and-out 'and-in) (line-between 'or-out 'or-in) (move-to-tag 'result) (line-right 1))) > (scale xor 2)
> (scale (after xor unit-grid) 2)