layli

package module
v0.0.14 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2024 License: Apache-2.0 Imports: 16 Imported by: 0

README

layli

This tools produces diagrams and has 2 simple aims:

  1. Define components and connections as code
  2. Look pretty

GitHub release (latest SemVer) Build Status codecov godoc Go Report Card

GitHub watchers GitHub stars Twitter URL

ko-fi

Using layli

Installation
$ go install github.com/dnnrly/layli/cmd/layli
A simple examples

Your first layli file:

node: "Hello World"
$ layli hello-world.layli

layli principles

layli aims to let you specify nodes and edges (boxes and lines) and looks after arranging them in a pleasing way. If you've ever used plantuml you'll be familiar with describing the diagrams in a simple to understand text file to generate a pretty diagram. Well, perhaps not as pretty as you would hope. This tool aims to solve this.

Here are some principles that hope to tackle this problem head on:

  1. Edge paths must travel across a "path grid"
  2. Node borders must be on the "path grid"
  3. Edges must meet nodes at "ports"
  4. Ports must sit on the "path grid"
  5. Where a port is not specified, layli may select a "default" port on any side of the node
  6. Nodes must be layed out so that the total area marked by the outside bounds of every node is as small as possible
  7. Nodes must be seperated by at least 1 space on the "path grid"
  8. Edges must must not cross!
  9. Edges must follow a grid path (ie. not curved or diagonal)
  10. Edges must be as short as possible
  11. Edges must have as few corners as possible
  12. Edge paths may sit on top of each other at the beginning or at the end
Defining nodes

Specifying a simple node:

Complex nodes:

nodes:
  - id: node-1
    contents: "A\nwith formatting"

Connecting nodes:

edges:
  - from: node-1
    to: "The node name"

Defining the layout style:

layout: flow-square

There are currently 3 different layout styles:

  • flow-square - nodes are arranged into rows and columns, much the way you read words on a page
  • topo-sort - nodes are sorted in order of the edges, all in a single row
  • tarjan - uses Tarjan's Algorithm to arrange the nodes an a 'pleasing' way
  • absolute - lets you specify where you want nodes to appear on the diagram
An example diagram

Here's an image that is generated by this command layli ./demo.layli --show-grid:

Demonstration image
Layli definition for this file
layout: flow-square
nodes:
    - id: a
      contents: Node A
    - id: b
      contents: Node B
    - id: c
      contents: Node C
    - id: d
      contents: Node D
    - id: e
      contents: Node E
    - id: f
      contents: Node F
    - id: g
      contents: Node G
    - id: h
      contents: Node H
    - id: i
      contents: Node J

edges:
    - from: a
      to: b
    - from: b
      to: c
    - from: c
      to: d
    - from: d
      to: e
    - from: c
      to: e
    - from: e
      to: d
    - from: d
      to: f
    - from: f
      to: g
    - from: f
      to: h
    - from: g
      to: i

width: 7
height: 4
border: 2
margin: 2

# You can also add comments to your file, like so.

You can see further examples here

Developing layli

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

Running Unit Tests
$ make test
Running Acceptance tests
$ make acceptance-test

Important make targets

  • deps - downloads all of the deps you need to build, test, and release
  • install - installs your application
  • build - builds your application
  • test - runs unit tests
  • ci-test - run tests for CI validation
  • acceptance-test - run the acceptance tests
  • coverage-report - merge coverage statistics from all sources
  • mocks - generate mocks for interface
  • lint - run linting
  • clean - clean project dependencies
  • clean-deps - remove all of the build dependencies too

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Pascal Dennerly - Initial work - dnnrly

See also the list of contributors who participated in this project.

License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details

Acknowledgments

  • There is a blog that I read a couple of years ago that described solving a similar problem. For the life of me, I can't remember find it anywhere to give the appropriate credit. But believe me when I say that a lot of the ideas are based on this blog and a lot of credit belongs to the author.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AbsoluteFromSVG added in v0.0.12

func AbsoluteFromSVG(svg string, output OutputFunc) error

AbsuluteFromSVG parses a string of an SVG and turns it in to a Layli configuration with with absulute layout that can represent the same SVG

func PythagoreanDistance added in v0.0.2

func PythagoreanDistance(from, to dijkstra.Point) int64

Types

type Arc added in v0.0.1

type Arc struct {
	From     Point
	To       Point
	Distance int
}

type Arcs added in v0.0.1

type Arcs []Arc

func (*Arcs) Add added in v0.0.1

func (all *Arcs) Add(from Point, to Point, distance int)

func (Arcs) Exists added in v0.0.1

func (all Arcs) Exists(from Point, to Point) bool

func (Arcs) Get added in v0.0.1

func (all Arcs) Get(from Point, to Point) Arc

func (Arcs) String added in v0.0.1

func (all Arcs) String() string

type Config added in v0.0.1

type Config struct {
	Layout         string      `yaml:"layout,omitempty"`
	LayoutAttempts int         `yaml:"layout-attempts,omitempty"`
	Path           ConfigPath  `yaml:"path,omitempty"`
	Nodes          ConfigNodes `yaml:"nodes"`
	Edges          ConfigEdges `yaml:"edges"`
	Spacing        int         `yaml:"-"`

	NodeWidth  int `yaml:"width"`
	NodeHeight int `yaml:"height"`
	Border     int `yaml:"border"`
	Margin     int `yaml:"margin"`

	Styles ConfigStyles `yaml:"styles,omitempty"`
}

func NewConfigFromFile added in v0.0.4

func NewConfigFromFile(r io.Reader) (*Config, error)

func (Config) String added in v0.0.12

func (config Config) String() string

type ConfigEdge added in v0.0.1

type ConfigEdge struct {
	ID    string `yaml:"id,omitempty"`
	From  string `yaml:"from"`
	To    string `yaml:"to"`
	Class string `yaml:"class,omitempty"`
	Style string `yaml:"style,omitempty"`
}

type ConfigEdges added in v0.0.1

type ConfigEdges []ConfigEdge

type ConfigNode added in v0.0.1

type ConfigNode struct {
	Id       string   `yaml:"id"`
	Contents string   `yaml:"contents"`
	Position Position `yaml:"position,omitempty"`
	Class    string   `yaml:"class,omitempty"`
	Style    string   `yaml:"style,omitempty"`
}

type ConfigNodes added in v0.0.1

type ConfigNodes []ConfigNode

func (ConfigNodes) ByID added in v0.0.4

func (nodes ConfigNodes) ByID(id string) *ConfigNode

type ConfigPath added in v0.0.6

type ConfigPath struct {
	Attempts int    `yaml:"attempts,omitempty"`
	Strategy string `yaml:"strategy,omitempty"`
	Class    string `yaml:"class,omitempty"`
}

type ConfigStyles added in v0.0.10

type ConfigStyles map[string]string

type CreateFinder added in v0.0.2

type CreateFinder func(start, end dijkstra.Point) PathFinder

type Diagram added in v0.0.1

type Diagram struct {
	Output   OutputFunc
	Config   Config
	Layout   *Layout
	ShowGrid bool
}

func (*Diagram) Draw added in v0.0.1

func (d *Diagram) Draw() error

Draw turns the diagram in to an image

type Layout added in v0.0.1

type Layout struct {
	Nodes        LayoutNodes
	Paths        LayoutPaths
	CreateFinder CreateFinder
	// contains filtered or unexported fields
}

func NewLayoutFromConfig added in v0.0.1

func NewLayoutFromConfig(finder CreateFinder, c *Config) (*Layout, error)

func (*Layout) Draw added in v0.0.1

func (l *Layout) Draw(canvas LayoutDrawer, spacing int)

func (*Layout) FindPath added in v0.0.6

func (l *Layout) FindPath(from, to string) (*LayoutPath, error)

func (*Layout) InsideAny added in v0.0.1

func (l *Layout) InsideAny(x, y int) bool

func (*Layout) IsAnyPort added in v0.0.1

func (l *Layout) IsAnyPort(x, y int) bool

func (*Layout) LayoutHeight added in v0.0.1

func (l *Layout) LayoutHeight() int

LayoutHeight is the height in path units

func (*Layout) LayoutWidth added in v0.0.1

func (l *Layout) LayoutWidth() int

LayoutWidth is the width in path units

func (*Layout) ShowGrid added in v0.0.1

func (l *Layout) ShowGrid(canvas LayoutDrawer, spacing int)

type LayoutArrangementFunc added in v0.0.4

type LayoutArrangementFunc func(c *Config) (LayoutNodes, error)

LayoutArrangementFunc returns a slice of nodes arranged according to the algorithm implemented

type LayoutDrawer added in v0.0.1

type LayoutDrawer interface {
	Circle(x int, y int, r int, s ...string)
	Path(d string, s ...string)
	Roundrect(x int, y int, w int, h int, rx int, ry int, s ...string)
	Textspan(x int, y int, t string, s ...string)
	TextEnd()
}

type LayoutNode added in v0.0.1

type LayoutNode struct {
	Id       string
	Contents string
	// contains filtered or unexported fields
}

func NewLayoutNode added in v0.0.1

func NewLayoutNode(id, contents string, left, top, width, height int, class, style string) LayoutNode

func (*LayoutNode) Draw added in v0.0.1

func (n *LayoutNode) Draw(d LayoutDrawer, spacing, order int)

func (*LayoutNode) GetCentre added in v0.0.1

func (n *LayoutNode) GetCentre() Point

func (*LayoutNode) GetPorts added in v0.0.1

func (n *LayoutNode) GetPorts() Points

func (*LayoutNode) IsInside added in v0.0.1

func (n *LayoutNode) IsInside(x, y int) bool

func (*LayoutNode) IsPort added in v0.0.1

func (n *LayoutNode) IsPort(x, y int) bool

type LayoutNodes added in v0.0.1

type LayoutNodes []LayoutNode

func LayoutAbsolute added in v0.0.8

func LayoutAbsolute(c *Config) (LayoutNodes, error)

func LayoutFlowSquare added in v0.0.4

func LayoutFlowSquare(c *Config) (LayoutNodes, error)

func LayoutRandomShortestSquare added in v0.0.7

func LayoutRandomShortestSquare(config *Config) (LayoutNodes, error)

func LayoutTarjan added in v0.0.4

func LayoutTarjan(config *Config) (LayoutNodes, error)

LayoutTarjan arranges nodes in multiple rows according to Tarhan's algorithm

func LayoutTopologicalSort added in v0.0.4

func LayoutTopologicalSort(config *Config) (LayoutNodes, error)

LayoutTopologicalSort arranges nodes in a single row, sorted in topological order

func (LayoutNodes) ByID added in v0.0.1

func (nodes LayoutNodes) ByID(id string) *LayoutNode

func (LayoutNodes) ConnectionDistances added in v0.0.7

func (n LayoutNodes) ConnectionDistances(connections ConfigEdges) (float64, error)

func (LayoutNodes) String added in v0.0.7

func (nodes LayoutNodes) String() string

type LayoutPath added in v0.0.1

type LayoutPath struct {
	ID     string
	From   string
	To     string
	Points Points
	Class  string
	Style  string
}

func (*LayoutPath) Draw added in v0.0.1

func (p *LayoutPath) Draw(canvas LayoutDrawer, spacing, order int)

func (*LayoutPath) Length added in v0.0.6

func (paths *LayoutPath) Length() float64

type LayoutPaths added in v0.0.1

type LayoutPaths []LayoutPath

func (*LayoutPaths) Draw added in v0.0.1

func (paths *LayoutPaths) Draw(canvas LayoutDrawer, spacing int)

func (LayoutPaths) Length added in v0.0.6

func (paths LayoutPaths) Length() float64

type OutputFunc added in v0.0.1

type OutputFunc func(output string) error

type PathFinder added in v0.0.2

type PathFinder interface {
	AddConnection(from dijkstra.Point, cost dijkstra.CostFunction, to ...dijkstra.Point)
	BestPath() ([]dijkstra.Point, error)
}

type PathStrategy added in v0.0.6

type PathStrategy func(config Config, paths *LayoutPaths, find func(from, to string) (*LayoutPath, error)) error

type Point added in v0.0.1

type Point struct {
	X float64
	Y float64
}

func (Point) Coordinates added in v0.0.2

func (p Point) Coordinates() (float64, float64)

func (Point) Distance added in v0.0.1

func (p Point) Distance(to Point) float64

func (Point) String added in v0.0.1

func (p Point) String() string

type Points added in v0.0.1

type Points []Point

func (Points) Path added in v0.0.1

func (p Points) Path(spacing int) string

type Position added in v0.0.8

type Position struct {
	X int `yaml:"x"`
	Y int `yaml:"y"`
}

type VertexMap added in v0.0.1

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

func BuildVertexMap added in v0.0.1

func BuildVertexMap(l *Layout) VertexMap

func NewVertexMap added in v0.0.1

func NewVertexMap(x, y int) VertexMap

func (*VertexMap) CountAvailable added in v0.0.1

func (v *VertexMap) CountAvailable(available bool) int

func (*VertexMap) Get added in v0.0.1

func (v *VertexMap) Get(x, y int) bool

func (VertexMap) GetArcs added in v0.0.1

func (vm VertexMap) GetArcs() Arcs

func (VertexMap) GetVertexPoints added in v0.0.1

func (v VertexMap) GetVertexPoints() Points

func (*VertexMap) Map added in v0.0.2

func (v *VertexMap) Map(m VertexStateMapper)

func (*VertexMap) MapAnd added in v0.0.1

func (v *VertexMap) MapAnd(m VertexMapper)

func (*VertexMap) MapOr added in v0.0.1

func (v *VertexMap) MapOr(m VertexMapper)

func (*VertexMap) MapSet added in v0.0.1

func (v *VertexMap) MapSet(m VertexMapper)

func (*VertexMap) MapUnset added in v0.0.1

func (v *VertexMap) MapUnset(m VertexMapper)

func (*VertexMap) Set added in v0.0.1

func (v *VertexMap) Set(x, y int, val bool)

func (VertexMap) String added in v0.0.1

func (v VertexMap) String() string

type VertexMapper added in v0.0.1

type VertexMapper func(x, y int) bool

type VertexStateMapper added in v0.0.2

type VertexStateMapper func(x, y int, state bool) bool

Directories

Path Synopsis
algorithms
cmd
pathfinder
Package test contains test definitions, code, and data.
Package test contains test definitions, code, and data.

Jump to

Keyboard shortcuts

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