From 962b9abdec2bd6557efa7de5113284e720d6dbc9 Mon Sep 17 00:00:00 2001 From: Jamie Isaacs Date: Fri, 6 Dec 2019 11:22:51 -0800 Subject: [PATCH] Add stacked bar chart value labels (#60) and a horizontal stacked bar chart (#39) (#114) * Add stacked bar chart value labels (#60) * Add horizontal render option to stacked bar chart (#39) * Pulling 100% inside the canvasBox to remain visible. * Use correct margins for YAxis.TextHorizontalAlign: chart.TextHorizontalAlignRight * Fixed Show to Hidden due to 5f42a580a98589e4f0acf5658ce3f0e7bc59df3f --- _examples/horizontal_stacked_bar/main.go | 222 ++++++++++++++++++ _examples/horizontal_stacked_bar/output.png | Bin 0 -> 34357 bytes _examples/stacked_bar_labels/main.go | 221 ++++++++++++++++++ _examples/stacked_bar_labels/output.png | Bin 0 -> 25482 bytes draw.go | 6 +- stacked_bar_chart.go | 245 +++++++++++++++++++- text.go | 2 +- 7 files changed, 688 insertions(+), 8 deletions(-) create mode 100644 _examples/horizontal_stacked_bar/main.go create mode 100644 _examples/horizontal_stacked_bar/output.png create mode 100644 _examples/stacked_bar_labels/main.go create mode 100644 _examples/stacked_bar_labels/output.png diff --git a/_examples/horizontal_stacked_bar/main.go b/_examples/horizontal_stacked_bar/main.go new file mode 100644 index 0000000..4447c03 --- /dev/null +++ b/_examples/horizontal_stacked_bar/main.go @@ -0,0 +1,222 @@ +package main + +import ( + "os" + + "github.com/wcharczuk/go-chart" + "github.com/wcharczuk/go-chart/drawing" +) + +func main() { + chart.DefaultBackgroundColor = chart.ColorTransparent + chart.DefaultCanvasColor = chart.ColorTransparent + + barWidth := 80 + + var ( + colorWhite = drawing.Color{R: 241, G: 241, B: 241, A: 255} + colorMariner = drawing.Color{R: 60, G: 100, B: 148, A: 255} + colorLightSteelBlue = drawing.Color{R: 182, G: 195, B: 220, A: 255} + colorPoloBlue = drawing.Color{R: 126, G: 155, B: 200, A: 255} + colorSteelBlue = drawing.Color{R: 73, G: 120, B: 177, A: 255} + ) + + stackedBarChart := chart.StackedBarChart{ + Title: "Quarterly Sales", + TitleStyle: chart.StyleShow(), + Background: chart.Style{ + Padding: chart.Box{ + Top: 75, + }, + }, + Width: 800, + Height: 600, + XAxis: chart.StyleShow(), + YAxis: chart.StyleShow(), + BarSpacing: 40, + IsHorizontal: true, + Bars: []chart.StackedBar{ + { + Name: "Q1", + Width: barWidth, + Values: []chart.Value{ + { + Label: "32K", + Value: 32, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorMariner, + FontColor: colorWhite, + }, + }, + { + Label: "46K", + Value: 46, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorLightSteelBlue, + FontColor: colorWhite, + }, + }, + { + Label: "48K", + Value: 48, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorPoloBlue, + FontColor: colorWhite, + }, + }, + { + Label: "42K", + Value: 42, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorSteelBlue, + FontColor: colorWhite, + }, + }, + }, + }, + { + Name: "Q2", + Width: barWidth, + Values: []chart.Value{ + { + Label: "45K", + Value: 45, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorMariner, + FontColor: colorWhite, + }, + }, + { + Label: "60K", + Value: 60, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorLightSteelBlue, + FontColor: colorWhite, + }, + }, + { + Label: "62K", + Value: 62, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorPoloBlue, + FontColor: colorWhite, + }, + }, + { + Label: "53K", + Value: 53, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorSteelBlue, + FontColor: colorWhite, + }, + }, + }, + }, + { + Name: "Q3", + Width: barWidth, + Values: []chart.Value{ + { + Label: "54K", + Value: 54, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorMariner, + FontColor: colorWhite, + }, + }, + { + Label: "58K", + Value: 58, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorLightSteelBlue, + FontColor: colorWhite, + }, + }, + { + Label: "55K", + Value: 55, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorPoloBlue, + FontColor: colorWhite, + }, + }, + { + Label: "47K", + Value: 47, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorSteelBlue, + FontColor: colorWhite, + }, + }, + }, + }, + { + Name: "Q4", + Width: barWidth, + Values: []chart.Value{ + { + Label: "46K", + Value: 46, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorMariner, + FontColor: colorWhite, + }, + }, + { + Label: "70K", + Value: 70, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorLightSteelBlue, + FontColor: colorWhite, + }, + }, + { + Label: "74K", + Value: 74, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorPoloBlue, + FontColor: colorWhite, + }, + }, + { + Label: "60K", + Value: 60, + Style: chart.Style{ + StrokeWidth: .01, + FillColor: colorSteelBlue, + FontColor: colorWhite, + }, + }, + }, + }, + }, + } + + pngFile, err := os.Create("output.png") + if err != nil { + panic(err) + } + + if err := stackedBarChart.Render(chart.PNG, pngFile); err != nil { + panic(err) + } + + if err := pngFile.Close(); err != nil { + panic(err) + } +} diff --git a/_examples/horizontal_stacked_bar/output.png b/_examples/horizontal_stacked_bar/output.png new file mode 100644 index 0000000000000000000000000000000000000000..d8ad1232e9d195d834324257a3ad8d8cc0117be7 GIT binary patch literal 34357 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
    U$1UB4o-K@)i?91t&!Uj{e~MTPd0ZsKo)p0 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

    p!uS!7sv3Q2dkK|oOY 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%0Dr>md2l&Dc?8Ml58#|6VY- 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 YZ1#2pRmQzFk6Y4Gf2dZZV)y#L06tYG!2kdN literal 0 HcmV?d00001 diff --git a/draw.go b/draw.go index 9267142..e188079 100644 --- a/draw.go +++ b/draw.go @@ -296,8 +296,10 @@ func (d draw) TextWithin(r Renderer, text string, box Box, style Style) { switch style.GetTextVerticalAlign() { case TextVerticalAlignBottom, TextVerticalAlignBaseline: // i have to build better baseline handling into measure text y = y - linesBox.Height() - case TextVerticalAlignMiddle, TextVerticalAlignMiddleBaseline: - y = (y - linesBox.Height()) >> 1 + case TextVerticalAlignMiddle: + y = y + (box.Height() >> 1) - (linesBox.Height() >> 1) + case TextVerticalAlignMiddleBaseline: + y = y + (box.Height() >> 1) - linesBox.Height() } var tx, ty int diff --git a/stacked_bar_chart.go b/stacked_bar_chart.go index 06db425..10aa545 100644 --- a/stacked_bar_chart.go +++ b/stacked_bar_chart.go @@ -46,6 +46,8 @@ type StackedBarChart struct { Font *truetype.Font defaultFont *truetype.Font + IsHorizontal bool + Bars []StackedBar Elements []Renderable } @@ -113,11 +115,20 @@ func (sbc StackedBarChart) Render(rp RendererProvider, w io.Writer) error { } r.SetDPI(sbc.GetDPI(DefaultDPI)) - canvasBox := sbc.getAdjustedCanvasBox(r, sbc.getDefaultCanvasBox()) - sbc.drawCanvas(r, canvasBox) - sbc.drawBars(r, canvasBox) - sbc.drawXAxis(r, canvasBox) - sbc.drawYAxis(r, canvasBox) + var canvasBox Box + if sbc.IsHorizontal { + canvasBox = sbc.getHorizontalAdjustedCanvasBox(r, sbc.getDefaultCanvasBox()) + sbc.drawCanvas(r, canvasBox) + sbc.drawHorizontalBars(r, canvasBox) + sbc.drawHorizontalXAxis(r, canvasBox) + sbc.drawHorizontalYAxis(r, canvasBox) + } else { + canvasBox = sbc.getAdjustedCanvasBox(r, sbc.getDefaultCanvasBox()) + sbc.drawCanvas(r, canvasBox) + sbc.drawBars(r, canvasBox) + sbc.drawXAxis(r, canvasBox) + sbc.drawYAxis(r, canvasBox) + } sbc.drawTitle(r) for _, a := range sbc.Elements { @@ -139,6 +150,14 @@ func (sbc StackedBarChart) drawBars(r Renderer, canvasBox Box) { } } +func (sbc StackedBarChart) drawHorizontalBars(r Renderer, canvasBox Box) { + yOffset := canvasBox.Top + for _, bar := range sbc.Bars { + sbc.drawHorizontalBar(r, canvasBox, yOffset, bar) + yOffset += sbc.GetBarSpacing() + bar.GetWidth() + } +} + func (sbc StackedBarChart) drawBar(r Renderer, canvasBox Box, xoffset int, bar StackedBar) int { barSpacing2 := sbc.GetBarSpacing() >> 1 bxl := xoffset + barSpacing2 @@ -158,9 +177,85 @@ func (sbc StackedBarChart) drawBar(r Renderer, canvasBox Box, xoffset int, bar S yoffset += barHeight } + // draw the labels + yoffset = canvasBox.Top + var lx, ly int + for index, bv := range normalizedBarComponents { + barHeight := int(math.Ceil(bv.Value * float64(canvasBox.Height()))) + + if len(bv.Label) > 0 { + lx = bxl + ((bxr - bxl) / 2) + ly = yoffset + (barHeight / 2) + + bv.Style.InheritFrom(sbc.styleDefaultsStackedBarValue(index)).WriteToRenderer(r) + tb := r.MeasureText(bv.Label) + lx = lx - (tb.Width() >> 1) + ly = ly + (tb.Height() >> 1) + + if lx < 0 { + lx = 0 + } + if ly < 0 { + lx = 0 + } + + r.Text(bv.Label, lx, ly) + } + yoffset += barHeight + } + return bxr } +func (sbc StackedBarChart) drawHorizontalBar(r Renderer, canvasBox Box, yoffset int, bar StackedBar) { + halfBarSpacing := sbc.GetBarSpacing() >> 1 + + boxTop := yoffset + halfBarSpacing + boxBottom := boxTop + bar.GetWidth() + + normalizedBarComponents := Values(bar.Values).Normalize() + + xOffset := canvasBox.Right + for index, bv := range normalizedBarComponents { + barHeight := int(math.Ceil(bv.Value * float64(canvasBox.Width()))) + barBox := Box{ + Top: boxTop, + Left: MinInt(xOffset-barHeight, canvasBox.Left+DefaultStrokeWidth), + Right: xOffset, + Bottom: boxBottom, + } + Draw.Box(r, barBox, bv.Style.InheritFrom(sbc.styleDefaultsStackedBarValue(index))) + xOffset -= barHeight + } + + // draw the labels + xOffset = canvasBox.Right + var lx, ly int + for index, bv := range normalizedBarComponents { + barHeight := int(math.Ceil(bv.Value * float64(canvasBox.Width()))) + + if len(bv.Label) > 0 { + lx = xOffset - (barHeight / 2) + ly = boxTop + ((boxBottom - boxTop) / 2) + + bv.Style.InheritFrom(sbc.styleDefaultsStackedBarValue(index)).WriteToRenderer(r) + tb := r.MeasureText(bv.Label) + lx = lx - (tb.Width() >> 1) + ly = ly + (tb.Height() >> 1) + + if lx < 0 { + lx = 0 + } + if ly < 0 { + lx = 0 + } + + r.Text(bv.Label, lx, ly) + } + xOffset -= barHeight + } +} + func (sbc StackedBarChart) drawXAxis(r Renderer, canvasBox Box) { if !sbc.XAxis.Hidden { axisStyle := sbc.XAxis.InheritFrom(sbc.styleDefaultsAxes()) @@ -195,6 +290,42 @@ func (sbc StackedBarChart) drawXAxis(r Renderer, canvasBox Box) { } } +func (sbc StackedBarChart) drawHorizontalXAxis(r Renderer, canvasBox Box) { + if !sbc.XAxis.Hidden { + axisStyle := sbc.XAxis.InheritFrom(sbc.styleDefaultsAxes()) + axisStyle.WriteToRenderer(r) + r.MoveTo(canvasBox.Left, canvasBox.Bottom) + r.LineTo(canvasBox.Right, canvasBox.Bottom) + r.Stroke() + + r.MoveTo(canvasBox.Left, canvasBox.Bottom) + r.LineTo(canvasBox.Left, canvasBox.Bottom+DefaultVerticalTickHeight) + r.Stroke() + + ticks := LinearRangeWithStep(0.0, 1.0, 0.2) + for _, t := range ticks { + axisStyle.GetStrokeOptions().WriteToRenderer(r) + tx := canvasBox.Left + int(t*float64(canvasBox.Width())) + r.MoveTo(tx, canvasBox.Bottom) + r.LineTo(tx, canvasBox.Bottom+DefaultVerticalTickHeight) + r.Stroke() + + axisStyle.GetTextOptions().WriteToRenderer(r) + text := fmt.Sprintf("%0.0f%%", t*100) + + textBox := r.MeasureText(text) + textX := tx - (textBox.Width() >> 1) + textY := canvasBox.Bottom + DefaultXAxisMargin + 10 + + if t == 1 { + textX = canvasBox.Right - textBox.Width() + } + + Draw.Text(r, text, textX, textY, axisStyle) + } + } +} + func (sbc StackedBarChart) drawYAxis(r Renderer, canvasBox Box) { if !sbc.YAxis.Hidden { axisStyle := sbc.YAxis.InheritFrom(sbc.styleDefaultsAxes()) @@ -221,7 +352,39 @@ func (sbc StackedBarChart) drawYAxis(r Renderer, canvasBox Box) { tb := r.MeasureText(text) Draw.Text(r, text, canvasBox.Right+DefaultYAxisMargin+5, ty+(tb.Height()>>1), axisStyle) } + } +} +func (sbc StackedBarChart) drawHorizontalYAxis(r Renderer, canvasBox Box) { + if !sbc.YAxis.Hidden { + axisStyle := sbc.YAxis.InheritFrom(sbc.styleDefaultsHorizontalAxes()) + axisStyle.WriteToRenderer(r) + + r.MoveTo(canvasBox.Left, canvasBox.Bottom) + r.LineTo(canvasBox.Left, canvasBox.Top) + r.Stroke() + + r.MoveTo(canvasBox.Left, canvasBox.Bottom) + r.LineTo(canvasBox.Left-DefaultHorizontalTickWidth, canvasBox.Bottom) + r.Stroke() + + cursor := canvasBox.Top + for _, bar := range sbc.Bars { + barLabelBox := Box{ + Top: cursor, + Left: 0, + Right: canvasBox.Left - DefaultYAxisMargin, + Bottom: cursor + bar.GetWidth() + sbc.GetBarSpacing(), + } + if len(bar.Name) > 0 { + Draw.TextWithin(r, bar.Name, barLabelBox, axisStyle) + } + axisStyle.WriteToRenderer(r) + r.MoveTo(canvasBox.Left, barLabelBox.Bottom) + r.LineTo(canvasBox.Left-DefaultHorizontalTickWidth, barLabelBox.Bottom) + r.Stroke() + cursor += bar.GetWidth() + sbc.GetBarSpacing() + } } } @@ -311,6 +474,48 @@ func (sbc StackedBarChart) getAdjustedCanvasBox(r Renderer, canvasBox Box) Box { } +func (sbc StackedBarChart) getHorizontalAdjustedCanvasBox(r Renderer, canvasBox Box) Box { + var totalHeight int + for _, bar := range sbc.Bars { + totalHeight += bar.GetWidth() + sbc.GetBarSpacing() + } + + if !sbc.YAxis.Hidden { + yAxisWidth := DefaultHorizontalTickWidth + + axisStyle := sbc.YAxis.InheritFrom(sbc.styleDefaultsHorizontalAxes()) + axisStyle.WriteToRenderer(r) + + cursor := canvasBox.Top + for _, bar := range sbc.Bars { + if len(bar.Name) > 0 { + barLabelBox := Box{ + Top: cursor, + Left: 0, + Right: canvasBox.Left + DefaultYAxisMargin, + Bottom: cursor + bar.GetWidth() + sbc.GetBarSpacing(), + } + lines := Text.WrapFit(r, bar.Name, barLabelBox.Width(), axisStyle) + linesBox := Text.MeasureLines(r, lines, axisStyle) + + yAxisWidth = MaxInt(linesBox.Height()+(2*DefaultXAxisMargin), yAxisWidth) + } + } + return Box{ + Top: canvasBox.Top, + Left: canvasBox.Left + yAxisWidth, + Right: canvasBox.Right, + Bottom: canvasBox.Top + totalHeight, + } + } + return Box{ + Top: canvasBox.Top, + Left: canvasBox.Left, + Right: canvasBox.Right, + Bottom: canvasBox.Top + totalHeight, + } +} + // Box returns the chart bounds as a box. func (sbc StackedBarChart) Box() Box { dpr := sbc.Background.Padding.GetRight(10) @@ -329,6 +534,9 @@ func (sbc StackedBarChart) styleDefaultsStackedBarValue(index int) Style { StrokeColor: sbc.GetColorPalette().GetSeriesColor(index), StrokeWidth: 3.0, FillColor: sbc.GetColorPalette().GetSeriesColor(index), + FontSize: sbc.getScaledFontSize(), + FontColor: sbc.GetColorPalette().TextColor(), + Font: sbc.GetFont(), } } @@ -343,6 +551,20 @@ func (sbc StackedBarChart) styleDefaultsTitle() Style { }) } +func (sbc StackedBarChart) getScaledFontSize() float64 { + effectiveDimension := MinInt(sbc.GetWidth(), sbc.GetHeight()) + if effectiveDimension >= 2048 { + return 48.0 + } else if effectiveDimension >= 1024 { + return 24.0 + } else if effectiveDimension > 512 { + return 18.0 + } else if effectiveDimension > 256 { + return 12.0 + } + return 10.0 +} + func (sbc StackedBarChart) getTitleFontSize() float64 { effectiveDimension := MinInt(sbc.GetWidth(), sbc.GetHeight()) if effectiveDimension >= 2048 { @@ -368,6 +590,19 @@ func (sbc StackedBarChart) styleDefaultsAxes() Style { TextWrap: TextWrapWord, } } + +func (sbc StackedBarChart) styleDefaultsHorizontalAxes() Style { + return Style{ + StrokeColor: DefaultAxisColor, + Font: sbc.GetFont(), + FontSize: DefaultAxisFontSize, + FontColor: DefaultAxisColor, + TextHorizontalAlign: TextHorizontalAlignCenter, + TextVerticalAlign: TextVerticalAlignMiddle, + TextWrap: TextWrapWord, + } +} + func (sbc StackedBarChart) styleDefaultsElements() Style { return Style{ Font: sbc.GetFont(), diff --git a/text.go b/text.go index 37750ab..0a9dfd0 100644 --- a/text.go +++ b/text.go @@ -46,7 +46,7 @@ const ( TextVerticalAlignBottom TextVerticalAlign = 2 // TextVerticalAlignMiddle aligns the text so that there is an equal amount of space above and below the top and bottom of the ligatures. TextVerticalAlignMiddle TextVerticalAlign = 3 - // TextVerticalAlignMiddleBaseline aligns the text veritcally so that there is an equal number of pixels above and below the baseline of the string. + // TextVerticalAlignMiddleBaseline aligns the text vertically so that there is an equal number of pixels above and below the baseline of the string. TextVerticalAlignMiddleBaseline TextVerticalAlign = 4 // TextVerticalAlignTop alignts the text so that the top of the ligatures are at y-pixel 0 in the container. TextVerticalAlignTop TextVerticalAlign = 5