Skip to content

Commit

Permalink
add Hour and CriticalPath
Browse files Browse the repository at this point in the history
  • Loading branch information
ddddddO committed Nov 3, 2024
1 parent b06cc29 commit ebcd2dc
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 108 deletions.
178 changes: 137 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ func main() {
developFeature1.Note("xxが担当")
reviewDevelopFeature1 := g.Task("レビュー対応")

developFeature2 := g.Task("feature2開発").Note("yyが担当")
developFeature2 := g.Task("feature2開発")
developFeature2.Note("yyが担当")
reviewDevelopFeature2 := g.Task("レビュー対応")

prepareInfra := g.Task("インフラ準備").Note("zzが担当")
prepareInfra := g.Task("インフラ準備")
prepareInfra.Note("zzが担当")

test := g.Task("結合テスト")
release := g.Task("リリース")
Expand All @@ -53,7 +55,7 @@ func main() {
reviewDesign.Con(prepareInfra).Con(test)
test.Con(release).Con(finish)

g.Done(design, reviewDesign, developFeature2, finish)
g.Done(design, reviewDesign, developFeature1, reviewDevelopFeature1, developFeature2)

uml, err := dag.UML()
if err != nil {
Expand All @@ -69,14 +71,14 @@ func main() {
rectangle "ゴール(目的)" as 1
usecase "設計" as 2 #DarkGray
usecase "レビュー対応" as 3 #DarkGray
usecase "feature1開発" as 4
usecase "feature1開発" as 4 #DarkGray
note left
xxが担当
end note
usecase "レビュー対応" as 5
usecase "レビュー対応" as 5 #DarkGray
usecase "結合テスト" as 9
usecase "リリース" as 10
usecase "finish" as 11 #DarkGray
usecase "finish" as 11
usecase "feature2開発" as 6 #DarkGray
note left
yyが担当
Expand Down Expand Up @@ -107,8 +109,104 @@ end note
![image](dag.svg)


### Critical path

1. `go run main.go > dag.pu`

```go
package main

import (
"fmt"
"os"

g "github.com/ddddddO/gdag"
)

func main() {
var dag *g.Node = g.DAG("ゴール(目的)")

var design *g.Node = g.Task("設計").Hour(10)
reviewDesign := g.Task("レビュー対応").Hour(2)

developFeature1 := g.Task("feature1開発").Hour(20)
developFeature1.Note("xxが担当")
reviewDevelopFeature1 := g.Task("レビュー対応").Hour(1.5)

developFeature2 := g.Task("feature2開発").Hour(15)
developFeature2.Note("yyが担当")
reviewDevelopFeature2 := g.Task("レビュー対応").Hour(1.5)

prepareInfra := g.Task("インフラ準備").Hour(15)
prepareInfra.Note("zzが担当")

test := g.Task("結合テスト").Hour(20)
release := g.Task("リリース").Hour(2)
finish := g.Task("finish")

dag.Con(design).Con(reviewDesign).Con(developFeature1).Con(reviewDevelopFeature1).Con(test)
reviewDesign.Con(developFeature2).Con(reviewDevelopFeature2).Con(test)
reviewDesign.Con(prepareInfra).Con(test)
test.Con(release).Con(finish)

g.Done(design, reviewDesign, developFeature1, reviewDevelopFeature1, developFeature2)

// If you do not want to represent critical path, use `dag.UMLNoCritical()`.
uml, err := dag.UML()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(uml)
}
```

```
@startuml
rectangle "ゴール(目的)" as 1
usecase "設計 (10.0h)" as 2 #DarkGray-Yellow
usecase "レビュー対応 (2.0h)" as 3 #DarkGray-Yellow
usecase "feature1開発 (20.0h)" as 4 #DarkGray-Yellow
note left
xxが担当
end note
usecase "レビュー対応 (1.5h)" as 5 #DarkGray-Yellow
usecase "結合テスト (20.0h)" as 9 #Yellow
usecase "リリース (2.0h)" as 10 #Yellow
usecase "finish" as 11 #Yellow
usecase "feature2開発 (15.0h)" as 6 #DarkGray
note left
yyが担当
end note
usecase "レビュー対応 (1.5h)" as 7
usecase "インフラ準備 (15.0h)" as 8
note left
zzが担当
end note
1 --> 2
2 --> 3
3 --> 4
4 --> 5
5 --> 9
9 --> 10
10 --> 11
3 --> 6
6 --> 7
7 --> 9
3 --> 8
8 --> 9
@enduml
```

2. dag.pu to png or svg
![image](dag_critical.svg)

## Mermaid

※ Mermaid method does not support critical paths.

1. `go run main.go`

```go
Expand All @@ -124,30 +222,30 @@ import (
func main() {
var dag *g.Node = g.DAG("ゴール(目的)")

var design *g.Node = g.Task("設計")
reviewDesign := g.Task("レビュー対応")
var design *g.Node = g.Task("設計").Hour(10)
reviewDesign := g.Task("レビュー対応").Hour(2)

developFeature1 := g.Task("feature1開発")
developFeature1.Note("noop")
reviewDevelopFeature1 := g.Task("レビュー対応")
developFeature1 := g.Task("feature1開発").Hour(20)
developFeature1.Note("xxが担当")
reviewDevelopFeature1 := g.Task("レビュー対応").Hour(1.5)

developFeature2 := g.Task("feature2開発")
developFeature2.Note("noop")
reviewDevelopFeature2 := g.Task("レビュー対応")
developFeature2 := g.Task("feature2開発").Hour(15)
developFeature2.Note("yyが担当")
reviewDevelopFeature2 := g.Task("レビュー対応").Hour(1.5)

prepareInfra := g.Task("インフラ準備")
prepareInfra.Note("noop")
prepareInfra := g.Task("インフラ準備").Hour(15)
prepareInfra.Note("zzが担当")

test := g.Task("結合テスト")
release := g.Task("リリース")
test := g.Task("結合テスト").Hour(20)
release := g.Task("リリース").Hour(2)
finish := g.Task("finish")

dag.Con(design).Con(reviewDesign).Con(developFeature1).Con(reviewDevelopFeature1).Con(test)
reviewDesign.Con(developFeature2).Con(reviewDevelopFeature2).Con(test)
reviewDesign.Con(prepareInfra).Con(test)
test.Con(release).Con(finish)

g.Done(design, reviewDesign, developFeature2, finish)
g.Done(design, reviewDesign, developFeature1, reviewDevelopFeature1, developFeature2)

mermaid, err := dag.Mermaid()
if err != nil {
Expand All @@ -156,23 +254,22 @@ func main() {
}
fmt.Println(mermaid)
}

```

```
graph TD
classDef doneColor fill:#868787
1("ゴール(目的)")
2(["設計"]):::doneColor
3(["レビュー対応"]):::doneColor
4(["feature1開発"])
5(["レビュー対応"])
9(["結合テスト"])
10(["リリース"])
11(["finish"]):::doneColor
6(["feature2開発"]):::doneColor
7(["レビュー対応"])
8(["インフラ準備"])
2(["設計 (10.0h)"]):::doneColor
3(["レビュー対応 (2.0h)"]):::doneColor
4(["feature1開発 (20.0h)"]):::doneColor
5(["レビュー対応 (1.5h)"]):::doneColor
9(["結合テスト (20.0h)"])
10(["リリース (2.0h)"])
11(["finish"])
6(["feature2開発 (15.0h)"]):::doneColor
7(["レビュー対応 (1.5h)"])
8(["インフラ準備 (15.0h)"])
1 --> 2
2 --> 3
Expand All @@ -194,16 +291,16 @@ classDef doneColor fill:#868787
graph TD
classDef doneColor fill:#868787
1("ゴール(目的)")
2(["設計"]):::doneColor
3(["レビュー対応"]):::doneColor
4(["feature1開発"])
5(["レビュー対応"])
9(["結合テスト"])
10(["リリース"])
11(["finish"]):::doneColor
6(["feature2開発"]):::doneColor
7(["レビュー対応"])
8(["インフラ準備"])
2(["設計 (10.0h)"]):::doneColor
3(["レビュー対応 (2.0h)"]):::doneColor
4(["feature1開発 (20.0h)"]):::doneColor
5(["レビュー対応 (1.5h)"]):::doneColor
9(["結合テスト (20.0h)"])
10(["リリース (2.0h)"])
11(["finish"])
6(["feature2開発 (15.0h)"]):::doneColor
7(["レビュー対応 (1.5h)"])
8(["インフラ準備 (15.0h)"])
1 --> 2
2 --> 3
Expand All @@ -219,7 +316,6 @@ classDef doneColor fill:#868787
8 --> 9
```


## CheckList

1. `go run main.go`
Expand Down
60 changes: 1 addition & 59 deletions dag.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions dag_critical.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions mermaid.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ func (*mermaidGenerator) renderComponent(node *Node) string {
ret += s
case usecase:
s := fmt.Sprintf("%d([\"%s\"])", node.index, node.text)
if node.hour > 0 {
s = fmt.Sprintf("%d([\"%s (%.1fh)\"])", node.index, node.text, node.hour)
}
if len(node.colorMermaid) != 0 {
s += fmt.Sprintf(":::%s", node.colorMermaid)
}
Expand Down
16 changes: 12 additions & 4 deletions node.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package gdag

type Node struct {
nodeType nodeType
index int // mermaidの識別子としても利用する
text string
note string
nodeType nodeType
index int // mermaidの識別子としても利用する
text string
note string
hour float64 // 見積時間

color string // done: #DarkGray
colorMermaid string // done: doneColor

// parent *Node // TODO: 現状、中間ノードのためにおいてる
downstream []*Node
startPoint bool // レンダリング処理の最初の node ということ
}

type nodeType string
Expand Down Expand Up @@ -85,6 +88,11 @@ func (current *Node) Note(note string) *Node {
return current
}

func (current *Node) Hour(hour float64) *Node {
current.hour = hour
return current
}

func (current *Node) isDone() bool {
return current.color == colorDone
}
Expand Down
5 changes: 5 additions & 0 deletions node_short.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ func (upstream *Node) C(current *Node) *Node {
func (current *Node) N(note string) *Node {
return current.Note(note)
}

// H is short name of Hour func.
func (current *Node) H(hour float64) *Node {
return current.Hour(hour)
}
Loading

0 comments on commit ebcd2dc

Please sign in to comment.