Better box width based on text contents.
5 files changed, 74 insertions(+), 4 deletions(-)

M cmd/orgchart/main.go
M cmd/orgchart/main_test.go
M cmd/orgchart/svg.go
A => cmd/orgchart/svg_test.go
A => todo.txt
M cmd/orgchart/main.go +4 -2
@@ 14,6 14,7 @@ package main
 
 import (
 	"encoding/csv"
+	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"

          
@@ 185,9 186,10 @@ func makePeople(f io.Reader, cols []int,
 		ps[name] = p
 	}
 	if e == io.EOF {
-		e = nil
+		return ps, nil
 	}
-	return ps, e
+	erstrng := fmt.Sprintf("%s: \"%#v\"", e.Error(), l)
+	return ps, errors.New(erstrng)
 }
 
 // Given a map of people, produces a ranking where rank[0] are people with no

          
M cmd/orgchart/main_test.go +2 -1
@@ 144,7 144,8 @@ D2,C2B3`
 	assert.Equal(t, 5, rs.width())
 	assert.Equal(t, 6, rs.height())
 	setBoxH(rs)
-	assert.Equal(t, 450, height(rs))
+	assert.Equal(t, 450, height(rs, false))
+	assert.Equal(t, 530, height(rs, true))
 }
 
 func TestClass(t *testing.T) {

          
M cmd/orgchart/svg.go +24 -1
@@ 11,7 11,8 @@ import (
  *  Constants & global variables                                          *
  **************************************************************************/
 const (
-	boxW      = 300
+	charW     = 5
+	padW      = 30
 	gapW      = 30
 	marginW   = 20
 	gapH      = 100

          
@@ 28,6 29,7 @@ const (
 var pageWidth int
 var bgW int
 var boxH int
+var boxW int
 
 /**************************************************************************
  *  SVG generating code                                                   *

          
@@ 58,8 60,13 @@ func setBoxH(rs Ranks) {
 	}
 }
 
+func setBoxW(rs Ranks) {
+	boxW = maxTextWidth(rs)*charW + padW
+}
+
 func renderSVG(out io.Writer, rs Ranks, sup bool, css string) {
 	setBoxH(rs)
+	setBoxW(rs)
 	c := svg.New(out)
 	bgW = boxW + gapW
 	pageWidth := rs.width() * bgW

          
@@ 249,3 256,19 @@ func height(rs Ranks, s bool) int {
 func class(p *Person) string {
 	return "class='" + p.Class + "'"
 }
+
+func maxTextWidth(rs Ranks) (mw int) {
+	for _, ps := range rs {
+		for _, p := range ps {
+			if len(p.Name) > mw {
+				mw = len(p.Name)
+			}
+			for _, l := range p.Lines {
+				if len(l) > mw {
+					mw = len(l)
+				}
+			}
+		}
+	}
+	return mw
+}

          
A => cmd/orgchart/svg_test.go +40 -0
@@ 0,0 1,40 @@ 
+package main
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestMaxTextWidth(t *testing.T) {
+	tests := []string{
+		"X,,A,B,C\nXX,,A,B,C",
+		"X,,AA,B,C\nXX,,A,B,C",
+		"X,,AAA,B,C\nXX,,A,B,C",
+		"X,,AAA,B,C\nXX,,A,BBBB,C",
+		"X,,AAA,B,CCCCC\nXX,,A,BBBB,C",
+	}
+	expects := []int{
+		2,
+		2,
+		3,
+		4,
+		5,
+	}
+	h := "Person,Manager,Text 1,Text 2, Text 3\n"
+	var ps map[string]*Person
+	rx, er := makeRuleSet([]string{})
+	if er != nil {
+		assert.Fail(t, er.Error())
+	}
+	for i, tst := range tests {
+		b := bytes.NewBufferString(h + tst)
+		ps, er = makePeople(b, []int{2, 3, 4}, rx)
+		if er != nil {
+			assert.Fail(t, er.Error())
+		}
+		rs := rank(ps)
+		assert.Equal(t, expects[i], maxTextWidth(rs))
+	}
+}

          
A => todo.txt +4 -0
@@ 0,0 1,4 @@ 
+Dotted-line reports
+Admin associations
+Exclude
+Pictures