diff --git a/axis.go b/axis.go
index 5e33062..9a9508f 100644
--- a/axis.go
+++ b/axis.go
@@ -239,6 +239,10 @@ func (d *Draw) axisTick(opt *axisOption) {
tickCount--
}
labelMargin := style.GetLabelMargin()
+ tickShow := true
+ if opt.style.TickShow != nil && !*opt.style.TickShow {
+ tickShow = false
+ }
tickLengthValue := style.GetTickLength()
labelHeight := labelMargin + opt.textMaxHeight
@@ -254,17 +258,20 @@ func (d *Draw) axisTick(opt *axisOption) {
if style.Position == PositionLeft {
x0 = labelWidth
}
- for _, v := range values {
- x := x0
- y := v
- d.moveTo(x, y)
- d.lineTo(x+tickLengthValue, y)
- r.Stroke()
+ if tickShow {
+ for _, v := range values {
+ x := x0
+ y := v
+ d.moveTo(x, y)
+ d.lineTo(x+tickLengthValue, y)
+ r.Stroke()
+ }
}
// 辅助线
if style.SplitLineShow && !style.SplitLineColor.IsZero() {
r.SetStrokeColor(style.SplitLineColor)
- splitLineWidth := width - labelWidth
+ splitLineWidth := width - labelWidth - tickLengthValue
+ x0 = labelWidth + tickLengthValue
if position == PositionRight {
x0 = 0
splitLineWidth = width - labelWidth - 1
@@ -284,12 +291,14 @@ func (d *Draw) axisTick(opt *axisOption) {
if position == PositionTop {
y0 = labelHeight
}
- for _, v := range values {
- x := v
- y := y0
- d.moveTo(x, y-tickLengthValue)
- d.lineTo(x, y)
- r.Stroke()
+ if tickShow {
+ for _, v := range values {
+ x := v
+ y := y0
+ d.moveTo(x, y-tickLengthValue)
+ d.lineTo(x, y)
+ r.Stroke()
+ }
}
// 辅助线
if style.SplitLineShow && !style.SplitLineColor.IsZero() {
diff --git a/axis_test.go b/axis_test.go
index cfbaec4..06b1a97 100644
--- a/axis_test.go
+++ b/axis_test.go
@@ -140,7 +140,7 @@ func TestAxis(t *testing.T) {
opt.style.BoundaryGap = FalseFlag()
return opt
},
- result: "",
+ result: "",
},
// 文本居中展示
// axis位于left
@@ -150,7 +150,7 @@ func TestAxis(t *testing.T) {
opt.style.Position = PositionLeft
return opt
},
- result: "",
+ result: "",
},
// 文本按起始位置展示
// axis位于right
diff --git a/chart.go b/chart.go
index b768993..e0e9a9a 100644
--- a/chart.go
+++ b/chart.go
@@ -23,17 +23,13 @@
package charts
import (
+ "math"
+
"github.com/dustin/go-humanize"
"github.com/wcharczuk/go-chart/v2"
"github.com/wcharczuk/go-chart/v2/drawing"
)
-type XAxisOption struct {
- BoundaryGap *bool
- Data []string
- // TODO split number
-}
-
type SeriesData struct {
Value float64
Style chart.Style
@@ -43,31 +39,6 @@ type Point struct {
Y int
}
-type Range struct {
- originalMin float64
- originalMax float64
- divideCount int
- Min float64
- Max float64
- Size int
- Boundary bool
-}
-
-func (r *Range) getHeight(value float64) int {
- v := 1 - value/(r.Max-r.Min)
- return int(v * float64(r.Size))
-}
-
-func (r *Range) getWidth(value float64) int {
- v := value / (r.Max - r.Min)
- // 移至居中
- if r.Boundary &&
- r.divideCount != 0 {
- v += 1 / float64(r.divideCount*2)
- }
- return int(v * float64(r.Size))
-}
-
type Series struct {
Type string
Name string
@@ -78,6 +49,7 @@ type Series struct {
type ChartOption struct {
Theme string
+ Title TitleOption
XAxis XAxisOption
Width int
Height int
@@ -87,6 +59,29 @@ type ChartOption struct {
BackgroundColor drawing.Color
}
+func (o *ChartOption) FillDefault(t *Theme) {
+ if o.BackgroundColor.IsZero() {
+ o.BackgroundColor = t.GetBackgroundColor()
+ }
+ if o.Title.Style.FontColor.IsZero() {
+ o.Title.Style.FontColor = t.GetTitleColor()
+ }
+ if o.Title.Style.FontSize == 0 {
+ o.Title.Style.FontSize = 14
+ }
+ if o.Title.Style.Font == nil {
+ o.Title.Style.Font, _ = chart.GetDefaultFont()
+ }
+ if o.Title.Style.Padding.IsZero() {
+ o.Title.Style.Padding = chart.Box{
+ Left: 5,
+ Top: 5,
+ Right: 5,
+ Bottom: 5,
+ }
+ }
+}
+
func (o *ChartOption) getWidth() int {
if o.Width == 0 {
return 600
@@ -102,8 +97,8 @@ func (o *ChartOption) getHeight() int {
}
func (o *ChartOption) getYRange(axisIndex int) Range {
- min := float64(0)
- max := float64(0)
+ min := math.MaxFloat64
+ max := -math.MaxFloat64
for _, series := range o.SeriesList {
if series.YAxisIndex != axisIndex {
@@ -118,18 +113,8 @@ func (o *ChartOption) getYRange(axisIndex int) Range {
}
}
}
- // TODO 对于小数的处理
-
- divideCount := 6
- r := Range{
- originalMin: min,
- originalMax: max,
- Min: float64(int(min * 0.8)),
- Max: max * 1.2,
- divideCount: divideCount,
- }
- value := int((r.Max - r.Min) / float64(divideCount))
- r.Max = float64(int(float64(value*divideCount) + r.Min))
+ // y轴分设置默认划分为6块
+ r := NewRange(min*0.9, max*1.1, 6)
return r
}
diff --git a/draw.go b/draw.go
index e7c37a4..037124b 100644
--- a/draw.go
+++ b/draw.go
@@ -34,6 +34,7 @@ import (
const (
PositionLeft = "left"
PositionRight = "right"
+ PositionCenter = "center"
PositionTop = "top"
PositionBottom = "bottom"
)
diff --git a/line_chart.go b/line_chart.go
index f1eea22..553e9b8 100644
--- a/line_chart.go
+++ b/line_chart.go
@@ -31,78 +31,6 @@ type LineChartOption struct {
ChartOption
}
-const YAxisWidth = 50
-
-func drawXAxis(d *Draw, opt *XAxisOption, theme *Theme) (int, *Range, error) {
- dXAxis, err := NewDraw(
- DrawOption{
- Parent: d,
- },
- PaddingOption(chart.Box{
- Left: YAxisWidth,
- }),
- )
- if err != nil {
- return 0, nil, err
- }
- data := NewAxisDataListFromStringList(opt.Data)
- style := AxisStyle{
- BoundaryGap: opt.BoundaryGap,
- StrokeColor: theme.GetAxisStrokeColor(),
- FontColor: theme.GetAxisStrokeColor(),
- StrokeWidth: 1,
- }
-
- boundary := true
- max := float64(len(opt.Data))
- if opt.BoundaryGap != nil && !*opt.BoundaryGap {
- boundary = false
- max--
- }
-
- dXAxis.Axis(data, style)
- return d.measureAxis(data, style), &Range{
- divideCount: len(opt.Data),
- Min: 0,
- Max: max,
- Size: dXAxis.Box.Width(),
- Boundary: boundary,
- }, nil
-}
-
-func drawYAxis(d *Draw, opt *ChartOption, theme *Theme, xAxisHeight int) (*Range, error) {
- yRange := opt.getYRange(0)
- data := NewAxisDataListFromStringList(yRange.Values())
- style := AxisStyle{
- Position: PositionLeft,
- BoundaryGap: FalseFlag(),
- // StrokeColor: theme.GetAxisStrokeColor(),
- FontColor: theme.GetAxisStrokeColor(),
- StrokeWidth: 1,
- SplitLineColor: theme.GetAxisSplitLineColor(),
- SplitLineShow: true,
- }
- width := d.measureAxis(data, style)
-
- dYAxis, err := NewDraw(
- DrawOption{
- Parent: d,
- Width: d.Box.Width(),
- // 减去x轴的高
- Height: d.Box.Height() - xAxisHeight,
- },
- PaddingOption(chart.Box{
- Left: YAxisWidth - width,
- }),
- )
- if err != nil {
- return nil, err
- }
- dYAxis.Axis(data, style)
- yRange.Size = dYAxis.Box.Height()
- return &yRange, nil
-}
-
func NewLineChart(opt LineChartOption) (*Draw, error) {
d, err := NewDraw(
DrawOption{
@@ -119,27 +47,35 @@ func NewLineChart(opt LineChartOption) (*Draw, error) {
theme := Theme{
mode: opt.Theme,
}
- // 设置背景色
- bg := opt.BackgroundColor
- if bg.IsZero() {
- bg = theme.GetBackgroundColor()
- }
+ opt.FillDefault(&theme)
if opt.Parent == nil {
- d.setBackground(opt.getWidth(), opt.getHeight(), bg)
+ d.setBackground(opt.getWidth(), opt.getHeight(), opt.BackgroundColor)
}
+ // 标题
+ _, titleHeight, err := drawTitle(d, &opt.Title)
+ if err != nil {
+ return nil, err
+ }
+
+ // xAxis
xAxisHeight, xRange, err := drawXAxis(d, &opt.XAxis, &theme)
if err != nil {
return nil, err
}
+
// 暂时仅支持单一yaxis
- yRange, err := drawYAxis(d, &opt.ChartOption, &theme, xAxisHeight)
+ yRange, err := drawYAxis(d, &opt.ChartOption, &theme, xAxisHeight, chart.Box{
+ Top: titleHeight,
+ })
if err != nil {
return nil, err
}
+
sd, err := NewDraw(DrawOption{
Parent: d,
}, PaddingOption(chart.Box{
+ Top: titleHeight,
Left: YAxisWidth,
}))
if err != nil {
@@ -166,9 +102,7 @@ func NewLineChart(opt LineChartOption) (*Draw, error) {
DotFillColor: dotFillColor,
})
}
-
}
- // fmt.Println(yRange)
return d, nil
}
diff --git a/range.go b/range.go
new file mode 100644
index 0000000..c2faf8b
--- /dev/null
+++ b/range.go
@@ -0,0 +1,75 @@
+// MIT License
+
+// Copyright (c) 2022 Tree Xie
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+package charts
+
+import (
+ "math"
+)
+
+type Range struct {
+ divideCount int
+ Min float64
+ Max float64
+ Size int
+ Boundary bool
+}
+
+func NewRange(min, max float64, divideCount int) Range {
+ r := math.Abs(max - min)
+
+ // 最小单位计算
+ unit := 5
+ if r > 100 {
+ unit = 20
+ }
+ unit = int((r/float64(divideCount))/float64(unit))*unit + unit
+
+ if min != 0 {
+ min = float64(int(min/float64(unit)) * unit)
+ // 如果是小于0,int的时候向上取整了,因此调整
+ if min < 0 {
+ min -= float64(unit)
+ }
+ }
+ max = min + float64(unit*divideCount)
+ return Range{
+ Min: min,
+ Max: max,
+ divideCount: divideCount,
+ }
+}
+
+func (r *Range) getHeight(value float64) int {
+ v := 1 - (value-r.Min)/(r.Max-r.Min)
+ return int(v * float64(r.Size))
+}
+
+func (r *Range) getWidth(value float64) int {
+ v := value / (r.Max - r.Min)
+ // 移至居中
+ if r.Boundary &&
+ r.divideCount != 0 {
+ v += 1 / float64(r.divideCount*2)
+ }
+ return int(v * float64(r.Size))
+}
diff --git a/range_test.go b/range_test.go
new file mode 100644
index 0000000..151a0bb
--- /dev/null
+++ b/range_test.go
@@ -0,0 +1,49 @@
+// MIT License
+
+// Copyright (c) 2022 Tree Xie
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+package charts
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRange(t *testing.T) {
+ assert := assert.New(t)
+
+ r := NewRange(0, 8, 6)
+ assert.Equal(0.0, r.Min)
+ assert.Equal(30.0, r.Max)
+
+ r = NewRange(0, 12, 6)
+ assert.Equal(0.0, r.Min)
+ assert.Equal(30.0, r.Max)
+
+ r = NewRange(-13, 18, 6)
+ assert.Equal(-20.0, r.Min)
+ assert.Equal(40.0, r.Max)
+
+ r = NewRange(0, 400, 6)
+ assert.Equal(0.0, r.Min)
+ assert.Equal(480.0, r.Max)
+}
diff --git a/theme.go b/theme.go
index 488e11c..a67dc02 100644
--- a/theme.go
+++ b/theme.go
@@ -120,3 +120,20 @@ func (t *Theme) GetBackgroundColor() drawing.Color {
}
return drawing.ColorWhite
}
+
+func (t *Theme) GetTitleColor() drawing.Color {
+ if t.IsDark() {
+ return drawing.Color{
+ R: 238,
+ G: 241,
+ B: 250,
+ A: 255,
+ }
+ }
+ return drawing.Color{
+ R: 70,
+ G: 70,
+ B: 70,
+ A: 255,
+ }
+}
diff --git a/title.go b/title.go
new file mode 100644
index 0000000..b37c0da
--- /dev/null
+++ b/title.go
@@ -0,0 +1,112 @@
+// MIT License
+
+// Copyright (c) 2022 Tree Xie
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+package charts
+
+import (
+ "strconv"
+ "strings"
+
+ "github.com/wcharczuk/go-chart/v2"
+)
+
+type TitleOption struct {
+ Text string
+ Style chart.Style
+ Left string
+ Top string
+}
+type titleMeasureOption struct {
+ width int
+ height int
+ text string
+}
+
+func drawTitle(d *Draw, opt *TitleOption) (int, int, error) {
+ if len(opt.Text) == 0 {
+ return 0, 0, nil
+ }
+
+ padding := opt.Style.Padding
+ titleDraw, err := NewDraw(DrawOption{
+ Parent: d,
+ }, PaddingOption(padding))
+ if err != nil {
+ return 0, 0, err
+ }
+
+ r := titleDraw.Render
+ opt.Style.GetTextOptions().WriteToRenderer(r)
+ arr := strings.Split(opt.Text, "\n")
+ textMaxWidth := 0
+ textMaxHeight := 0
+ width := 0
+ measureOptions := make([]titleMeasureOption, len(arr))
+ for index, str := range arr {
+ textBox := r.MeasureText(str)
+
+ w := textBox.Width()
+ h := textBox.Height()
+ if w > textMaxWidth {
+ textMaxWidth = w
+ }
+ if h > textMaxHeight {
+ textMaxHeight = h
+ }
+ measureOptions[index] = titleMeasureOption{
+ text: str,
+ width: w,
+ height: h,
+ }
+ }
+ width = textMaxWidth
+ titleX := 0
+ b := titleDraw.Box
+ switch opt.Left {
+ case PositionRight:
+ titleX = b.Width() - textMaxWidth
+ case PositionCenter:
+ titleX = b.Width()>>1 - (textMaxWidth >> 1)
+ default:
+ if strings.HasSuffix(opt.Left, "%") {
+ value, _ := strconv.Atoi(strings.ReplaceAll(opt.Left, "%", ""))
+ titleX = b.Width() * value / 100
+ } else {
+ value, _ := strconv.Atoi(opt.Left)
+ titleX = value
+ }
+ }
+ titleY := 0
+ // TODO TOP 暂只支持数值
+ if opt.Top != "" {
+ value, _ := strconv.Atoi(opt.Top)
+ titleY += value
+ }
+ for _, item := range measureOptions {
+ x := titleX + (textMaxWidth-item.width)>>1
+ titleDraw.text(item.text, x, titleY)
+ titleY += textMaxHeight
+ }
+ height := titleY + padding.Top + padding.Bottom
+
+ return width, height, nil
+}
diff --git a/util.go b/util.go
index 11fc066..041b8c5 100644
--- a/util.go
+++ b/util.go
@@ -67,6 +67,7 @@ func maxInt(values ...int) int {
return result
}
+// measureTextMaxWidthHeight returns maxWidth and maxHeight of text list
func measureTextMaxWidthHeight(textList []string, r chart.Renderer) (int, int) {
maxWidth := 0
maxHeight := 0
diff --git a/xaxis.go b/xaxis.go
new file mode 100644
index 0000000..01ef2d3
--- /dev/null
+++ b/xaxis.go
@@ -0,0 +1,69 @@
+// MIT License
+
+// Copyright (c) 2022 Tree Xie
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+package charts
+
+import "github.com/wcharczuk/go-chart/v2"
+
+type XAxisOption struct {
+ BoundaryGap *bool
+ Data []string
+ // TODO split number
+}
+
+// drawXAxis draws x axis, and returns the height, range of if.
+func drawXAxis(d *Draw, opt *XAxisOption, theme *Theme) (int, *Range, error) {
+ dXAxis, err := NewDraw(
+ DrawOption{
+ Parent: d,
+ },
+ PaddingOption(chart.Box{
+ Left: YAxisWidth,
+ }),
+ )
+ if err != nil {
+ return 0, nil, err
+ }
+ data := NewAxisDataListFromStringList(opt.Data)
+ style := AxisStyle{
+ BoundaryGap: opt.BoundaryGap,
+ StrokeColor: theme.GetAxisStrokeColor(),
+ FontColor: theme.GetAxisStrokeColor(),
+ StrokeWidth: 1,
+ }
+
+ boundary := true
+ max := float64(len(opt.Data))
+ if opt.BoundaryGap != nil && !*opt.BoundaryGap {
+ boundary = false
+ max--
+ }
+
+ dXAxis.Axis(data, style)
+ return d.measureAxis(data, style), &Range{
+ divideCount: len(opt.Data),
+ Min: 0,
+ Max: max,
+ Size: dXAxis.Box.Width(),
+ Boundary: boundary,
+ }, nil
+}
diff --git a/yaxis.go b/yaxis.go
new file mode 100644
index 0000000..1777b02
--- /dev/null
+++ b/yaxis.go
@@ -0,0 +1,62 @@
+// MIT License
+
+// Copyright (c) 2022 Tree Xie
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+package charts
+
+import (
+ "github.com/wcharczuk/go-chart/v2"
+)
+
+const YAxisWidth = 40
+
+func drawYAxis(d *Draw, opt *ChartOption, theme *Theme, xAxisHeight int, padding chart.Box) (*Range, error) {
+ yRange := opt.getYRange(0)
+ data := NewAxisDataListFromStringList(yRange.Values())
+ style := AxisStyle{
+ Position: PositionLeft,
+ BoundaryGap: FalseFlag(),
+ FontColor: theme.GetAxisStrokeColor(),
+ TickShow: FalseFlag(),
+ StrokeWidth: 1,
+ SplitLineColor: theme.GetAxisSplitLineColor(),
+ SplitLineShow: true,
+ }
+ width := d.measureAxis(data, style)
+
+ padding.Left += (YAxisWidth - width)
+
+ dYAxis, err := NewDraw(
+ DrawOption{
+ Parent: d,
+ Width: d.Box.Width(),
+ // 减去x轴的高
+ Height: d.Box.Height() - xAxisHeight,
+ },
+ PaddingOption(padding),
+ )
+ if err != nil {
+ return nil, err
+ }
+ dYAxis.Axis(data, style)
+ yRange.Size = dYAxis.Box.Height()
+ return &yRange, nil
+}