feat: support subtext for title
This commit is contained in:
parent
dfba1ceafc
commit
126244ba52
5 changed files with 81 additions and 30 deletions
6
axis.go
6
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
|
||||
}
|
||||
|
||||
|
|
|
|||
24
chart.go
24
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()
|
||||
|
|
|
|||
72
title.go
72
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()
|
||||
|
|
|
|||
7
util.go
7
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
|
||||
}
|
||||
|
|
|
|||
2
xaxis.go
2
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--
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue