Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ jobs:
# Required: the version of golangci-lint is required and must be specified without patch version:
# we always use the latest patch version.
version: v1.34
args: --timeout=5m
77 changes: 69 additions & 8 deletions axis.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,41 @@ func (a horizontalAxis) draw(c draw.Canvas) {
}

// GlyphBoxes returns the GlyphBoxes for the tick labels.
func (a horizontalAxis) GlyphBoxes(*Plot) []GlyphBox {
var boxes []GlyphBox
for _, t := range a.Tick.Marker.Ticks(a.Min, a.Max) {
func (a horizontalAxis) GlyphBoxes(p *Plot) []GlyphBox {
var (
boxes []GlyphBox
yoff font.Length
)

if a.Label.Text != "" {
x := a.Norm(p.X.Max)
switch a.Label.Position {
case draw.PosCenter:
x = a.Norm(0.5 * (p.X.Max + p.X.Min))
case draw.PosRight:
x -= a.Norm(0.5 * a.Label.TextStyle.Width(a.Label.Text).Points()) // FIXME(sbinet): want data coordinates
}
descent := a.Label.TextStyle.FontExtents().Descent
boxes = append(boxes, GlyphBox{
X: x,
Rectangle: a.Label.TextStyle.Rectangle(a.Label.Text).Add(vg.Point{Y: yoff + descent}),
})
yoff += a.Label.TextStyle.Height(a.Label.Text)
yoff += a.Label.Padding
}

var (
marks = a.Tick.Marker.Ticks(a.Min, a.Max)
height = tickLabelHeight(a.Tick.Label, marks)
descent = a.Tick.Label.FontExtents().Descent
)
for _, t := range marks {
if t.IsMinor() {
continue
}
box := GlyphBox{
X: a.Norm(t.Value),
Rectangle: a.Tick.Label.Rectangle(t.Label),
Rectangle: a.Tick.Label.Rectangle(t.Label).Add(vg.Point{Y: yoff + height + descent}),
}
boxes = append(boxes, box)
}
Expand Down Expand Up @@ -396,15 +422,50 @@ func (a verticalAxis) draw(c draw.Canvas) {
}

// GlyphBoxes returns the GlyphBoxes for the tick labels
func (a verticalAxis) GlyphBoxes(*Plot) []GlyphBox {
var boxes []GlyphBox
for _, t := range a.Tick.Marker.Ticks(a.Min, a.Max) {
func (a verticalAxis) GlyphBoxes(p *Plot) []GlyphBox {
var (
boxes []GlyphBox
xoff font.Length
)

if a.Label.Text != "" {
yoff := a.Norm(p.Y.Max)
switch a.Label.Position {
case draw.PosCenter:
yoff = a.Norm(0.5 * (p.Y.Max + p.Y.Min))
case draw.PosTop:
yoff -= a.Norm(0.5 * a.Label.TextStyle.Width(a.Label.Text).Points()) // FIXME(sbinet): want data coordinates
}

sty := a.Label.TextStyle
sty.Rotation += math.Pi / 2

xoff += a.Label.TextStyle.Height(a.Label.Text)
descent := a.Label.TextStyle.FontExtents().Descent
boxes = append(boxes, GlyphBox{
Y: yoff,
Rectangle: sty.Rectangle(a.Label.Text).Add(vg.Point{X: xoff - descent}),
})
xoff += descent
xoff += a.Label.Padding
}

marks := a.Tick.Marker.Ticks(a.Min, a.Max)
if w := tickLabelWidth(a.Tick.Label, marks); len(marks) != 0 && w > 0 {
xoff += w
}

var (
ext = a.Tick.Label.FontExtents()
desc = ext.Height - ext.Ascent // descent + linegap
)
for _, t := range marks {
if t.IsMinor() {
continue
}
box := GlyphBox{
Y: a.Norm(t.Value),
Rectangle: a.Tick.Label.Rectangle(t.Label),
Rectangle: a.Tick.Label.Rectangle(t.Label).Add(vg.Point{X: xoff, Y: desc}),
}
boxes = append(boxes, box)
}
Expand Down
2 changes: 1 addition & 1 deletion legend.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (l *Legend) Draw(c draw.Canvas) {

descent := sty.FontExtents().Descent
enth := l.entryHeight()
y := c.Max.Y - enth
y := c.Max.Y - enth - descent
if !l.Top {
y = c.Min.Y + (enth+l.Padding)*(vg.Length(len(l.entries))-1)
}
Expand Down
68 changes: 60 additions & 8 deletions plot.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,13 @@ func (p *Plot) Draw(c draw.Canvas) {
c.SetColor(p.BackgroundColor)
c.Fill(c.Rectangle.Path())
}

if p.Title.Text != "" {
descent := p.Title.TextStyle.FontExtents().Descent
c.FillText(p.Title.TextStyle, vg.Point{X: c.Center().X, Y: c.Max.Y + descent}, p.Title.Text)
_, h, d := p.Title.TextStyle.Handler.Box(p.Title.Text, p.Title.TextStyle.Font)
c.Max.Y -= h + d

rect := p.Title.TextStyle.Rectangle(p.Title.Text)
c.Max.Y -= rect.Size().Y
c.Max.Y -= p.Title.Padding
}

Expand Down Expand Up @@ -179,7 +181,8 @@ func (p *Plot) Draw(c draw.Canvas) {
// the plot data will be drawn.
func (p *Plot) DataCanvas(da draw.Canvas) draw.Canvas {
if p.Title.Text != "" {
da.Max.Y -= p.Title.TextStyle.Height(p.Title.Text) + p.Title.TextStyle.FontExtents().Descent
rect := p.Title.TextStyle.Rectangle(p.Title.Text)
da.Max.Y -= rect.Size().Y
da.Max.Y -= p.Title.Padding
}
p.X.sanitizeRange()
Expand All @@ -191,12 +194,61 @@ func (p *Plot) DataCanvas(da draw.Canvas) draw.Canvas {

// DrawGlyphBoxes draws red outlines around the plot's
// GlyphBoxes. This is intended for debugging.
func (p *Plot) DrawGlyphBoxes(c *draw.Canvas) {
c.SetColor(color.RGBA{R: 255, A: 255})
func (p *Plot) DrawGlyphBoxes(c draw.Canvas) {
dac := p.DataCanvas(c)
sty := draw.LineStyle{
Color: color.RGBA{R: 255, A: 255},
Width: vg.Points(0.5),
}

drawBox := func(c draw.Canvas, b GlyphBox) {
x := c.X(b.X) + b.Rectangle.Min.X
y := c.Y(b.Y) + b.Rectangle.Min.Y
c.StrokeLines(sty, []vg.Point{
{X: x, Y: y},
{X: x + b.Rectangle.Size().X, Y: y},
{X: x + b.Rectangle.Size().X, Y: y + b.Rectangle.Size().Y},
{X: x, Y: y + b.Rectangle.Size().Y},
{X: x, Y: y},
})
}

var title vg.Length
if p.Title.Text != "" {
rect := p.Title.TextStyle.Rectangle(p.Title.Text)
title += rect.Size().Y
title += p.Title.Padding
box := GlyphBox{
Rectangle: rect.Add(vg.Point{
X: c.Center().X,
Y: c.Max.Y,
}),
}
drawBox(c, box)
}

for _, b := range p.GlyphBoxes(p) {
b.Rectangle.Min.X += c.X(b.X)
b.Rectangle.Min.Y += c.Y(b.Y)
c.Stroke(b.Rectangle.Path())
drawBox(dac, b)
}

p.X.sanitizeRange()
p.Y.sanitizeRange()

x := horizontalAxis{p.X}
y := verticalAxis{p.Y}

ywidth := y.size()
xheight := x.size()

cx := padX(p, draw.Crop(c, ywidth, 0, 0, 0))
for _, b := range x.GlyphBoxes(p) {
drawBox(cx, b)
}

cy := padY(p, draw.Crop(c, 0, 0, xheight, 0))
cy.Max.Y -= title
for _, b := range y.GlyphBoxes(p) {
drawBox(cy, b)
}
}

Expand Down
60 changes: 60 additions & 0 deletions plot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,63 @@ func TestIssue514(t *testing.T) {
})
}
}

func TestDrawGlyphBoxes(t *testing.T) {
cmpimg.CheckPlot(func() {
p := plot.New()

p.Title.Text = "My very very very\nlong Title"
p.X.Min = 0
p.X.Max = 10
p.Y.Min = 0
p.Y.Max = 10

p.X.Label.Text = "X-axis"
p.Y.Label.Text = "Y-axis"

f1 := plotter.NewFunction(func(x float64) float64 { return 5 })
f1.LineStyle.Color = color.RGBA{R: 255, A: 255}

f2 := plotter.NewFunction(func(x float64) float64 { return 6 })
f2.LineStyle.Color = color.RGBA{B: 255, A: 255}

labels, err := plotter.NewLabels(plotter.XYLabels{
XYs: []plotter.XY{
{X: 2.5, Y: 2.5},
{X: 7.5, Y: 2.5},
{X: 7.5, Y: 7.5},
{X: 2.5, Y: 7.5},
},
Labels: []string{"Agg", "Bgg", "Cgg", "Dgg"},
})
if err != nil {
t.Fatalf("could not creates labels plotter: %+v", err)
}

p.Add(f1, f2, labels)
p.Add(plotter.NewGrid())

p.Legend.Add("fg1", f1)
p.Legend.Add("fg2", f2)
p.Legend.Top = true

c := vgimg.PngCanvas{
Canvas: vgimg.New(20*vg.Centimeter, 15*vg.Centimeter),
}

d := draw.New(c)
p.Draw(d)
p.DrawGlyphBoxes(d)

buf := new(bytes.Buffer)
_, err = c.WriteTo(buf)
if err != nil {
t.Fatalf("error: %+v", err)
}

err = ioutil.WriteFile("testdata/glyphbox.png", buf.Bytes(), 0644)
if err != nil {
t.Fatalf("could not save plot: %+v", err)
}
}, t, "glyphbox.png")
}
Binary file modified plotter/testdata/barChart2_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/barChart_positiveNegative_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/clippedFilledLine_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/colorBarVertical_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/contour_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/field_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/functions_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/groupedQuartPlot_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/heatMap_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/horizontalBoxPlot_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/horizontalQuartPlot_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/image_plot_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/image_plot_log_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/labels_cnv_coords_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/labels_glyphboxes_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/labels_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/plotLogo_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plotter/testdata/polygon_hexagons_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 35 additions & 35 deletions plotter/testdata/polygon_holes_golden.eps
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%%Creator gonum.org/v1/plot/vg/vgeps
%%Title:
%%BoundingBox: 0 0 100 100
%%CreationDate: 2021-01-13 19:18:09.973243623 +0100 CET m=+3.699589445
%%CreationDate: 2021-08-04 15:18:17.591742993 +0200 CEST m=+1.847419518
%%Orientation: Portrait
%%EndComments

Expand Down Expand Up @@ -57,79 +57,79 @@ stroke
gsave
90 rotate
/LiberationSerif-Regular findfont 12 scalefont setfont
57.652 -9.3867 moveto
56.358 -9.3867 moveto
(Y) show
grestore
15.885 37.924 moveto
(0) show
15.885 59.7 moveto
15.885 58.406 moveto
(2) show
15.885 81.477 moveto
15.885 78.889 moveto
(4) show
newpath
23.385 40.209 moveto
31.385 40.209 lineto
stroke
newpath
23.385 61.985 moveto
31.385 61.985 lineto
23.385 60.691 moveto
31.385 60.691 lineto
stroke
newpath
23.385 83.762 moveto
31.385 83.762 lineto
23.385 81.174 moveto
31.385 81.174 lineto
stroke
newpath
27.385 51.097 moveto
31.385 51.097 lineto
27.385 50.45 moveto
31.385 50.45 lineto
stroke
newpath
27.385 72.874 moveto
31.385 72.874 lineto
27.385 70.933 moveto
31.385 70.933 lineto
stroke
newpath
31.385 40.209 moveto
31.385 83.762 lineto
31.385 81.174 lineto
stroke
0 0 1 setrgbcolor
newpath
37.135 40.209 moveto
97.5 40.209 lineto
97.5 83.762 lineto
37.135 83.762 lineto
97.5 81.174 lineto
37.135 81.174 lineto
closepath
44.68 45.653 moveto
59.772 45.653 lineto
59.772 56.541 lineto
44.68 56.541 lineto
44.68 45.33 moveto
59.772 45.33 lineto
59.772 55.571 lineto
44.68 55.571 lineto
closepath
89.954 67.429 moveto
74.863 67.429 lineto
74.863 78.318 lineto
89.954 78.318 lineto
89.954 65.812 moveto
74.863 65.812 lineto
74.863 76.053 lineto
89.954 76.053 lineto
closepath
fill
0 0 0 setrgbcolor
1 setlinewidth
newpath
37.135 40.209 moveto
97.5 40.209 lineto
97.5 83.762 lineto
37.135 83.762 lineto
97.5 81.174 lineto
37.135 81.174 lineto
37.135 40.209 lineto
stroke
newpath
44.68 45.653 moveto
59.772 45.653 lineto
59.772 56.541 lineto
44.68 56.541 lineto
44.68 45.653 lineto
44.68 45.33 moveto
59.772 45.33 lineto
59.772 55.571 lineto
44.68 55.571 lineto
44.68 45.33 lineto
stroke
newpath
89.954 67.429 moveto
74.863 67.429 lineto
74.863 78.318 lineto
89.954 78.318 lineto
89.954 67.429 lineto
89.954 65.812 moveto
74.863 65.812 lineto
74.863 76.053 lineto
89.954 76.053 lineto
89.954 65.812 lineto
stroke
0 0 1 setrgbcolor
newpath
Expand Down
Binary file modified plotter/testdata/polygon_holes_golden.pdf
Binary file not shown.
Binary file modified plotter/testdata/polygon_holes_golden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading