diff --git a/bar_chart.go b/bar_chart.go index 19c1664..695b9fd 100644 --- a/bar_chart.go +++ b/bar_chart.go @@ -23,6 +23,8 @@ package charts import ( + "math" + "github.com/golang/freetype/truetype" "github.com/wcharczuk/go-chart/v2" ) @@ -164,11 +166,26 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B if labelPainter == nil { 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{ Index: index, Value: item.Value, X: x + barWidth>>1, - Y: barMaxHeight - h, + Y: y, + // 旋转 + Radians: radians, + FontColor: fontColor, }) } diff --git a/examples/charts/main.go b/examples/charts/main.go index c3bb486..76aa42c 100644 --- a/examples/charts/main.go +++ b/examples/charts/main.go @@ -355,6 +355,10 @@ func indexHandler(w http.ResponseWriter, req *http.Request) { Value: 180, }, }, + Label: charts.SeriesLabel{ + Show: true, + Position: charts.PositionBottom, + }, }, }, }, diff --git a/painter.go b/painter.go index 6743b37..a0f81ed 100644 --- a/painter.go +++ b/painter.go @@ -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) { 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() } diff --git a/series.go b/series.go index 7bd6834..373c7dc 100644 --- a/series.go +++ b/series.go @@ -79,6 +79,8 @@ type SeriesLabel struct { Show bool // Distance to the host graphic element. Distance int + // The position of label + Position string } const ( diff --git a/series_label.go b/series_label.go index 57bd1bf..f2dd40f 100644 --- a/series_label.go +++ b/series_label.go @@ -32,6 +32,8 @@ type labelRenderValue struct { Style Style X int Y int + // 旋转 + Radians float64 } type LabelValue struct { @@ -39,6 +41,10 @@ type LabelValue struct { Value float64 X int Y int + // 旋转 + Radians float64 + // 字体颜色 + FontColor Color } type SeriesLabelPainter struct { @@ -81,19 +87,33 @@ func (o *SeriesLabelPainter) Add(value LabelValue) { FontSize: labelFontSize, Font: o.font, } + if !value.FontColor.IsZero() { + label.Color = value.FontColor + } if !label.Color.IsZero() { labelStyle.FontColor = label.Color } - o.p.OverrideDrawingStyle(labelStyle) - textBox := o.p.MeasureText(text) - renderValue := labelRenderValue{ - Text: text, - Style: labelStyle, - X: value.X - textBox.Width()>>1, - Y: value.Y - distance, + p := o.p + p.OverrideDrawingStyle(labelStyle) + rotated := value.Radians != 0 + if rotated { + p.SetTextRotation(value.Radians) } - if textBox.Width()%2 != 0 { - renderValue.X++ + textBox := p.MeasureText(text) + renderValue := labelRenderValue{ + Text: text, + Style: labelStyle, + X: value.X - textBox.Width()>>1, + 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 { + renderValue.X++ + } } o.values = append(o.values, renderValue) } @@ -101,7 +121,11 @@ func (o *SeriesLabelPainter) Add(value LabelValue) { func (o *SeriesLabelPainter) Render() (Box, error) { for _, item := range o.values { o.p.OverrideTextStyle(item.Style) - o.p.Text(item.Text, item.X, item.Y) + 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) + } } return chart.BoxZero, nil }