# HG changeset patch # User Sean E. Russell # Date 1426209078 14400 # Thu Mar 12 21:11:18 2015 -0400 # Node ID 8d13797bcfff1c43aecb9ca431e4a8d6889c2b8b # Parent 477e09c419a1d9bd92fe931d314e480078b030f9 Documentation diff --git a/cmd/orgchart/main.go b/cmd/orgchart/main.go --- a/cmd/orgchart/main.go +++ b/cmd/orgchart/main.go @@ -10,6 +10,9 @@ "github.com/ajstarks/svgo" ) +/************************************************************************** + * Constants & global variables * + **************************************************************************/ const ( boxW = 170 gapW = 30 @@ -25,10 +28,40 @@ var pageWidth int +/************************************************************************** + * Main * + **************************************************************************/ +func main() { + c := flag.String("c", "", "CSV input file") + flag.Parse() + if *c == "" { + fmt.Println("CSV is required") + flag.Usage() + os.Exit(1) + } + f, e := os.Open(*c) + defer f.Close() + if e != nil { + fmt.Println(e.Error()) + os.Exit(1) + } + ps, e := makePeople(f) + if e != nil { + fmt.Println(e.Error()) + os.Exit(1) + } + rs := rank(ps) + renderSVG(os.Stdout, rs) +} + +/************************************************************************** + * Person & methods * + **************************************************************************/ type Person struct { - Name string - Manager *Person - Reports []*Person + Name string + Manager *Person + Reports []*Person + Contractor bool } // The index of this person in the person's manager's reports @@ -87,6 +120,9 @@ return &Person{Name: n, Reports: make([]*Person, 0)} } +/************************************************************************** + * Box & methods * + **************************************************************************/ type Box struct { X, Y int Leaf bool @@ -103,29 +139,12 @@ return b.X + boxW/2, b.Y } -func main() { - c := flag.String("c", "", "CSV input file") - flag.Parse() - if *c == "" { - fmt.Println("CSV is required") - flag.Usage() - os.Exit(1) - } - f, e := os.Open(*c) - defer f.Close() - if e != nil { - fmt.Println(e.Error()) - os.Exit(1) - } - ps, e := makePeople(f) - if e != nil { - fmt.Println(e.Error()) - os.Exit(1) - } - rs := rank(ps) - renderSVG(os.Stdout, rs) -} +/************************************************************************** + * Utility functions * + **************************************************************************/ +// Parses a CSV data stream, producing a map of people indexed by the person +// name. Returns an error if a non-EOF read error is encountered func makePeople(f io.Reader) (map[string]*Person, error) { r := csv.NewReader(f) r.LazyQuotes = true @@ -159,6 +178,8 @@ return ps, e } +// Given a map of people, produces a ranking where rank[0] are people with no +// managers, rank[1] are people who's managers are in rank[1], and so on. func rank(ps map[string]*Person) Ranks { rs := make(Ranks, 0) for _, p := range ps { @@ -173,6 +194,8 @@ return rs } +// Adds a person and their reports to the supplied ranks structure and recurses +// into the reports, creating new ranks as needed func addRecursively(p *Person, rs Ranks, i int) Ranks { if len(rs) <= i { rs = append(rs, make(Rank, 0)) @@ -184,6 +207,9 @@ return rs } +/************************************************************************** + * SVG generating code * + **************************************************************************/ func renderSVG(out io.Writer, rs Ranks) { c := svg.New(out) pageWidth := rs.width()