From 126244ba520cbd7916db6e5b619a47195c69833d Mon Sep 17 00:00:00 2001 From: vicanso Date: Fri, 4 Feb 2022 10:05:58 +0800 Subject: [PATCH] feat: support subtext for title --- axis.go | 6 ++--- chart.go | 24 +++++++++++++++---- title.go | 72 +++++++++++++++++++++++++++++++++++++++----------------- util.go | 7 ++++++ xaxis.go | 2 +- 5 files changed, 81 insertions(+), 30 deletions(-) diff --git a/axis.go b/axis.go index 7f3ba4b..ba0604e 100644 --- a/axis.go +++ b/axis.go @@ -256,7 +256,7 @@ func (a *axis) axisTick(opt *axisOption) { } labelMargin := style.GetLabelMargin() tickShow := true - if style.TickShow != nil && !*style.TickShow { + if isFalse(style.TickShow) { tickShow = false } @@ -364,7 +364,7 @@ func (a *axis) measureAxis() int { func (a *axis) Render() { style := a.style - if style.Show != nil && !*style.Show { + if isFalse(style.Show) { return } textMaxWidth, textMaxHeight := a.axisMeasureTextMaxWidthHeight() @@ -373,7 +373,7 @@ func (a *axis) Render() { textMaxHeight: textMaxHeight, boundaryGap: true, } - if style.BoundaryGap != nil && !*style.BoundaryGap { + if isFalse(style.BoundaryGap) { opt.boundaryGap = false } diff --git a/chart.go b/chart.go index 5cd85af..88fc43d 100644 --- a/chart.go +++ b/chart.go @@ -72,11 +72,14 @@ type ChartOption struct { func (o *ChartOption) FillDefault(theme string) { t := NewTheme(theme) - f, _ := chart.GetDefaultFont() - o.Font = f + if o.Font == nil { + o.Font, _ = chart.GetDefaultFont() + } if o.BackgroundColor.IsZero() { o.BackgroundColor = t.GetBackgroundColor() } + + // 标题的默认值 if o.Title.Style.FontColor.IsZero() { o.Title.Style.FontColor = t.GetTextColor() } @@ -84,7 +87,7 @@ func (o *ChartOption) FillDefault(theme string) { o.Title.Style.FontSize = 14 } if o.Title.Style.Font == nil { - o.Title.Style.Font = f + o.Title.Style.Font = o.Font } if o.Title.Style.Padding.IsZero() { o.Title.Style.Padding = chart.Box{ @@ -94,12 +97,23 @@ func (o *ChartOption) FillDefault(theme string) { Bottom: 5, } } + // 副标题 + if o.Title.SubtextStyle.FontColor.IsZero() { + o.Title.SubtextStyle.FontColor = o.Title.Style.FontColor.WithAlpha(180) + } + if o.Title.SubtextStyle.FontSize == 0 { + o.Title.SubtextStyle.FontSize = 10 + } + if o.Title.SubtextStyle.Font == nil { + o.Title.SubtextStyle.Font = o.Font + } + o.Legend.Theme = t if o.Legend.Style.FontSize == 0 { - o.Legend.Style.FontSize =10 + o.Legend.Style.FontSize = 10 } if o.Legend.Style.Font == nil { - o.Legend.Style.Font = f + o.Legend.Style.Font = o.Font } if o.Legend.Style.FontColor.IsZero() { o.Legend.Style.FontColor = t.GetTextColor() diff --git a/title.go b/title.go index a6d9a39..cd8f6ad 100644 --- a/title.go +++ b/title.go @@ -30,39 +30,71 @@ import ( ) type TitleOption struct { - Text string - Style chart.Style - Left string - Top string + Text string + Subtext string + Style chart.Style + SubtextStyle chart.Style + Left string + Top string } type titleMeasureOption struct { width int height int text string + style chart.Style } -func drawTitle(d *Draw, opt *TitleOption) (chart.Box, error) { +func splitTitleText(text string) []string { + arr := strings.Split(text, "\n") + result := make([]string, 0) + for _, v := range arr { + v = strings.TrimSpace(v) + if v == "" { + continue + } + result = append(result, v) + } + return result +} + +func drawTitle(p *Draw, opt *TitleOption) (chart.Box, error) { if len(opt.Text) == 0 { return chart.BoxZero, nil } padding := opt.Style.Padding - titleDraw, err := NewDraw(DrawOption{ - Parent: d, + d, err := NewDraw(DrawOption{ + Parent: p, }, PaddingOption(padding)) if err != nil { return chart.BoxZero, err } - r := titleDraw.Render - opt.Style.GetTextOptions().WriteToRenderer(r) - arr := strings.Split(opt.Text, "\n") + r := d.Render + + measureOptions := make([]titleMeasureOption, 0) + + // 主标题 + for _, v := range splitTitleText(opt.Text) { + measureOptions = append(measureOptions, titleMeasureOption{ + text: v, + style: opt.Style.GetTextOptions(), + }) + } + // 副标题 + for _, v := range splitTitleText(opt.Subtext) { + measureOptions = append(measureOptions, titleMeasureOption{ + text: v, + style: opt.SubtextStyle.GetTextOptions(), + }) + } + textMaxWidth := 0 textMaxHeight := 0 width := 0 - measureOptions := make([]titleMeasureOption, len(arr)) - for index, str := range arr { - textBox := r.MeasureText(str) + for index, item := range measureOptions { + item.style.WriteTextOptionsToRenderer(r) + textBox := r.MeasureText(item.text) w := textBox.Width() h := textBox.Height() @@ -72,15 +104,12 @@ func drawTitle(d *Draw, opt *TitleOption) (chart.Box, error) { if h > textMaxHeight { textMaxHeight = h } - measureOptions[index] = titleMeasureOption{ - text: str, - width: w, - height: h, - } + measureOptions[index].height = h + measureOptions[index].width = w } width = textMaxWidth titleX := 0 - b := titleDraw.Box + b := d.Box switch opt.Left { case PositionRight: titleX = b.Width() - textMaxWidth @@ -102,9 +131,10 @@ func drawTitle(d *Draw, opt *TitleOption) (chart.Box, error) { titleY += value } for _, item := range measureOptions { + item.style.WriteTextOptionsToRenderer(r) x := titleX + (textMaxWidth-item.width)>>1 - titleDraw.text(item.text, x, titleY) - titleY += textMaxHeight + d.text(item.text, x, titleY) + titleY += item.height } height := titleY + padding.Top + padding.Bottom box := padding.Clone() diff --git a/util.go b/util.go index 01590b4..c9c817f 100644 --- a/util.go +++ b/util.go @@ -106,3 +106,10 @@ func convertPercent(value string) float64 { } return float64(v) / 100 } + +func isFalse(flag *bool) bool { + if flag != nil && !*flag { + return true + } + return false +} diff --git a/xaxis.go b/xaxis.go index 8d47ed8..5993796 100644 --- a/xaxis.go +++ b/xaxis.go @@ -56,7 +56,7 @@ func drawXAxis(p *Draw, opt *XAxisOption) (int, *Range, error) { boundary := true max := float64(len(opt.Data)) - if opt.BoundaryGap != nil && !*opt.BoundaryGap { + if isFalse(opt.BoundaryGap) { boundary = false max-- }