From 6fbc6caa9c2ce1ecb7cc88318b4e0c9461596f3f Mon Sep 17 00:00:00 2001 From: Will Charczuk Date: Sat, 27 Aug 2016 13:45:38 -0700 Subject: [PATCH] axes label example and thin legend. --- _examples/axes_labels/output.png | Bin 0 -> 23752 bytes _examples/request_timings/main.go | 7 +- legend.go | 107 ++++++++++++++++++++++++++++-- 3 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 _examples/axes_labels/output.png diff --git a/_examples/axes_labels/output.png b/_examples/axes_labels/output.png new file mode 100644 index 0000000000000000000000000000000000000000..5f93731ea173988cdf420d7c5874e501033f9aaa GIT binary patch literal 23752 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 0 { - + label = labels[x] + if len(label) > 0 { if legendCount > 0 { ycursor += DefaultMinimumTickVerticalSpacing } - tb := r.MeasureText(labels[x]) + tb := r.MeasureText(label) ty := ycursor + tb.Height() - r.Text(labels[x], tx, ty) + r.Text(label, tx, ty) th2 := tb.Height() >> 1 @@ -114,3 +115,101 @@ func Legend(c *Chart, userDefaults ...Style) Renderable { } } } + +// LegendThin is a legend that doesn't obscure the chart area. +func LegendThin(c *Chart, userDefaults ...Style) Renderable { + return func(r Renderer, cb Box, chartDefaults Style) { + legendDefaults := Style{ + FillColor: drawing.ColorWhite, + FontColor: DefaultTextColor, + FontSize: 8.0, + StrokeColor: DefaultAxisColor, + StrokeWidth: DefaultAxisLineWidth, + Padding: Box{ + Top: 2, + Left: 7, + Right: 7, + Bottom: 5, + }, + } + + var legendStyle Style + if len(userDefaults) > 0 { + legendStyle = userDefaults[0].InheritFrom(chartDefaults.InheritFrom(legendDefaults)) + } else { + legendStyle = chartDefaults.InheritFrom(legendDefaults) + } + + r.SetFont(legendStyle.GetFont()) + r.SetFontColor(legendStyle.GetFontColor()) + r.SetFontSize(legendStyle.GetFontSize()) + + var labels []string + var lines []Style + for index, 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().InheritFrom(c.styleDefaultsSeries(index))) + } + } + } + + var textHeight int + var textWidth int + var textBox Box + for x := 0; x < len(labels); x++ { + if len(labels[x]) > 0 { + textBox = r.MeasureText(labels[x]) + textHeight = Math.MaxInt(textBox.Height(), textHeight) + textWidth = Math.MaxInt(textBox.Width(), textWidth) + } + } + + legendBoxHeight := textHeight + legendStyle.Padding.Top + legendStyle.Padding.Bottom + chartPadding := cb.Top + legendYMargin := (chartPadding - legendBoxHeight) >> 1 + + legendBox := Box{ + Left: cb.Left, + Right: cb.Right, + Top: legendYMargin, + Bottom: legendYMargin + legendBoxHeight, + } + + Draw.Box(r, legendBox, legendDefaults) + + r.SetFont(legendStyle.GetFont()) + r.SetFontColor(legendStyle.GetFontColor()) + r.SetFontSize(legendStyle.GetFontSize()) + + lineTextGap := 5 + lineLengthMinimum := 25 + + tx := legendBox.Left + legendStyle.Padding.Left + ty := legendYMargin + legendStyle.Padding.Top + textHeight + var label string + var lx, ly int + th2 := textHeight >> 1 + for index := range labels { + label = labels[index] + if len(label) > 0 { + textBox = r.MeasureText(label) + r.Text(label, tx, ty) + + lx = tx + textBox.Width() + lineTextGap + ly = ty - th2 + + r.SetStrokeColor(lines[index].GetStrokeColor()) + r.SetStrokeWidth(lines[index].GetStrokeWidth()) + r.SetStrokeDashArray(lines[index].GetStrokeDashArray()) + + r.MoveTo(lx, ly) + r.LineTo(lx+lineLengthMinimum, ly) + r.Stroke() + + tx += textBox.Width() + DefaultMinimumTickHorizontalSpacing + lineTextGap + lineLengthMinimum + } + } + } +}