feat: support subtext for title

This commit is contained in:
vicanso 2022-02-04 10:05:58 +08:00
parent dfba1ceafc
commit 126244ba52
5 changed files with 81 additions and 30 deletions

View file

@ -256,7 +256,7 @@ func (a *axis) axisTick(opt *axisOption) {
} }
labelMargin := style.GetLabelMargin() labelMargin := style.GetLabelMargin()
tickShow := true tickShow := true
if style.TickShow != nil && !*style.TickShow { if isFalse(style.TickShow) {
tickShow = false tickShow = false
} }
@ -364,7 +364,7 @@ func (a *axis) measureAxis() int {
func (a *axis) Render() { func (a *axis) Render() {
style := a.style style := a.style
if style.Show != nil && !*style.Show { if isFalse(style.Show) {
return return
} }
textMaxWidth, textMaxHeight := a.axisMeasureTextMaxWidthHeight() textMaxWidth, textMaxHeight := a.axisMeasureTextMaxWidthHeight()
@ -373,7 +373,7 @@ func (a *axis) Render() {
textMaxHeight: textMaxHeight, textMaxHeight: textMaxHeight,
boundaryGap: true, boundaryGap: true,
} }
if style.BoundaryGap != nil && !*style.BoundaryGap { if isFalse(style.BoundaryGap) {
opt.boundaryGap = false opt.boundaryGap = false
} }

View file

@ -72,11 +72,14 @@ type ChartOption struct {
func (o *ChartOption) FillDefault(theme string) { func (o *ChartOption) FillDefault(theme string) {
t := NewTheme(theme) t := NewTheme(theme)
f, _ := chart.GetDefaultFont() if o.Font == nil {
o.Font = f o.Font, _ = chart.GetDefaultFont()
}
if o.BackgroundColor.IsZero() { if o.BackgroundColor.IsZero() {
o.BackgroundColor = t.GetBackgroundColor() o.BackgroundColor = t.GetBackgroundColor()
} }
// 标题的默认值
if o.Title.Style.FontColor.IsZero() { if o.Title.Style.FontColor.IsZero() {
o.Title.Style.FontColor = t.GetTextColor() o.Title.Style.FontColor = t.GetTextColor()
} }
@ -84,7 +87,7 @@ func (o *ChartOption) FillDefault(theme string) {
o.Title.Style.FontSize = 14 o.Title.Style.FontSize = 14
} }
if o.Title.Style.Font == nil { if o.Title.Style.Font == nil {
o.Title.Style.Font = f o.Title.Style.Font = o.Font
} }
if o.Title.Style.Padding.IsZero() { if o.Title.Style.Padding.IsZero() {
o.Title.Style.Padding = chart.Box{ o.Title.Style.Padding = chart.Box{
@ -94,12 +97,23 @@ func (o *ChartOption) FillDefault(theme string) {
Bottom: 5, 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 o.Legend.Theme = t
if o.Legend.Style.FontSize == 0 { if o.Legend.Style.FontSize == 0 {
o.Legend.Style.FontSize =10 o.Legend.Style.FontSize = 10
} }
if o.Legend.Style.Font == nil { if o.Legend.Style.Font == nil {
o.Legend.Style.Font = f o.Legend.Style.Font = o.Font
} }
if o.Legend.Style.FontColor.IsZero() { if o.Legend.Style.FontColor.IsZero() {
o.Legend.Style.FontColor = t.GetTextColor() o.Legend.Style.FontColor = t.GetTextColor()

View file

@ -30,39 +30,71 @@ import (
) )
type TitleOption struct { type TitleOption struct {
Text string Text string
Style chart.Style Subtext string
Left string Style chart.Style
Top string SubtextStyle chart.Style
Left string
Top string
} }
type titleMeasureOption struct { type titleMeasureOption struct {
width int width int
height int height int
text string 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 { if len(opt.Text) == 0 {
return chart.BoxZero, nil return chart.BoxZero, nil
} }
padding := opt.Style.Padding padding := opt.Style.Padding
titleDraw, err := NewDraw(DrawOption{ d, err := NewDraw(DrawOption{
Parent: d, Parent: p,
}, PaddingOption(padding)) }, PaddingOption(padding))
if err != nil { if err != nil {
return chart.BoxZero, err return chart.BoxZero, err
} }
r := titleDraw.Render r := d.Render
opt.Style.GetTextOptions().WriteToRenderer(r)
arr := strings.Split(opt.Text, "\n") 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 textMaxWidth := 0
textMaxHeight := 0 textMaxHeight := 0
width := 0 width := 0
measureOptions := make([]titleMeasureOption, len(arr)) for index, item := range measureOptions {
for index, str := range arr { item.style.WriteTextOptionsToRenderer(r)
textBox := r.MeasureText(str) textBox := r.MeasureText(item.text)
w := textBox.Width() w := textBox.Width()
h := textBox.Height() h := textBox.Height()
@ -72,15 +104,12 @@ func drawTitle(d *Draw, opt *TitleOption) (chart.Box, error) {
if h > textMaxHeight { if h > textMaxHeight {
textMaxHeight = h textMaxHeight = h
} }
measureOptions[index] = titleMeasureOption{ measureOptions[index].height = h
text: str, measureOptions[index].width = w
width: w,
height: h,
}
} }
width = textMaxWidth width = textMaxWidth
titleX := 0 titleX := 0
b := titleDraw.Box b := d.Box
switch opt.Left { switch opt.Left {
case PositionRight: case PositionRight:
titleX = b.Width() - textMaxWidth titleX = b.Width() - textMaxWidth
@ -102,9 +131,10 @@ func drawTitle(d *Draw, opt *TitleOption) (chart.Box, error) {
titleY += value titleY += value
} }
for _, item := range measureOptions { for _, item := range measureOptions {
item.style.WriteTextOptionsToRenderer(r)
x := titleX + (textMaxWidth-item.width)>>1 x := titleX + (textMaxWidth-item.width)>>1
titleDraw.text(item.text, x, titleY) d.text(item.text, x, titleY)
titleY += textMaxHeight titleY += item.height
} }
height := titleY + padding.Top + padding.Bottom height := titleY + padding.Top + padding.Bottom
box := padding.Clone() box := padding.Clone()

View file

@ -106,3 +106,10 @@ func convertPercent(value string) float64 {
} }
return float64(v) / 100 return float64(v) / 100
} }
func isFalse(flag *bool) bool {
if flag != nil && !*flag {
return true
}
return false
}

View file

@ -56,7 +56,7 @@ func drawXAxis(p *Draw, opt *XAxisOption) (int, *Range, error) {
boundary := true boundary := true
max := float64(len(opt.Data)) max := float64(len(opt.Data))
if opt.BoundaryGap != nil && !*opt.BoundaryGap { if isFalse(opt.BoundaryGap) {
boundary = false boundary = false
max-- max--
} }