The callback cost bar charts about 10% on wide plots; barGlyph keeps the shared rule without an indirect call per cell.
- commit
- 534700c830f52c2d310c9ebede99c78a60058ddc
- parent
- 36ec6aeb432129a806bb658b60ff6e4d1a185fc9
- author
- Dami <dami.etoile@gmail.com>
| M | internal/ | 47 | +++++++++++++++--------------- |
| M | internal/ | 10 | ++++--- |
@@ -101,10 +101,13 @@ func (p *barPlan) draw(g *Grid, o Options) {
101101 if math.IsNaN(v) {102102 continue103103 }104- // Left of the axis, bars fill from the right.105- barCells(zero, p.sc.pos(v), v >= 0, leftEighths, "▐", func(c int, glyph string) {106- g.set(p.plot.Min.X+c, p.barRow(i, j), glyph, SeriesRole(j))107- })104+ lo, hi := min(zero, p.sc.pos(v)), max(zero, p.sc.pos(v))105+ for c := int(math.Floor(lo)); float64(c) < hi; c++ {106+ // Left of the axis, bars fill from the right.107+ if glyph := barGlyph(lo, hi, c, v >= 0, leftEighths, "▐"); glyph != "" {108+ g.set(p.plot.Min.X+c, p.barRow(i, j), glyph, SeriesRole(j))109+ }110+ }108111 }109112 }110113 }@@ -136,26 +139,22 @@ func (p *barPlan) drawAxis(g *Grid) {
136139 }137140 }138141 139-// barCells walks the cells a bar covers from zero to end, distances140-// along its axis in cells, calling fill with each cell and its glyph.141-// A positive bar grows away from the axis in eighths; a negative one142-// has no eighths growing the other way, so its partly covered cells are143-// a full block or the half block half.144-func barCells(zero, end float64, positive bool, eighths []string, half string, fill func(c int, glyph string)) {145- lo, hi := min(zero, end), max(zero, end)146- for c := int(math.Floor(lo)); float64(c) < hi; c++ {147- cover := min(hi, float64(c+1)) - max(lo, float64(c))148- glyph := ""149- switch {150- case positive:151- glyph = eighths[int(math.Round(cover*8))]152- case cover >= 0.75:153- glyph = "█"154- case cover >= 0.25:155- glyph = half156- }157- if glyph != "" && glyph != " " {158- fill(c, glyph)142+// barGlyph is the glyph of cell c of a bar from lo to hi, distances143+// along its axis in cells, or "" for none. A positive bar grows away144+// from the axis in eighths; a negative one has no eighths growing the145+// other way, so its partly covered cells are a full block or the half146+// block half.147+func barGlyph(lo, hi float64, c int, positive bool, eighths []string, half string) string {148+ cover := min(hi, float64(c+1)) - max(lo, float64(c))149+ switch {150+ case positive:151+ if g := eighths[int(math.Round(cover*8))]; g != " " {152+ return g159153 }154+ case cover >= 0.75:155+ return "█"156+ case cover >= 0.25:157+ return half160158 }159+ return ""161160 }@@ -168,12 +168,14 @@ func (p *columnPlan) drawBars(g *Grid) {
168168 continue169169 }170170 x0, x1 := p.bar(i, j)171- // Below the axis, bars fill from the top.172- barCells(zero, p.sc.pos(v), v >= 0, lowerEighths, "▀", func(r int, glyph string) {173- for x := x0; x < x1; x++ {171+ lo, hi := min(zero, p.sc.pos(v)), max(zero, p.sc.pos(v))172+ for r := int(math.Floor(lo)); float64(r) < hi; r++ {173+ // Below the axis, bars fill from the top.174+ glyph := barGlyph(lo, hi, r, v >= 0, lowerEighths, "▀")175+ for x := x0; glyph != "" && x < x1; x++ {174176 g.set(x, p.axisRow-1-r, glyph, SeriesRole(j))175177 }176- })178+ }177179 }178180 }179181 }