snapshot.

This commit is contained in:
Will Charczuk 2016-09-05 13:26:12 -07:00
parent b78f2327aa
commit 8f56e5939b
10 changed files with 105 additions and 44 deletions

View File

@ -15,12 +15,30 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
YAxis: chart.YAxis{
Style: chart.Style{
Show: true,
TextRotationDegrees: 45.0,
},
Range: &chart.ContinuousRange{
Min: 0.0,
Max: 4.0,
},
TickStyle: chart.Style{
TextRotationDegrees: 45.0,
},
Ticks: []chart.Tick{
{0.0, "0.00"},
{2.0, "2.00"},
{4.0, "4.00"},
{6.0, "6.00"},
{8.0, "Eight"},
{10.0, "Ten"},
},
},
XAxis: chart.XAxis{
Style: chart.Style{
Show: true,
},
TickStyle: chart.Style{
TextRotationDegrees: 45.0,
},
Ticks: []chart.Tick{
{0.0, "0.00"},
{2.0, "2.00"},
@ -39,6 +57,20 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
}
res.Header().Set("Content-Type", "image/png")
graph.Elements = []chart.Renderable{
func(r chart.Renderer, cb chart.Box, defaults chart.Style) {
b := chart.Box{50, 50, 90, 110}
chart.Draw.Box(r, b, chart.Style{
StrokeWidth: 2,
StrokeColor: chart.ColorBlue,
})
chart.Draw.Box(r, b.Rotate(chart.Math.DegreesToRadians(45)), chart.Style{
StrokeWidth: 2,
StrokeColor: chart.ColorRed,
})
},
}
graph.Render(chart.PNG, res)
}

6
box.go
View File

@ -76,8 +76,8 @@ func (b Box) Height() int {
// Center returns the center of the box
func (b Box) Center() (x, y int) {
w, h := b.Width(), b.Height()
return b.Left + w>>1, b.Top + h>>1
w2, h2 := b.Width()>>1, b.Height()>>1
return b.Left + w2, b.Top + h2
}
// Aspect returns the aspect ratio of the box.
@ -227,8 +227,8 @@ func (b Box) Rotate(radians float64) Box {
ltx, lty := Math.RotateCoordinate(cx, cy, b.Left, b.Top, radians)
rbx, rby := Math.RotateCoordinate(cx, cy, b.Right, b.Bottom, radians)
return Box{
Top: lty,
Left: ltx,
Top: lty,
Right: rbx,
Bottom: rby,
}

View File

@ -144,6 +144,20 @@ func TestBoxShift(t *testing.T) {
assert.Equal(12, shifted.Bottom)
}
func TestBoxCenter(t *testing.T) {
assert := assert.New(t)
b := Box{
Top: 10,
Left: 10,
Right: 20,
Bottom: 30,
}
cx, cy := b.Center()
assert.Equal(15, cx)
assert.Equal(20, cy)
}
func TestBoxRotate(t *testing.T) {
assert := assert.New(t)
@ -156,6 +170,6 @@ func TestBoxRotate(t *testing.T) {
rotated := b.Rotate(Math.DegreesToRadians(45))
assert.Equal(1, rotated.Top)
assert.Equal(4, rotated.Left)
assert.Equal(11, rotated.Right)
assert.Equal(15, rotated.Bottom)
assert.Equal(10, rotated.Right)
assert.Equal(14, rotated.Bottom)
}

View File

@ -223,9 +223,9 @@ func (m mathUtil) CirclePoint(cx, cy int, radius, thetaRadians float64) (x, y in
func (m mathUtil) RotateCoordinate(cx, cy, x, y int, thetaRadians float64) (rx, ry int) {
tempX, tempY := float64(x-cx), float64(y-cy)
rotatedX := int(math.Ceil(tempX*math.Cos(thetaRadians) - tempY*math.Sin(thetaRadians)))
rotatedY := int(math.Ceil(tempX*math.Sin(thetaRadians) + tempY*math.Cos(thetaRadians)))
rx = rotatedX + cy
ry = rotatedY + cy
rotatedX := tempX*math.Cos(thetaRadians) - tempY*math.Sin(thetaRadians)
rotatedY := tempX*math.Sin(thetaRadians) + tempY*math.Cos(thetaRadians)
rx = int(rotatedX) + cy
ry = int(rotatedY) + cy
return
}

View File

@ -161,13 +161,24 @@ func TestRadianAdd(t *testing.T) {
assert.Equal(_pi, Math.RadianAdd(_pi, -_2pi))
}
func TestRotateCoordinate(t *testing.T) {
func TestRotateCoordinate90(t *testing.T) {
assert := assert.New(t)
cx, cy := 10, 10
x, y := 5, 5
x, y := 5, 10
rx, ry := Math.RotateCoordinate(cx, cy, x, y, Math.DegreesToRadians(90))
assert.Equal(10, rx)
assert.Equal(5, ry)
}
func TestRotateCoordinate45(t *testing.T) {
assert := assert.New(t)
cx, cy := 10, 10
x, y := 5, 10
rx, ry := Math.RotateCoordinate(cx, cy, x, y, Math.DegreesToRadians(45))
assert.Equal(10, rx)
assert.Equal(3, ry)
assert.Equal(7, rx)
assert.Equal(7, ry)
}

View File

@ -28,7 +28,7 @@ type rasterRenderer struct {
i *image.RGBA
gc *drawing.RasterGraphicContext
rotateRadians float64
rotateRadians *float64
s Style
}
@ -183,34 +183,34 @@ func (rr *rasterRenderer) MeasureText(body string) Box {
Right: int(math.Ceil(r)),
Bottom: int(math.Ceil(b)),
}
if rr.rotateRadians == 0 {
if rr.rotateRadians == nil {
return textBox
}
return textBox.Rotate(rr.rotateRadians)
return textBox.Rotate(*rr.rotateRadians)
}
// SetTextRotation sets a text rotation.
func (rr *rasterRenderer) SetTextRotation(radians float64) {
rr.rotateRadians = radians
rr.rotateRadians = &radians
}
func (rr *rasterRenderer) getCoords(x, y int) (xf, yf int) {
if rr.rotateRadians == 0 {
if rr.rotateRadians == nil {
xf = x
yf = y
return
}
rr.gc.Translate(float64(x), float64(y))
rr.gc.Rotate(rr.rotateRadians)
rr.gc.Rotate(*rr.rotateRadians)
return
}
// ClearTextRotation clears text rotation.
func (rr *rasterRenderer) ClearTextRotation() {
rr.gc.SetMatrixTransform(drawing.NewIdentityMatrix())
rr.rotateRadians = 0
rr.rotateRadians = nil
}
// Save implements the interface method.

View File

@ -33,7 +33,7 @@ type Style struct {
TextVerticalAlign TextVerticalAlign
TextWrap TextWrap
TextLineSpacing int
TextRotationDegrees float64
TextRotationDegrees float64 //0 is unset or normal
}
// IsZero returns if the object is set or not.
@ -262,9 +262,8 @@ func (s Style) WriteToRenderer(r Renderer) {
r.SetFontColor(s.GetFontColor())
r.SetFontSize(s.GetFontSize())
if s.GetTextRotationDegrees() == 0 {
r.ClearTextRotation()
} else {
if s.GetTextRotationDegrees() != 0 {
r.SetTextRotation(Math.DegreesToRadians(s.GetTextRotationDegrees()))
}
}

View File

@ -32,7 +32,6 @@ type vectorRenderer struct {
b *bytes.Buffer
c *canvas
s *Style
r float64
p []string
fc *font.Drawer
}
@ -168,18 +167,22 @@ func (vr *vectorRenderer) MeasureText(body string) (box Box) {
box.Right = w
box.Bottom = int(drawing.PointsToPixels(vr.dpi, vr.s.FontSize))
if vr.c.textTheta == nil {
return
}
box = box.Rotate(*vr.c.textTheta)
}
return
}
// SetTextRotation sets the text rotation.
func (vr *vectorRenderer) SetTextRotation(radians float64) {
vr.c.r = radians
vr.c.textTheta = &radians
}
// ClearTextRotation clears the text rotation.
func (vr *vectorRenderer) ClearTextRotation() {
vr.c.r = 0
vr.c.textTheta = nil
}
// Save saves the renderer's contents to a writer.
@ -198,7 +201,7 @@ func newCanvas(w io.Writer) *canvas {
type canvas struct {
w io.Writer
dpi float64
r float64
textTheta *float64
width int
height int
}
@ -218,10 +221,10 @@ func (c *canvas) Path(d string, style Style) {
}
func (c *canvas) Text(x, y int, body string, style Style) {
if c.r == 0 {
if c.textTheta == nil {
c.w.Write([]byte(fmt.Sprintf(`<text x="%d" y="%d" style="%s">%s</text>`, x, y, c.styleAsSVG(style), body)))
} else {
transform := fmt.Sprintf(` transform="rotate(%0.2f,%d,%d)"`, Math.RadiansToDegrees(c.r), x, y)
transform := fmt.Sprintf(` transform="rotate(%0.2f,%d,%d)"`, Math.RadiansToDegrees(*c.textTheta), x, y)
c.w.Write([]byte(fmt.Sprintf(`<text x="%d" y="%d" style="%s"%s>%s</text>`, x, y, c.styleAsSVG(style), transform, body)))
}
}

View File

@ -9,11 +9,13 @@ import (
type XAxis struct {
Name string
NameStyle Style
Style Style
ValueFormatter ValueFormatter
Range Range
Ticks []Tick
TickStyle Style
Ticks []Tick
TickPosition TickPosition
GridLines []GridLine
@ -139,7 +141,7 @@ func (xa XAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, tick
r.LineTo(tx, canvasBox.Bottom+DefaultVerticalTickHeight)
r.Stroke()
tickStyle.GetTextOptions().WriteToRenderer(r)
xa.TickStyle.InheritFrom(xa.Style.InheritFrom(defaults)).WriteToRenderer(r)
tb := r.MeasureText(t.Label)
switch tp {

View File

@ -22,8 +22,8 @@ type YAxis struct {
TickStyle Style
Ticks []Tick
GridLines []GridLine
GridLines []GridLine
GridMajorStyle Style
GridMinorStyle Style
}
@ -149,11 +149,10 @@ func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, tick
var maxTextWidth int
for _, t := range ticks {
ya.TickStyle.InheritFrom(ya.Style.InheritFrom(defaults)).WriteToRenderer(r)
v := t.Value
ly := canvasBox.Bottom - ra.Translate(v)
ya.TickStyle.InheritFrom(ya.Style.InheritFrom(defaults)).WriteToRenderer(r)
tb := r.MeasureText(t.Label)
if tb.Width() > maxTextWidth {
@ -167,7 +166,8 @@ func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, tick
}
r.Text(t.Label, finalTextX, finalTextY)
r.ClearTextRotation()
ya.Style.InheritFrom(defaults).WriteToRenderer(r)
r.MoveTo(lx, ly)
if ya.AxisType == YAxisPrimary {