diff --git a/bar_chart.go b/bar_chart.go
index 797f710..8826ffb 100644
--- a/bar_chart.go
+++ b/bar_chart.go
@@ -93,9 +93,7 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
markPointPainter := NewMarkPointPainter(seriesPainter)
markLinePainter := NewMarkLinePainter(seriesPainter)
- labelPainter := NewSeriesLabelPainter(seriesPainter)
rendererList := []Renderer{
- labelPainter,
markPointPainter,
markLinePainter,
}
@@ -106,6 +104,18 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
divideValues := xRange.AutoDivide()
points := make([]Point, len(series.Data))
+ var labelPainter *SeriesLabelPainter
+ if series.Label.Show {
+ labelPainter = NewSeriesLabelPainter(SeriesLabelPainterParams{
+ P: seriesPainter,
+ SeriesNames: seriesNames,
+ Label: series.Label,
+ Theme: opt.Theme,
+ Font: opt.Font,
+ })
+ rendererList = append(rendererList, labelPainter)
+ }
+
for j, item := range series.Data {
if j >= xRange.divideCount {
continue
@@ -144,29 +154,14 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
Y: top,
}
// 如果label不需要展示,则返回
- if !series.Label.Show {
+ if labelPainter == nil {
continue
}
- distance := series.Label.Distance
- if distance == 0 {
- distance = 5
- }
- text := NewValueLabelFormatter(seriesNames, series.Label.Formatter)(index, item.Value, -1)
- labelStyle := Style{
- FontColor: theme.GetTextColor(),
- FontSize: labelFontSize,
- Font: opt.Font,
- }
- if !series.Label.Color.IsZero() {
- labelStyle.FontColor = series.Label.Color
- }
-
- textBox := seriesPainter.MeasureText(text)
labelPainter.Add(LabelValue{
- Text: text,
- Style: labelStyle,
- X: x + (barWidth-textBox.Width())>>1,
- Y: barMaxHeight - h - distance,
+ Index: index,
+ Value: item.Value,
+ X: x + barWidth>>1,
+ Y: barMaxHeight - h,
})
}
diff --git a/bar_chart_test.go b/bar_chart_test.go
index bee0583..e1522d6 100644
--- a/bar_chart_test.go
+++ b/bar_chart_test.go
@@ -102,7 +102,7 @@ func TestBarChart(t *testing.T) {
}
return p.Bytes()
},
- result: "",
+ result: "",
},
}
diff --git a/line_chart.go b/line_chart.go
index bf39ae2..26f94a4 100644
--- a/line_chart.go
+++ b/line_chart.go
@@ -97,9 +97,7 @@ func (l *lineChart) render(result *defaultRenderResult, seriesList SeriesList) (
}
markPointPainter := NewMarkPointPainter(seriesPainter)
markLinePainter := NewMarkLinePainter(seriesPainter)
- labelPainter := NewSeriesLabelPainter(seriesPainter)
rendererList := []Renderer{
- labelPainter,
markPointPainter,
markLinePainter,
}
@@ -108,7 +106,6 @@ func (l *lineChart) render(result *defaultRenderResult, seriesList SeriesList) (
strokeWidth = defaultStrokeWidth
}
seriesNames := seriesList.Names()
- theme := opt.Theme
for index := range seriesList {
series := seriesList[index]
seriesColor := opt.Theme.GetSeriesColor(series.index)
@@ -119,6 +116,17 @@ func (l *lineChart) render(result *defaultRenderResult, seriesList SeriesList) (
yRange := result.axisRanges[series.AxisIndex]
points := make([]Point, 0)
+ var labelPainter *SeriesLabelPainter
+ if series.Label.Show {
+ labelPainter = NewSeriesLabelPainter(SeriesLabelPainterParams{
+ P: seriesPainter,
+ SeriesNames: seriesNames,
+ Label: series.Label,
+ Theme: opt.Theme,
+ Font: opt.Font,
+ })
+ rendererList = append(rendererList, labelPainter)
+ }
for i, item := range series.Data {
h := yRange.getRestHeight(item.Value)
if item.Value == nullValue {
@@ -131,29 +139,14 @@ func (l *lineChart) render(result *defaultRenderResult, seriesList SeriesList) (
points = append(points, p)
// 如果label不需要展示,则返回
- if !series.Label.Show {
+ if labelPainter == nil {
continue
}
- distance := series.Label.Distance
- if distance == 0 {
- distance = 5
- }
- text := NewValueLabelFormatter(seriesNames, series.Label.Formatter)(index, item.Value, -1)
- labelStyle := Style{
- FontColor: theme.GetTextColor(),
- FontSize: labelFontSize,
- Font: opt.Font,
- }
- if !series.Label.Color.IsZero() {
- labelStyle.FontColor = series.Label.Color
- }
-
- textBox := seriesPainter.MeasureText(text)
labelPainter.Add(LabelValue{
- Text: text,
- Style: labelStyle,
- X: p.X - textBox.Width()>>1,
- Y: p.Y - distance,
+ Index: index,
+ Value: item.Value,
+ X: p.X,
+ Y: p.Y,
})
}
// 如果需要填充区域
diff --git a/series_label.go b/series_label.go
index c1850bb..57bd1bf 100644
--- a/series_label.go
+++ b/series_label.go
@@ -22,29 +22,80 @@
package charts
-import "github.com/wcharczuk/go-chart/v2"
+import (
+ "github.com/golang/freetype/truetype"
+ "github.com/wcharczuk/go-chart/v2"
+)
-type LabelValue struct {
+type labelRenderValue struct {
Text string
Style Style
X int
Y int
}
-type SeriesLabelPainter struct {
- p *Painter
- values []LabelValue
+type LabelValue struct {
+ Index int
+ Value float64
+ X int
+ Y int
}
-func NewSeriesLabelPainter(p *Painter) *SeriesLabelPainter {
+type SeriesLabelPainter struct {
+ p *Painter
+ seriesNames []string
+ label *SeriesLabel
+ theme ColorPalette
+ font *truetype.Font
+ values []labelRenderValue
+}
+
+type SeriesLabelPainterParams struct {
+ P *Painter
+ SeriesNames []string
+ Label SeriesLabel
+ Theme ColorPalette
+ Font *truetype.Font
+}
+
+func NewSeriesLabelPainter(params SeriesLabelPainterParams) *SeriesLabelPainter {
return &SeriesLabelPainter{
- p: p,
- values: make([]LabelValue, 0),
+ p: params.P,
+ seriesNames: params.SeriesNames,
+ label: ¶ms.Label,
+ theme: params.Theme,
+ font: params.Font,
+ values: make([]labelRenderValue, 0),
}
}
func (o *SeriesLabelPainter) Add(value LabelValue) {
- o.values = append(o.values, value)
+ label := o.label
+ distance := label.Distance
+ if distance == 0 {
+ distance = 5
+ }
+ text := NewValueLabelFormatter(o.seriesNames, label.Formatter)(value.Index, value.Value, -1)
+ labelStyle := Style{
+ FontColor: o.theme.GetTextColor(),
+ FontSize: labelFontSize,
+ Font: o.font,
+ }
+ 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,
+ }
+ if textBox.Width()%2 != 0 {
+ renderValue.X++
+ }
+ o.values = append(o.values, renderValue)
}
func (o *SeriesLabelPainter) Render() (Box, error) {