From 0cef99b52483bde932662d2bf980cac58f1d501c Mon Sep 17 00:00:00 2001 From: Will Charczuk Date: Thu, 14 Jul 2016 19:25:40 -0700 Subject: [PATCH] CreateLegend() returns a renderable for a legend. --- drawing_helpers.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drawing_helpers.go b/drawing_helpers.go index 4f094f2..16a22cc 100644 --- a/drawing_helpers.go +++ b/drawing_helpers.go @@ -1,5 +1,7 @@ package chart +import "github.com/wcharczuk/go-chart/drawing" + // DrawLineSeries draws a line series with a renderer. func DrawLineSeries(r Renderer, canvasBox Box, xrange, yrange Range, s Style, vs ValueProvider) { if vs.Len() == 0 { @@ -165,3 +167,83 @@ func DrawTextCentered(r Renderer, text string, x, y int, s Style) { ty := y - (tb.Height() >> 1) r.Text(text, tx, ty) } + +func CreateLegend(c *Chart) Renderable { + return func(r Renderer, cb Box, defaults Style) { + // DEFAULTS + legendPadding := 5 + lineTextGap := 5 + lineLengthMinimum := 25 + + var labels []string + var lines []Style + for _, s := range c.Series { + if s.GetStyle().IsZero() || s.GetStyle().Show { + if _, isAnnotationSeries := s.(AnnotationSeries); !isAnnotationSeries { + labels = append(labels, s.GetName()) + lines = append(lines, s.GetStyle()) + } + } + } + + legend := Box{ + Top: cb.Top, //padding + Left: cb.Left, + } + + legendContent := Box{ + Top: legend.Top + legendPadding, + Left: legend.Left + legendPadding, + } + + r.SetFontColor(DefaultTextColor) + r.SetFontSize(8.0) + + // measure + for x := 0; x < len(labels); x++ { + if len(labels[x]) > 0 { + tb := r.MeasureText(labels[x]) + legendContent.Bottom += (tb.Height() + DefaultMinimumTickVerticalSpacing) + rowRight := tb.Width() + legendContent.Left + lineLengthMinimum + lineTextGap + legendContent.Right = MaxInt(legendContent.Right, rowRight) + } + } + + legend = legend.Grow(legendContent) + DrawBox(r, legend, Style{ + FillColor: drawing.ColorWhite, + StrokeColor: DefaultAxisColor, + StrokeWidth: 1.0, + }) + + legendContent.Right = legend.Right - legendPadding + legendContent.Bottom = legend.Bottom - legendPadding + + ycursor := legendContent.Top + tx := legendContent.Left + for x := 0; x < len(labels); x++ { + if len(labels[x]) > 0 { + tb := r.MeasureText(labels[x]) + ycursor += tb.Height() + + //r.SetFillColor(DefaultTextColor) + r.Text(labels[x], tx, ycursor) + th2 := tb.Height() >> 1 + + lx := tx + tb.Width() + lineTextGap + ly := ycursor - th2 + lx2 := legendContent.Right - legendPadding + + r.SetStrokeColor(lines[x].GetStrokeColor()) + r.SetStrokeWidth(lines[x].GetStrokeWidth()) + r.SetStrokeDashArray(lines[x].GetStrokeDashArray()) + + r.MoveTo(lx, ly) + r.LineTo(lx2, ly) + r.Stroke() + + ycursor += DefaultMinimumTickVerticalSpacing + } + } + } +}