diff --git a/README.md b/README.md
index 4d0a34c..01458a4 100644
--- a/README.md
+++ b/README.md
@@ -129,6 +129,11 @@ The `helloworld` color scheme drops in some colors!
+#### Mult-Bar / Stacked-Bar Chart
+[demo code](https://github.com/gizak/termui/blob/master/example/mbarchart.go)
+
+
+
#### Sparklines
[demo code](https://github.com/gizak/termui/blob/master/example/sparklines.go)
diff --git a/example/mbarchart.go b/example/mbarchart.go
index 7729104..a32a28e 100644
--- a/example/mbarchart.go
+++ b/example/mbarchart.go
@@ -18,10 +18,10 @@ func main() {
termui.UseTheme("helloworld")
bc := termui.NewMBarChart()
- math := []int{45, 75, 34, 62}
- english := []int{50, 45, 25, 57}
- science := []int{75, 60, 15, 50}
- compsci := []int{90, 95, 100, 100}
+ math := []int{90, 85, 90, 80}
+ english := []int{70, 85, 75, 60}
+ science := []int{75, 60, 80, 85}
+ compsci := []int{100, 100, 100, 100}
bc.Data[0] = math
bc.Data[1] = english
bc.Data[2] = science
@@ -33,6 +33,8 @@ func main() {
bc.Y = 10
bc.BarWidth = 10
bc.DataLabels = studentsName
+ bc.ShowScale = true //Show y_axis scale value (min and max)
+ bc.SetMax(400)
bc.TextColor = termui.ColorGreen //this is color for label (x-axis)
bc.BarColor[3] = termui.ColorGreen //BarColor for computerscience
diff --git a/example/mbarchart.png b/example/mbarchart.png
new file mode 100644
index 0000000..9a42526
Binary files /dev/null and b/example/mbarchart.png differ
diff --git a/mbar.go b/mbar.go
index 2f825a2..9d18c2c 100644
--- a/mbar.go
+++ b/mbar.go
@@ -41,6 +41,8 @@ type MBarChart struct {
max int
minDataLen int
numStack int
+ ShowScale bool
+ maxScale []rune
}
// NewBarChart returns a new *BarChart with current theme.
@@ -59,7 +61,7 @@ func (bc *MBarChart) layout() {
bc.labels = make([][]rune, bc.numBar)
DataLen := 0
LabelLen := len(bc.DataLabels)
- bc.minDataLen = 9999 //Set this to some very hight value so that we find the minimum one We want to know which array among data[][] has got the least lenght
+ bc.minDataLen = 9999 //Set this to some very hight value so that we find the minimum one We want to know which array among data[][] has got the least length
// We need to know how many stack/data array data[0] , data[1] are there
for i := 0; i < len(bc.Data); i++ {
@@ -70,7 +72,7 @@ func (bc *MBarChart) layout() {
}
bc.numStack = DataLen
- //We need to what is the mimimum size of data array data[0] could have 10 elements data[1] could have only 5, so we plot only 5 bar graphs
+ //We need to know what is the mimimum size of data array data[0] could have 10 elements data[1] could have only 5, so we plot only 5 bar graphs
for i := 0; i < DataLen; i++ {
if bc.minDataLen > len(bc.Data[i]) {
@@ -122,7 +124,16 @@ func (bc *MBarChart) layout() {
bc.max = dsum
}
}
- bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
+
+ //Finally Calculate max sale
+ if bc.ShowScale {
+ s := fmt.Sprintf("%d", bc.max)
+ bc.maxScale = trimStr2Runes(s, len(s))
+ bc.scale = float64(bc.max) / float64(bc.innerHeight-2)
+ } else {
+ bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
+ }
+
}
func (bc *MBarChart) SetMax(max int) {
@@ -140,9 +151,9 @@ func (bc *MBarChart) Buffer() []Point {
for i := 0; i < bc.numBar && i < bc.minDataLen && i < len(bc.DataLabels); i++ {
ph := 0 //Previous Height to stack up
+ oftX = i * (bc.BarWidth + bc.BarGap)
for i1 := 0; i1 < bc.numStack; i1++ {
h := int(float64(bc.Data[i1][i]) / bc.scale)
- oftX = i * (bc.BarWidth + bc.BarGap)
// plot bars
for j := 0; j < bc.BarWidth; j++ {
for k := 0; k < h; k++ {
@@ -167,7 +178,7 @@ func (bc *MBarChart) Buffer() []Point {
p.Bg = bc.BgColor
p.Fg = bc.TextColor
p.Y = bc.innerY + bc.innerHeight - 1
- p.X = bc.innerX + oftX + k
+ p.X = bc.innerX + oftX + ((bc.BarWidth - len(bc.labels[i])) / 2) + k
ps = append(ps, p)
k += w
}
@@ -194,5 +205,29 @@ func (bc *MBarChart) Buffer() []Point {
}
}
+ if bc.ShowScale {
+ //Currently bar graph only supprts data range from 0 to MAX
+ //Plot 0
+ p := Point{}
+ p.Ch = '0'
+ p.Bg = bc.BgColor
+ p.Fg = bc.TextColor
+ p.Y = bc.innerY + bc.innerHeight - 2
+ p.X = bc.X
+ ps = append(ps, p)
+
+ //Plot the maximum sacle value
+ for i := 0; i < len(bc.maxScale); i++ {
+ p := Point{}
+ p.Ch = bc.maxScale[i]
+ p.Bg = bc.BgColor
+ p.Fg = bc.TextColor
+ p.Y = bc.innerY
+ p.X = bc.X + i
+ ps = append(ps, p)
+ }
+
+ }
+
return bc.Block.chopOverflow(ps)
}