feat: support rotate series label
This commit is contained in:
parent
55eca7b0b9
commit
4fc250aefc
5 changed files with 66 additions and 12 deletions
19
bar_chart.go
19
bar_chart.go
|
|
@ -23,6 +23,8 @@
|
||||||
package charts
|
package charts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"github.com/wcharczuk/go-chart/v2"
|
"github.com/wcharczuk/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
@ -164,11 +166,26 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
|
||||||
if labelPainter == nil {
|
if labelPainter == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
y := barMaxHeight - h
|
||||||
|
radians := float64(0)
|
||||||
|
var fontColor Color
|
||||||
|
if series.Label.Position == PositionBottom {
|
||||||
|
y = barMaxHeight
|
||||||
|
radians = -math.Pi / 2
|
||||||
|
if isLightColor(fillColor) {
|
||||||
|
fontColor = defaultLightFontColor
|
||||||
|
} else {
|
||||||
|
fontColor = defaultDarkFontColor
|
||||||
|
}
|
||||||
|
}
|
||||||
labelPainter.Add(LabelValue{
|
labelPainter.Add(LabelValue{
|
||||||
Index: index,
|
Index: index,
|
||||||
Value: item.Value,
|
Value: item.Value,
|
||||||
X: x + barWidth>>1,
|
X: x + barWidth>>1,
|
||||||
Y: barMaxHeight - h,
|
Y: y,
|
||||||
|
// 旋转
|
||||||
|
Radians: radians,
|
||||||
|
FontColor: fontColor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -355,6 +355,10 @@ func indexHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
Value: 180,
|
Value: 180,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Label: charts.SeriesLabel{
|
||||||
|
Show: true,
|
||||||
|
Position: charts.PositionBottom,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -560,7 +560,14 @@ func (p *Painter) Text(body string, x, y int) *Painter {
|
||||||
|
|
||||||
func (p *Painter) TextRotation(body string, x, y int, radians float64) {
|
func (p *Painter) TextRotation(body string, x, y int, radians float64) {
|
||||||
p.render.SetTextRotation(radians)
|
p.render.SetTextRotation(radians)
|
||||||
p.render.Text(body, x, y)
|
p.render.Text(body, x+p.box.Left, y+p.box.Top)
|
||||||
|
p.render.ClearTextRotation()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Painter) SetTextRotation(radians float64) {
|
||||||
|
p.render.SetTextRotation(radians)
|
||||||
|
}
|
||||||
|
func (p *Painter) ClearTextRotation() {
|
||||||
p.render.ClearTextRotation()
|
p.render.ClearTextRotation()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ type SeriesLabel struct {
|
||||||
Show bool
|
Show bool
|
||||||
// Distance to the host graphic element.
|
// Distance to the host graphic element.
|
||||||
Distance int
|
Distance int
|
||||||
|
// The position of label
|
||||||
|
Position string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ type labelRenderValue struct {
|
||||||
Style Style
|
Style Style
|
||||||
X int
|
X int
|
||||||
Y int
|
Y int
|
||||||
|
// 旋转
|
||||||
|
Radians float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type LabelValue struct {
|
type LabelValue struct {
|
||||||
|
|
@ -39,6 +41,10 @@ type LabelValue struct {
|
||||||
Value float64
|
Value float64
|
||||||
X int
|
X int
|
||||||
Y int
|
Y int
|
||||||
|
// 旋转
|
||||||
|
Radians float64
|
||||||
|
// 字体颜色
|
||||||
|
FontColor Color
|
||||||
}
|
}
|
||||||
|
|
||||||
type SeriesLabelPainter struct {
|
type SeriesLabelPainter struct {
|
||||||
|
|
@ -81,27 +87,45 @@ func (o *SeriesLabelPainter) Add(value LabelValue) {
|
||||||
FontSize: labelFontSize,
|
FontSize: labelFontSize,
|
||||||
Font: o.font,
|
Font: o.font,
|
||||||
}
|
}
|
||||||
|
if !value.FontColor.IsZero() {
|
||||||
|
label.Color = value.FontColor
|
||||||
|
}
|
||||||
if !label.Color.IsZero() {
|
if !label.Color.IsZero() {
|
||||||
labelStyle.FontColor = label.Color
|
labelStyle.FontColor = label.Color
|
||||||
}
|
}
|
||||||
o.p.OverrideDrawingStyle(labelStyle)
|
p := o.p
|
||||||
textBox := o.p.MeasureText(text)
|
p.OverrideDrawingStyle(labelStyle)
|
||||||
|
rotated := value.Radians != 0
|
||||||
|
if rotated {
|
||||||
|
p.SetTextRotation(value.Radians)
|
||||||
|
}
|
||||||
|
textBox := p.MeasureText(text)
|
||||||
renderValue := labelRenderValue{
|
renderValue := labelRenderValue{
|
||||||
Text: text,
|
Text: text,
|
||||||
Style: labelStyle,
|
Style: labelStyle,
|
||||||
X: value.X - textBox.Width()>>1,
|
X: value.X - textBox.Width()>>1,
|
||||||
Y: value.Y - distance,
|
Y: value.Y - distance,
|
||||||
|
Radians: value.Radians,
|
||||||
}
|
}
|
||||||
|
if rotated {
|
||||||
|
renderValue.X = value.X + textBox.Width()>>1 - 1
|
||||||
|
p.ClearTextRotation()
|
||||||
|
} else {
|
||||||
if textBox.Width()%2 != 0 {
|
if textBox.Width()%2 != 0 {
|
||||||
renderValue.X++
|
renderValue.X++
|
||||||
}
|
}
|
||||||
|
}
|
||||||
o.values = append(o.values, renderValue)
|
o.values = append(o.values, renderValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *SeriesLabelPainter) Render() (Box, error) {
|
func (o *SeriesLabelPainter) Render() (Box, error) {
|
||||||
for _, item := range o.values {
|
for _, item := range o.values {
|
||||||
o.p.OverrideTextStyle(item.Style)
|
o.p.OverrideTextStyle(item.Style)
|
||||||
|
if item.Radians != 0 {
|
||||||
|
o.p.TextRotation(item.Text, item.X, item.Y, item.Radians)
|
||||||
|
} else {
|
||||||
o.p.Text(item.Text, item.X, item.Y)
|
o.p.Text(item.Text, item.X, item.Y)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return chart.BoxZero, nil
|
return chart.BoxZero, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue