Skip to content

Commit 034d328

Browse files
authored
Merge pull request #54 from owulveryck/horizontalplacement-wtg
horizontalplacement wtg
2 parents 671f748 + 560b603 commit 034d328

File tree

11 files changed

+437
-240
lines changed

11 files changed

+437
-240
lines changed

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
evolution: |...|...x.|..>.|.......|
7272
}
7373
power: {
74-
type: outsource
74+
type: pipeline
7575
evolution: |...|...|....x|.....>..|
7676
}
7777

docs/wtg.wasm

-67.7 KB
Binary file not shown.

examples/webassembly/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ assets/index.html: server/assets/index.html
1717

1818
install: all
1919
cp assets/index.html assets/script.js assets/style.css assets/wtg.wasm ../../docs
20+
21+
clean:
22+
rm assets/wtg.wasm

parser/wtg/coords.go

Lines changed: 58 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -1,220 +1,80 @@
11
package wtg
22

33
import (
4-
"fmt"
5-
"math"
6-
"sort"
7-
84
"github.com/owulveryck/wardleyToGo"
95
"github.com/owulveryck/wardleyToGo/components/wardley"
10-
"gonum.org/v1/gonum/graph/path"
6+
"gonum.org/v1/gonum/graph/simple"
117
)
128

13-
func computeEvolutionPosition(s string) (int, int, error) {
14-
// stages is an array containing the size of each stage
15-
// for example if the string is |...|....|.....|......|
16-
// then stages is [3,4,5,6]
17-
stages := make([]int, 4)
18-
// cursor is the place of the cursor in its stage (ex: |..x..|, x=3; |x|, x=0)
19-
cursor := 0
20-
// stage is the actual stage where the cursor is (x)
21-
stage := 0
22-
evolvedCursor := 0
23-
evolvedStage := 0
24-
// Position of each stage
25-
stagePositions := []float64{0, 17.4, 40, 70, 100}
26-
iteratorStage := -1
27-
iteratorCursor := 0
28-
x := 0
29-
sup := 0
30-
for _, c := range s {
31-
switch c {
32-
case '|':
33-
iteratorCursor = 0
34-
iteratorStage++
35-
continue
36-
case 'x':
37-
x++
38-
cursor = iteratorCursor
39-
stage = iteratorStage
40-
stages[iteratorStage]++
41-
case '>':
42-
sup++
43-
evolvedCursor = iteratorCursor
44-
evolvedStage = iteratorStage
45-
stages[iteratorStage]++
46-
default:
47-
iteratorCursor++
48-
if iteratorStage < 0 {
49-
return 0, 0, fmt.Errorf("expected | as a first element")
50-
}
51-
if iteratorStage >= len(stages) {
52-
return 0, 0, fmt.Errorf("too many |")
9+
// SetCoords sets the y anx x axis of the components
10+
func SetCoords(m wardleyToGo.Map, withEvolution bool) {
11+
tempMap := &scratchMapchMap{backend: simple.NewDirectedGraph()}
12+
ns := m.Nodes()
13+
inventory := make(map[int64]*node)
14+
for ns.Next() {
15+
if c, ok := ns.Node().(*wardley.EvolvedComponent); ok {
16+
n := &node{
17+
c: c.Component,
5318
}
54-
stages[iteratorStage]++
19+
inventory[c.ID()] = n
20+
tempMap.AddNode(n)
5521
}
56-
}
57-
if iteratorStage != 4 {
58-
return 0, 0, fmt.Errorf("expected 5x|")
59-
}
60-
if x != 1 {
61-
return 0, 0, fmt.Errorf("expeted one and only one x")
62-
}
63-
if sup > 1 {
64-
return 0, 0, fmt.Errorf("expeted one or less >")
65-
}
66-
position := 50.0
67-
if stages[stage] != 0 {
68-
percentageInCurrentStage := float64(cursor+1) / float64(stages[stage]+1)
69-
//log.Printf("\n\t%v\n\tstages: %v\n\tcurrent stage: %v\n\tcursor: %v\n\tpercentage: %v", s, stages, stage, cursor, percentageInCurrentStage)
70-
position = stagePositions[stage] + (stagePositions[stage+1]-stagePositions[stage])*percentageInCurrentStage
71-
}
72-
evolvedPosition := 0.0
73-
if stages[evolvedStage] != 0 && sup != 0 {
74-
percentageInCurrentStage := float64(evolvedCursor+1) / float64(stages[evolvedStage]+1)
75-
evolvedPosition = stagePositions[evolvedStage] + (stagePositions[evolvedStage+1]-stagePositions[evolvedStage])*percentageInCurrentStage
76-
}
77-
if position >= evolvedPosition && evolvedPosition != 0 {
78-
return 0, 0, fmt.Errorf("cannot have an evolution before the cursor")
79-
}
80-
return int(math.Round(position)), int(math.Round(evolvedPosition)), nil
81-
}
82-
83-
type nodeSorter []wardleyToGo.Component
84-
85-
// Len is part of sort.Interface.
86-
func (s nodeSorter) Len() int {
87-
return len(s)
88-
}
89-
90-
// Swap is part of sort.Interface.
91-
func (s nodeSorter) Swap(i, j int) {
92-
s[i], s[j] = s[j], s[i]
93-
}
94-
95-
// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
96-
func (s nodeSorter) Less(i, j int) bool {
97-
var labelI string
98-
var labelJ string
99-
if current, ok := s[i].(*wardley.Component); ok {
100-
labelI = current.Label
101-
}
102-
if current, ok := s[i].(*wardley.EvolvedComponent); ok {
103-
labelI = current.Label
104-
}
105-
if current, ok := s[j].(*wardley.Component); ok {
106-
labelJ = current.Label
107-
}
108-
if current, ok := s[j].(*wardley.EvolvedComponent); ok {
109-
labelJ = current.Label
110-
}
111-
return labelI < labelJ
112-
}
113-
114-
func (p *Parser) computeX() {
115-
wide := 100
116-
layersAndNodes := make(map[int][]wardleyToGo.Component)
117-
nodesIT := p.WMap.Nodes()
118-
allNodes := make([]wardleyToGo.Component, nodesIT.Len())
119-
for i := 0; nodesIT.Next(); i++ {
120-
current := nodesIT.Node().(wardleyToGo.Component)
121-
allNodes[i] = current
122-
layersAndNodes[current.GetPosition().Y] = append(layersAndNodes[current.GetPosition().Y], current)
123-
}
124-
// sort the nodes to be coherent
125-
sort.Sort(nodeSorter(allNodes))
126-
// Arrange nodes on the same layer
127-
for _, nodes := range layersAndNodes {
128-
sort.Sort(nodeSorter(nodes))
129-
nodesNumber := len(nodes)
130-
// if more than one node on the row, dispatch them
131-
if nodesNumber > 1 {
132-
step := wide / (nodesNumber + 1)
133-
for i, n := range nodes {
134-
if n, ok := n.(*wardley.Component); ok {
135-
n.Placement.X = step * (i + 1)
136-
}
137-
if n, ok := n.(*wardley.EvolvedComponent); ok {
138-
n.Placement.X = step * (i + 1)
139-
}
22+
if c, ok := ns.Node().(*wardley.Component); ok {
23+
n := &node{
24+
c: c,
14025
}
26+
inventory[c.ID()] = n
27+
tempMap.AddNode(n)
14128
}
14229
}
143-
// set nodes randomly
144-
for i, current := range allNodes {
30+
es := m.Edges()
31+
for es.Next() {
32+
tempMap.SetEdge(&edge{
33+
f: inventory[es.Edge().From().ID()],
34+
t: inventory[es.Edge().To().ID()],
35+
visibility: es.Edge().(*wardley.Collaboration).Visibility,
36+
})
37+
}
38+
maxVisibility := setNodesVisibility(tempMap)
39+
setY(tempMap, m, maxVisibility)
40+
if withEvolution {
41+
maxEvolution := setNodesEvolutionStep(tempMap)
42+
setX(tempMap, m, maxEvolution)
43+
}
44+
// TODO set the graph nodes
45+
}
14546

146-
if current.GetPosition().X == 0 {
147-
if current, ok := current.(*wardley.Component); ok {
148-
current.Placement.X = 50 + 4*(i%2) - 4*((i+1)%2)
149-
}
150-
if current, ok := current.(*wardley.EvolvedComponent); ok {
151-
current.Placement.X = 50 + 4*(i%2) - 4*((i+1)%2)
152-
}
47+
func setY(buf *scratchMapchMap, m wardleyToGo.Map, maxVisibility int) {
48+
vStep := 50
49+
if maxVisibility != 0 {
50+
vStep = 96 / maxVisibility
51+
}
52+
allNodes := buf.Nodes()
53+
for allNodes.Next() {
54+
n := allNodes.Node().(*node)
55+
if c, ok := m.Node(n.ID()).(*wardley.Component); ok {
56+
c.Placement.Y = n.visibility*vStep + 2
15357
}
154-
}
155-
nodesIT.Reset()
156-
for nodesIT.Next() {
157-
current := nodesIT.Node().(wardleyToGo.Component)
158-
fromIT := p.WMap.From(current.ID())
159-
// if only one child, set it at the X of the only father, or at the center otherwise
160-
for i := 0; fromIT.Next(); i++ {
161-
child := fromIT.Node().(wardleyToGo.Component)
162-
fathers := p.WMap.To(child.ID())
163-
if fathers.Len() == 1 && i == 0 {
164-
if child, ok := child.(*wardley.Component); ok {
165-
child.Placement.X = current.GetPosition().X
166-
}
167-
if child, ok := child.(*wardley.EvolvedComponent); ok {
168-
child.Placement.X = current.GetPosition().X
169-
}
170-
}
58+
if c, ok := m.Node(n.ID()).(*wardley.EvolvedComponent); ok {
59+
c.Placement.Y = n.visibility*vStep + 2
17160
}
17261
}
173-
}
17462

175-
func (p *Parser) computeY() {
176-
allShortestPaths := path.DijkstraAllPaths(p.WMap)
177-
roots := findRoot(p.WMap)
178-
leafs := findLeafs(p.WMap)
179-
maxDepth := 1
180-
for _, r := range roots {
181-
for _, l := range leafs {
182-
paths, _ := allShortestPaths.AllBetween(r.ID(), l.ID())
183-
for _, path := range paths {
184-
currentVisibility := 0
185-
for i := 0; i < len(path)-1; i++ {
186-
e := p.WMap.Edge(path[i].ID(), path[i+1].ID())
187-
currentVisibility += e.(*wardley.Collaboration).Visibility
188-
}
189-
if currentVisibility > maxDepth {
190-
maxDepth = currentVisibility
191-
}
63+
}
64+
func setX(buf *scratchMapchMap, m wardleyToGo.Map, maxEvolution int) {
65+
hStep := 50
66+
if maxEvolution != 0 {
67+
hStep = 20 / maxEvolution
68+
}
69+
allNodes := buf.Nodes()
70+
for allNodes.Next() {
71+
n := allNodes.Node().(*node)
72+
if nn, ok := m.Node(n.ID()).(*wardley.Component); ok {
73+
if !nn.Configured {
74+
nn.Placement.X = n.evolutionStep*hStep + 30
75+
nn.Color = Colors["Grey"]
19276
}
19377
}
19478
}
19579

196-
step := 96 / maxDepth
197-
cs := &coordSetter{
198-
verticalStep: step,
199-
}
200-
for _, n := range roots {
201-
cs.walk(p.WMap, n, 0)
202-
}
203-
}
204-
205-
type coordSetter struct {
206-
verticalStep int
207-
}
208-
209-
func (c *coordSetter) walk(m *wardleyToGo.Map, n *wardley.Component, visibility int) {
210-
n.Placement.Y = 2 + visibility*c.verticalStep
211-
fromIT := m.From(n.ID())
212-
for fromIT.Next() {
213-
switch fromNode := fromIT.Node().(type) {
214-
case *wardley.Component:
215-
c.walk(m, fromNode, m.Edge(n.ID(), fromNode.ID()).(*wardley.Collaboration).Visibility+visibility)
216-
case *wardley.EvolvedComponent:
217-
c.walk(m, fromNode.Component, m.Edge(n.ID(), fromNode.ID()).(*wardley.Collaboration).Visibility+visibility)
218-
}
219-
}
22080
}

0 commit comments

Comments
 (0)