-
Notifications
You must be signed in to change notification settings - Fork 204
Description
while working on the glyphboxes issue, I've noticed:
package plotter // import "gonum.org/v1/plot/plotter"
// Labels implements the Plotter interface,
// drawing a set of labels at specified points.
type Labels struct {
XYs
// Labels is the set of labels corresponding
// to each point.
Labels []string
// TextStyle is the style of the label text. Each label
// can have a different text style.
TextStyle []text.Style
// XOffset and YOffset are added directly to the final
// label X and Y location respectively.
XOffset, YOffset vg.Length
}the {X,Y}Offset fields are in vg.Length (so, centimeters and what not).
it's convenient when drawing the labels:
// Plot implements the Plotter interface, drawing labels.
func (l *Labels) Plot(c draw.Canvas, p *plot.Plot) {
trX, trY := p.Transforms(&c)
for i, label := range l.Labels {
pt := vg.Point{X: trX(l.XYs[i].X), Y: trY(l.XYs[i].Y)}
if !c.Contains(pt) {
continue
}
pt.X += l.XOffset
pt.Y += l.YOffset
c.FillText(l.TextStyle[i], pt, label)
}
}but rather inconvenient when trying to compute the glyphbox around each label:
// GlyphBoxes returns a slice of GlyphBoxes,
// one for each of the labels, implementing the
// plot.GlyphBoxer interface.
func (l *Labels) GlyphBoxes(p *plot.Plot) []plot.GlyphBox {
bs := make([]plot.GlyphBox, len(l.Labels))
for i, label := range l.Labels {
pt := l.XYs[i]
pt.X += l.XOffset // error (cannot add float64 and vg.Length)
pt.Y += l.YOffset // ditto
bs[i].X = p.X.Norm(pt.X)
bs[i].Y = p.Y.Norm(pt.Y)
sty := l.TextStyle[i]
bs[i].Rectangle = sty.Rectangle(label)
}
return bs
}(the original code of Labels.GlyphBoxes(...) was missing the x/y-offsets)
there's no way (at least, I couldn't find one) to go from vg units back to "canvas/user" units.
(even less so when one has only a plot.Plot in hands, w/o the corresponding draw.Canvas as one has in Labels.Plot(c,p))
I see two avenues to solve this:
- change
{X,Y}Offsetto data units (and document) - modify the
GlyphBoxessignature (and the accordingplot.GlyphBoxerinterface) to take an additionaldraw.Canvasargument, add a way (toplot.Plot?) to go fromvg.Lengthunits back to "data units".
option a) is probably less wide-ranging a change (only a couple of plotters in gonum/plot are using these fields)
(in any event, adding a method to go from vg.Length units back to "data units" may very well be quite convenient, though. I had the use for such a thing for go-hep/hplot here when trying to set labels in "normalized" coordinates.)
thoughts?