design

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2020 License: MIT Imports: 9 Imported by: 0

README

design - package for writing software design diagrams

Sequence diagram

var (
    d   = design.NewSequenceDiagram()
    cli = d.AddStruct(app.Client{})
    srv = d.AddStruct(app.Server{})
    db  = d.AddStruct(sql.DB{})
)
d.Link(cli, srv, "connect()")
d.Link(srv, db, "SELECT").Class = "highlight"
d.Link(db, srv, "Rows")
d.Link(srv, srv, "Transform to view model").Class = "highlight"
d.Link(srv, cli, "Send HTML")

Activity diagram

Rendered by ExampleActivityDiagram

Class diagram

Class diagrams show relations between structs and interfaces. Reflection includes fields and methods.

This diagram is rendered by ExampleClassDiagram

Generic diagram

It should be easy to just add any extra shapes to any diagram when explaining a design. This diagram is rendered by ExampleDiagram

Grid layout

Simplifying placing shapes in a grid layout aligning different sizes of shapes.

Gantt chart

ExampleGanttChart

Showcase

You can find more examples in the showcase folder.

Documentation

Overview

Package design provides svg diagram creators

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActivityDiagram

type ActivityDiagram struct {
	Diagram

	Spacing int
	// contains filtered or unexported fields
}
Example
package main

import (
	"github.com/gregoryv/draw/shape"
	"github.com/gregoryv/draw/shape/design"
)

func main() {
	var (
		d = design.NewActivityDiagram()
	)
	d.Start().At(80, 20)
	d.Then("Push commit")
	d.Then("Run git hook")
	dec := d.Decide()
	d.Then("Deploy", "ok")
	d.Exit()
	d.If(dec, "Tests failed", shape.NewExitDot())
	// manual part
	var (
		start = shape.NewDot()
		push  = shape.NewState("Push tag")
		hook  = shape.NewState("Run git hook")
		exit  = shape.NewExitDot()
	)
	d.Place(start).At(180, 20)
	d.Place(push).RightOf(start)
	d.Place(hook, exit).Below(push)
	d.HAlignCenter(start, push)
	d.VAlignCenter(push, hook, exit)
	d.LinkAll(start, push, hook, exit)
	d.SaveAs("img/activity_diagram.svg")
}

func NewActivityDiagram

func NewActivityDiagram() *ActivityDiagram

func (*ActivityDiagram) Decide added in v0.9.0

func (d *ActivityDiagram) Decide() *shape.Diamond

Decide adds a diamond below the last activity

func (*ActivityDiagram) Exit added in v0.9.0

func (d *ActivityDiagram) Exit(txt ...string) *shape.ExitDot

Exit adds an ExitDot below the last activity

func (*ActivityDiagram) If added in v0.9.0

func (d *ActivityDiagram) If(after shape.Shape, txt string, next shape.Shape) *shape.Adjuster

If adds next state to the right with a label.

func (d *ActivityDiagram) Link(from, to shape.Shape, txt ...string) *shape.Arrow

Link places an arrow with a optional label above it between the two shapes.

func (*ActivityDiagram) LinkAll added in v0.8.0

func (d *ActivityDiagram) LinkAll(s ...shape.Shape)

LinkAll places arrows between each shape, s0->s1->...->sn

func (*ActivityDiagram) Place added in v0.9.0

func (d *ActivityDiagram) Place(next ...shape.Shape) *shape.Adjuster

func (*ActivityDiagram) Start added in v0.9.0

func (d *ActivityDiagram) Start() *shape.Adjuster

func (*ActivityDiagram) Then added in v0.9.0

func (d *ActivityDiagram) Then(label string, txt ...string) *shape.Adjuster

type ClassDiagram

type ClassDiagram struct {
	Diagram
	// contains filtered or unexported fields
}
Example
package main

import (
	"github.com/gregoryv/draw/shape"
	"github.com/gregoryv/draw/shape/design"
)

func main() {
	var (
		d        = design.NewClassDiagram()
		record   = d.Struct(shape.Record{})
		arrow    = d.Struct(shape.Arrow{})
		line     = d.Struct(shape.Line{})
		circle   = d.Struct(shape.Circle{})
		diaarrow = d.Struct(shape.Diamond{})
		triangle = d.Struct(shape.Triangle{})
		shapE    = d.Interface((*shape.Shape)(nil))
	)
	d.HideRealizations()

	var (
		fnt      = d.Struct(shape.Font{})
		style    = d.Struct(shape.Style{})
		seqdia   = d.Struct(design.SequenceDiagram{})
		classdia = d.Struct(design.ClassDiagram{})
		dia      = d.Struct(design.Diagram{})
		aligner  = d.Struct(shape.Aligner{})
		adj      = d.Struct(shape.Adjuster{})
		rel      = d.Struct(design.Relation{})
	)
	d.HideRealizations()

	d.Place(shapE).At(220, 20)
	d.Place(record).At(20, 120)
	d.Place(line).Below(shapE, 90)
	d.VAlignCenter(shapE, line)

	d.Place(arrow).RightOf(line, 90)
	d.Place(circle).RightOf(shapE, 280)
	d.Place(diaarrow).Below(circle)
	d.Place(triangle).Below(diaarrow)
	d.HAlignBottom(record, arrow, line)

	d.Place(fnt).Below(record, 170)
	d.Place(style).RightOf(fnt, 90)
	d.VAlignCenter(shapE, line, style)
	d.VAlignCenter(record, fnt)

	d.Place(rel).Below(line, 80)
	d.Place(dia).RightOf(style, 90)
	d.Place(aligner).RightOf(dia, 80)
	d.HAlignCenter(fnt, style, dia, aligner)

	d.Place(adj).Below(fnt, 70)
	d.Place(seqdia).Below(aligner, 90)
	d.Place(classdia).Below(dia, 90)
	d.VAlignCenter(dia, classdia)
	d.HAlignBottom(classdia, seqdia)

	d.SetCaption("Figure 1. Class diagram of design and design.shape packages")
	d.SaveAs("img/class_example.svg")
}

func NewClassDiagram

func NewClassDiagram() *ClassDiagram

NewClassDiagram returns a diagram representing structs and interfaces. Relations are reflected from the types and drawn as arrows.

func (*ClassDiagram) HideRealizations

func (d *ClassDiagram) HideRealizations()

HideRealizations hides all methods of structs that implement a visible interface.

func (*ClassDiagram) Interface

func (d *ClassDiagram) Interface(obj interface{}) VRecord

func (*ClassDiagram) SaveAs

func (d *ClassDiagram) SaveAs(filename string) error

SaveAs saves the diagram to filename as SVG

func (*ClassDiagram) Struct

func (d *ClassDiagram) Struct(obj interface{}) VRecord

func (*ClassDiagram) WriteSvg

func (d *ClassDiagram) WriteSvg(w io.Writer) error

WriteSvg renders the diagram as SVG to the given writer.

type Diagram

type Diagram struct {
	draw.Svg
	shape.Aligner
	shape.Style

	Caption *shape.Label
}

Diagram is a generic SVG image with box related styling

Example
package main

import (
	"github.com/gregoryv/draw/shape"
	"github.com/gregoryv/draw/shape/design"
)

func main() {
	var (
		record     = shape.NewRecord("Record")
		x, y       = 130, 80
		q1arrow    = shape.NewArrow(x, y, x+50, y-10)
		q2arrow    = shape.NewArrow(x, y, x-30, y-10)
		q3arrow    = shape.NewArrow(x, y, x-50, y+20)
		q4arrow    = shape.NewArrow(x, y, x+40, y+20)
		rightarrow = shape.NewArrow(x, y, x+90, y)
		leftarrow  = shape.NewArrow(x, y, x-50, y)
		uparrow    = shape.NewArrow(x, y, x, y-40)
		downarrow  = shape.NewArrow(x, y, x, y+40)
		label      = shape.NewLabel("Label")
		withtail   = shape.NewArrow(20, 100, 150, 100)
		diaarrow   = shape.NewArrow(20, 120, 150, 120)
		note       = shape.NewNote(`Notes support
multilines`)
		comp   = shape.NewComponent("database")
		srv    = shape.NewComponent("service")
		circle = shape.NewCircle(10)
		dot    = shape.NewDot()
		exit   = shape.NewExitDot()
		rect   = shape.NewRect("Rect")
		state  = shape.NewState("Waiting for go routine")
		d      = design.NewDiagram()
	)
	d.Place(record).At(10, 30)
	for _, arrow := range []*shape.Arrow{
		q1arrow, q2arrow, q3arrow, q4arrow,
		rightarrow, leftarrow,
		uparrow, downarrow,
	} {
		d.Place(arrow)
	}
	d.Place(label).RightOf(record, 150)
	withtail.Tail = shape.NewCircle(3)
	d.Place(withtail).At(20, 150)
	diaarrow.Tail = shape.NewDiamond()
	d.Place(diaarrow).Below(withtail)
	d.Place(note).Below(diaarrow)
	d.Place(circle).Below(note)
	d.Place(dot).RightOf(circle)
	d.Place(exit).RightOf(dot)
	d.HAlignCenter(circle, dot, exit)
	d.LinkAll(circle, dot, exit)
	d.Place(comp).RightOf(diaarrow)
	d.Place(rect).Below(circle)
	d.Place(state).RightOf(rect)
	d.Place(srv).Below(comp)
	d.VAlignCenter(comp, srv)
	d.Link(srv, comp, "")
	d.SaveAs("img/diagram_example.svg")
}

func NewDiagram

func NewDiagram() Diagram

NewDiagram returns a diagram with present font and padding values.

TODO: size and padding affects eg. records, but is related to the styling

func (*Diagram) AdaptSize

func (d *Diagram) AdaptSize() (int, int)

AdaptSize adapts the diagram size to the shapes inside it so all are visible. Returns the new width and height

func (d *Diagram) Link(from, to shape.Shape, txt ...string) *shape.Arrow

Link places an arrow with a optional label above it between the two shapes.

func (*Diagram) LinkAll

func (d *Diagram) LinkAll(s ...shape.Shape)

LinkAll places arrows between each shape, s0->s1->...->sn

func (*Diagram) Place

func (d *Diagram) Place(s ...shape.Shape) *shape.Adjuster

Place adds the shape to the diagram returning an adjuster for positioning.

func (*Diagram) PlaceGrid

func (d *Diagram) PlaceGrid(cols, X, Y int, s ...shape.Shape)

PlaceGrid place all the shapes into a grid starting at X,Y position. Row height is adapted to heighest element.

func (*Diagram) SaveAs

func (d *Diagram) SaveAs(filename string) error

SaveAs saves the diagram to filename as SVG

func (*Diagram) SetCaption

func (d *Diagram) SetCaption(txt string)

SetCaption adds a caption to the bottom of the diagram.

func (*Diagram) WriteSvg

func (d *Diagram) WriteSvg(w io.Writer) error

type GanttAdjuster added in v0.9.0

type GanttAdjuster struct {
	// contains filtered or unexported fields
}

func (*GanttAdjuster) After added in v0.9.0

func (a *GanttAdjuster) After(parent *Task, days int)

func (*GanttAdjuster) At added in v0.9.0

func (a *GanttAdjuster) At(from date.String, days int)

type GanttChart added in v0.8.0

type GanttChart struct {
	Diagram

	// Set a marker at this date.
	Mark time.Time

	Weeks bool
	// contains filtered or unexported fields
}
Example
package main

import (
	"github.com/gregoryv/draw/shape/design"
)

func main() {
	var (
		d   = design.NewGanttChart("20191111", 30)
		dev = d.Add("Develop")
		rel = d.Add("Release").Red()
		vac = d.Add("Vacation").Blue()
	)
	d.MarkDate("20191120")
	d.Place(dev).At("20191111", 10)
	d.Place(rel).After(dev, 1)
	d.Place(vac).At("20191125", 14)
	d.SetCaption("Figure 1. Project estimated delivery")
	d.SaveAs("img/gantt_chart.svg")
}
Example (Year)
package main

import (
	"github.com/gregoryv/draw/shape/design"
)

func main() {
	var (
		d   = design.NewGanttChart("20191111", 365)
		dev = d.Add("Develop")
		rel = d.Add("Release").Red()
		vac = d.Add("Vacation").Blue()
	)
	d.Weeks = true
	d.MarkDate("20200404")
	d.Place(dev).At("20191111", 60)
	d.Place(rel).After(dev, 1)
	d.Place(vac).At("20200404", 21)
	d.SetCaption("Figure 1. Project estimated delivery")
	d.SaveAs("img/gantt_year.svg")
}

func NewGanttChart added in v0.8.0

func NewGanttChart(from date.String, days int) *GanttChart

NewGanttChart returns a GanttChart spanning days from the given date. Panics if date cannot be resolved.

func (*GanttChart) Add added in v0.8.0

func (g *GanttChart) Add(txt string) *Task

Add new task from start spanning 3 days. Default color is green.

func (*GanttChart) MarkDate added in v0.9.0

func (g *GanttChart) MarkDate(yyyymmdd date.String)

func (*GanttChart) Place added in v0.9.0

func (g *GanttChart) Place(task *Task) *GanttAdjuster

Add new task. Default color is green.

func (*GanttChart) SaveAs added in v0.8.0

func (d *GanttChart) SaveAs(filename string) error

func (*GanttChart) WriteSvg added in v0.8.0

func (d *GanttChart) WriteSvg(w io.Writer) error
type Link struct {
	Class     string
	TextClass string
	// contains filtered or unexported fields
}

Link represents an arrow in a sequence diagram

type Relation

type Relation struct {
	// contains filtered or unexported fields
}

Relation defines a relation between two records

type SequenceDiagram

type SequenceDiagram struct {
	Diagram
	ColWidth int
	VMargin  int // top margin for each horizontal lane
	// contains filtered or unexported fields
}

SequenceDiagram defines columns and links between columns.

Example
package main

import (
	"database/sql"

	"github.com/gregoryv/draw/internal/app"
	"github.com/gregoryv/draw/shape/design"
)

func main() {
	var (
		d   = design.NewSequenceDiagram()
		cli = d.AddStruct(app.Client{})
		srv = d.AddStruct(app.Server{})
		db  = d.AddStruct(sql.DB{})
	)
	d.Link(cli, srv, "connect()")
	d.Link(srv, db, "SELECT").Class = "highlight"
	d.Link(db, srv, "Rows")
	d.Link(srv, srv, "Transform to view model").Class = "highlight"
	d.Link(srv, cli, "Send HTML")
	d.SaveAs("img/app_sequence_diagram.svg")
}

func NewSequenceDiagram

func NewSequenceDiagram() *SequenceDiagram

NewSequenceDiagram returns a sequence diagram with default column width.

func (*SequenceDiagram) AddColumns

func (d *SequenceDiagram) AddColumns(names ...string)

func (*SequenceDiagram) AddStruct

func (d *SequenceDiagram) AddStruct(obj interface{}) string
func (d *SequenceDiagram) ClearLinks()

func (*SequenceDiagram) Height

func (d *SequenceDiagram) Height() int

Height returns the total height of the diagram

func (d *SequenceDiagram) Link(from, to, text string) *Link

func (*SequenceDiagram) SaveAs

func (d *SequenceDiagram) SaveAs(filename string) error

func (*SequenceDiagram) Width

func (d *SequenceDiagram) Width() int

Width returns the total width of the diagram

func (*SequenceDiagram) WriteSvg

func (d *SequenceDiagram) WriteSvg(w io.Writer) error

WriteSvg renders the diagram as SVG to the given writer.

type Task added in v0.8.0

type Task struct {
	// contains filtered or unexported fields
}

Task is the colorized span of a gantt chart.

func NewTask added in v0.8.0

func NewTask(txt string) *Task

NewTask returns a green task.

func (*Task) Blue added in v0.8.0

func (t *Task) Blue() *Task

Blue sets class of task to span-blue

func (*Task) Red added in v0.8.0

func (t *Task) Red() *Task

Red sets class of task to span-red

type VRecord

type VRecord struct {
	*shape.Record
	// contains filtered or unexported fields
}

VRecord represents a type struct or interface as a record shape.

func NewVRecord added in v0.11.0

func NewVRecord(v interface{}) *VRecord

func (*VRecord) Aggregates added in v0.8.0

func (vr *VRecord) Aggregates(d *VRecord) bool

func (*VRecord) ComposedOf added in v0.8.0

func (vr *VRecord) ComposedOf(d *VRecord) bool

func (*VRecord) Implements added in v0.8.0

func (vr *VRecord) Implements(iface *VRecord) bool

func (*VRecord) TitleOnly

func (vr *VRecord) TitleOnly()

TitleOnly hides fields and methods.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL