Skip to content

Commit a3d5993

Browse files
authored
plot,vg/draw: add ability to set the axis label position
Fixes #589.
1 parent e32acf9 commit a3d5993

File tree

5 files changed

+68
-4
lines changed

5 files changed

+68
-4
lines changed

align_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ import (
1313
func TestAlign(t *testing.T) {
1414
cmpimg.CheckPlot(ExampleAlign, t, "align.png")
1515
}
16+
17+
func TestAxisLabels(t *testing.T) {
18+
cmpimg.CheckPlot(ExampleAxis_labelsPosition, t, "axis_labels.png")
19+
}

axis.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ type Axis struct {
4747
// counterclockwise will be added to the label
4848
// text before drawing.
4949
draw.TextStyle
50+
51+
// Position is where the axis label string should be drawn.
52+
// The default value is draw.PosCenter, displaying the label
53+
// at the center of the axis.
54+
// Valid values are [-1,+1], with +1 being the far right/top
55+
// of the axis, and -1 the far left/bottom of the axis.
56+
Position float64
5057
}
5158

5259
// LineStyle is the style of the axis line.
@@ -112,6 +119,7 @@ func makeAxis(o orientation) (Axis, error) {
112119
XAlign: draw.XCenter,
113120
YAlign: draw.YBottom,
114121
}
122+
a.Label.Position = draw.PosCenter
115123

116124
var (
117125
xalign draw.XAlignment
@@ -240,10 +248,20 @@ func (a horizontalAxis) size() (h vg.Length) {
240248

241249
// draw draws the axis along the lower edge of a draw.Canvas.
242250
func (a horizontalAxis) draw(c draw.Canvas) {
243-
y := c.Min.Y
251+
var (
252+
x vg.Length
253+
y = c.Min.Y
254+
)
255+
switch a.Label.Position {
256+
case draw.PosCenter:
257+
x = c.Center().X
258+
case draw.PosRight:
259+
x = c.Max.X
260+
x -= a.Label.Font.Width(a.Label.Text) / 2
261+
}
244262
if a.Label.Text != "" {
245263
y -= a.Label.Font.Extents().Descent
246-
c.FillText(a.Label.TextStyle, vg.Point{X: c.Center().X, Y: y}, a.Label.Text)
264+
c.FillText(a.Label.TextStyle, vg.Point{X: x, Y: y}, a.Label.Text)
247265
y += a.Label.Height(a.Label.Text)
248266
y += a.Label.Padding
249267
}
@@ -327,12 +345,22 @@ func (a verticalAxis) size() (w vg.Length) {
327345

328346
// draw draws the axis along the left side of a draw.Canvas.
329347
func (a verticalAxis) draw(c draw.Canvas) {
330-
x := c.Min.X
348+
var (
349+
x = c.Min.X
350+
y vg.Length
351+
)
331352
if a.Label.Text != "" {
332353
sty := a.Label.TextStyle
333354
sty.Rotation += math.Pi / 2
334355
x += a.Label.Height(a.Label.Text)
335-
c.FillText(sty, vg.Point{X: x, Y: c.Center().Y}, a.Label.Text)
356+
switch a.Label.Position {
357+
case draw.PosCenter:
358+
y = c.Center().Y
359+
case draw.PosTop:
360+
y = c.Max.Y
361+
y -= a.Label.Font.Width(a.Label.Text) / 2
362+
}
363+
c.FillText(sty, vg.Point{X: x, Y: y}, a.Label.Text)
336364
x += -a.Label.Font.Extents().Descent
337365
x += a.Label.Padding
338366
}

example_align_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package plot_test
66

77
import (
8+
"log"
89
"math"
910
"os"
1011

@@ -90,3 +91,25 @@ func ExampleAlign() {
9091
panic(err)
9192
}
9293
}
94+
95+
func ExampleAxis_labelsPosition() {
96+
p, err := plot.New()
97+
if err != nil {
98+
log.Fatalf("could not create plot: %+v", err)
99+
}
100+
101+
p.Title.Text = "Title"
102+
p.X.Label.Text = "X [mm]"
103+
p.Y.Label.Text = "Y [A.U.]"
104+
p.X.Label.Position = draw.PosRight
105+
p.Y.Label.Position = draw.PosTop
106+
p.X.Min = -10
107+
p.X.Max = +10
108+
p.Y.Min = -10
109+
p.Y.Max = +10
110+
111+
err = p.Save(10*vg.Centimeter, 10*vg.Centimeter, "testdata/axis_labels.png")
112+
if err != nil {
113+
log.Fatalf("could not save plot: %+v", err)
114+
}
115+
}

testdata/axis_labels_golden.png

5.81 KB
Loading

vg/draw/canvas.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ const (
7171
YBottom YAlignment = 0
7272
)
7373

74+
// Position specifies the text position.
75+
const (
76+
PosLeft = -1
77+
PosBottom = -1
78+
PosCenter = 0
79+
PosTop = +1
80+
PosRight = +1
81+
)
82+
7483
// LineStyle describes what a line will look like.
7584
type LineStyle struct {
7685
// Color is the color of the line.

0 commit comments

Comments
 (0)