where did my ticks go.

This commit is contained in:
Will Charczuk 2016-07-29 19:35:18 -07:00
parent a008ebe30e
commit e44cdd5600
3 changed files with 123 additions and 28 deletions

View file

@ -13,8 +13,15 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
Background: chart.Style{ Background: chart.Style{
Padding: chart.Box{Top: 50, Left: 50, Right: 50, Bottom: 50}, Padding: chart.Box{Top: 50, Left: 50, Right: 50, Bottom: 50},
}, },
XAxis: chart.Style{
Show: true,
},
YAxis: chart.Style{
Show: true,
},
Bars: []chart.StackedBar{ Bars: []chart.StackedBar{
{ {
Name: "Funnel",
Values: []chart.Value{ Values: []chart.Value{
{Value: 5, Label: "Blue"}, {Value: 5, Label: "Blue"},
{Value: 5, Label: "Green"}, {Value: 5, Label: "Green"},
@ -26,6 +33,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
}, },
}, },
{ {
Name: "Test",
Values: []chart.Value{ Values: []chart.Value{
{Value: 10, Label: "Blue"}, {Value: 10, Label: "Blue"},
{Value: 5, Label: "Green"}, {Value: 5, Label: "Green"},

View file

@ -2,6 +2,7 @@ package chart
import ( import (
"errors" "errors"
"fmt"
"io" "io"
"github.com/golang/freetype/truetype" "github.com/golang/freetype/truetype"
@ -17,7 +18,7 @@ type StackedBar struct {
// GetWidth returns the width of the bar. // GetWidth returns the width of the bar.
func (sb StackedBar) GetWidth() int { func (sb StackedBar) GetWidth() int {
if sb.Width == 0 { if sb.Width == 0 {
return 20 return 50
} }
return sb.Width return sb.Width
} }
@ -34,6 +35,9 @@ type StackedBarChart struct {
Background Style Background Style
Canvas Style Canvas Style
XAxis Style
YAxis Style
BarSpacing int BarSpacing int
Font *truetype.Font Font *truetype.Font
@ -108,6 +112,8 @@ func (sbc StackedBarChart) Render(rp RendererProvider, w io.Writer) error {
canvasBox := sbc.getAdjustedCanvasBox(sbc.getDefaultCanvasBox()) canvasBox := sbc.getAdjustedCanvasBox(sbc.getDefaultCanvasBox())
sbc.drawBars(r, canvasBox) sbc.drawBars(r, canvasBox)
sbc.drawXAxis(r, canvasBox)
sbc.drawYAxis(r, canvasBox)
sbc.drawTitle(r) sbc.drawTitle(r)
for _, a := range sbc.Elements { for _, a := range sbc.Elements {
@ -126,8 +132,8 @@ func (sbc StackedBarChart) drawBars(r Renderer, canvasBox Box) {
} }
func (sbc StackedBarChart) drawBar(r Renderer, canvasBox Box, xoffset int, bar StackedBar) int { func (sbc StackedBarChart) drawBar(r Renderer, canvasBox Box, xoffset int, bar StackedBar) int {
bxl := xoffset bxl := xoffset + Math.AbsInt(bar.GetWidth()>>1-sbc.GetBarSpacing()>>1)
bxr := xoffset + bar.GetWidth() bxr := bxl + bar.GetWidth()
normalizedBarComponents := Values(bar.Values).Normalize() normalizedBarComponents := Values(bar.Values).Normalize()
yoffset := canvasBox.Top yoffset := canvasBox.Top
@ -141,22 +147,71 @@ func (sbc StackedBarChart) drawBar(r Renderer, canvasBox Box, xoffset int, bar S
return bxr return bxr
} }
func (sbc StackedBarChart) drawXAxis(r Renderer, canvasBox Box) {
if sbc.XAxis.Show {
axisStyle := sbc.XAxis.InheritFrom(sbc.styleDefaultsAxes())
axisStyle.WriteToRenderer(r)
r.MoveTo(canvasBox.Left, canvasBox.Bottom)
r.LineTo(canvasBox.Right, canvasBox.Bottom)
r.Stroke()
r.MoveTo(canvasBox.Left, canvasBox.Bottom)
r.LineTo(canvasBox.Left, canvasBox.Bottom+DefaultVerticalTickHeight)
r.Stroke()
cursor := canvasBox.Left
for _, bar := range sbc.Bars {
spacing := (sbc.GetBarSpacing() >> 1)
barLabelBox := Box{
Top: canvasBox.Bottom + DefaultXAxisMargin,
Left: cursor,
Right: cursor + bar.GetWidth() + spacing,
Bottom: sbc.GetHeight(),
}
if len(bar.Name) > 0 {
Draw.TextWithin(r, bar.Name, barLabelBox, axisStyle)
}
axisStyle.WriteToRenderer(r)
r.MoveTo(barLabelBox.Right, canvasBox.Bottom)
r.LineTo(barLabelBox.Right, canvasBox.Bottom+DefaultVerticalTickHeight)
r.Stroke()
cursor += bar.GetWidth() + spacing
}
}
}
func (sbc StackedBarChart) drawYAxis(r Renderer, canvasBox Box) {
if sbc.YAxis.Show {
axisStyle := sbc.YAxis.InheritFrom(sbc.styleDefaultsAxes())
axisStyle.WriteToRenderer(r)
r.MoveTo(canvasBox.Right, canvasBox.Top)
r.LineTo(canvasBox.Right, canvasBox.Bottom)
r.Stroke()
r.MoveTo(canvasBox.Right, canvasBox.Bottom)
r.LineTo(canvasBox.Right+DefaultHorizontalTickWidth, canvasBox.Bottom)
r.Stroke()
ticks := Sequence.Float64(1.0, 0.0, 0.2)
for _, t := range ticks {
ty := canvasBox.Bottom - int(t*float64(canvasBox.Height()))
r.MoveTo(canvasBox.Right, ty)
r.LineTo(canvasBox.Right+DefaultHorizontalTickWidth, ty)
r.Stroke()
text := fmt.Sprintf("%0.0f%%", t*100)
Draw.Text(r, text, canvasBox.Right+DefaultYAxisMargin, ty, axisStyle)
}
}
}
func (sbc StackedBarChart) drawTitle(r Renderer) { func (sbc StackedBarChart) drawTitle(r Renderer) {
if len(sbc.Title) > 0 && sbc.TitleStyle.Show { if len(sbc.Title) > 0 && sbc.TitleStyle.Show {
r.SetFont(sbc.TitleStyle.GetFont(sbc.GetFont())) Draw.TextWithin(r, sbc.Title, sbc.Box(), sbc.styleDefaultsTitle())
r.SetFontColor(sbc.TitleStyle.GetFontColor(DefaultTextColor))
titleFontSize := sbc.TitleStyle.GetFontSize(DefaultTitleFontSize)
r.SetFontSize(titleFontSize)
textBox := r.MeasureText(sbc.Title)
textWidth := textBox.Width()
textHeight := textBox.Height()
titleX := (sbc.GetWidth() >> 1) - (textWidth >> 1)
titleY := sbc.TitleStyle.Padding.GetTop(DefaultTitleTop) + textHeight
r.Text(sbc.Title, titleX, titleY)
} }
} }
@ -173,22 +228,22 @@ func (sbc StackedBarChart) getAdjustedCanvasBox(canvasBox Box) Box {
} }
} }
return canvasBox.OuterConstrain(sbc.Box(), Box{ return Box{
Top: canvasBox.Top, Top: canvasBox.Top,
Left: canvasBox.Left, Left: canvasBox.Left,
Right: canvasBox.Left + totalWidth, Right: canvasBox.Left + totalWidth,
Bottom: canvasBox.Bottom, Bottom: canvasBox.Bottom,
}) }
} }
// Box returns the chart bounds as a box. // Box returns the chart bounds as a box.
func (sbc StackedBarChart) Box() Box { func (sbc StackedBarChart) Box() Box {
dpr := sbc.Background.Padding.GetRight(DefaultBackgroundPadding.Right) dpr := sbc.Background.Padding.GetRight(10)
dpb := sbc.Background.Padding.GetBottom(DefaultBackgroundPadding.Bottom) dpb := sbc.Background.Padding.GetBottom(50)
return Box{ return Box{
Top: sbc.Background.Padding.GetTop(DefaultBackgroundPadding.Top), Top: 20,
Left: sbc.Background.Padding.GetLeft(DefaultBackgroundPadding.Left), Left: 20,
Right: sbc.GetWidth() - dpr, Right: sbc.GetWidth() - dpr,
Bottom: sbc.GetHeight() - dpb, Bottom: sbc.GetHeight() - dpb,
} }
@ -202,6 +257,42 @@ func (sbc StackedBarChart) styleDefaultsStackedBarValue(index int) Style {
} }
} }
func (sbc StackedBarChart) styleDefaultsTitle() Style {
return sbc.TitleStyle.InheritFrom(Style{
FontColor: DefaultTextColor,
Font: sbc.GetFont(),
FontSize: sbc.getTitleFontSize(),
TextHorizontalAlign: TextHorizontalAlignCenter,
TextVerticalAlign: TextVerticalAlignTop,
TextWrap: TextWrapWord,
})
}
func (sbc StackedBarChart) getTitleFontSize() float64 {
effectiveDimension := Math.MinInt(sbc.GetWidth(), sbc.GetHeight())
if effectiveDimension >= 2048 {
return 48
} else if effectiveDimension >= 1024 {
return 24
} else if effectiveDimension >= 512 {
return 18
} else if effectiveDimension >= 256 {
return 12
}
return 10
}
func (sbc StackedBarChart) styleDefaultsAxes() Style {
return Style{
StrokeColor: DefaultAxisColor,
Font: sbc.GetFont(),
FontSize: DefaultAxisFontSize,
FontColor: DefaultAxisColor,
TextHorizontalAlign: TextHorizontalAlignCenter,
TextVerticalAlign: TextVerticalAlignTop,
TextWrap: TextWrapWord,
}
}
func (sbc StackedBarChart) styleDefaultsElements() Style { func (sbc StackedBarChart) styleDefaultsElements() Style {
return Style{ return Style{
Font: sbc.GetFont(), Font: sbc.GetFont(),

View file

@ -1,9 +1,6 @@
package chart package chart
import ( import "strings"
"fmt"
"strings"
)
// TextHorizontalAlign is an enum for the horizontal alignment options. // TextHorizontalAlign is an enum for the horizontal alignment options.
type textHorizontalAlign int type textHorizontalAlign int
@ -74,7 +71,6 @@ func (t text) WrapFit(r Renderer, value string, width int, style Style) []string
case TextWrapWord: case TextWrapWord:
return t.WrapFitWord(r, value, width, style) return t.WrapFitWord(r, value, width, style)
} }
fmt.Printf("text wrap: %#v\n", style.TextWrap)
return []string{value} return []string{value}
} }