Skip to content

Commit

Permalink
Minor cleanup changes
Browse files Browse the repository at this point in the history
These include some minor changes that were originally in the v0.4.0 branch, but can be provided without any impact in functionality.  Backporting to keep the API change PR as clean as possible.
  • Loading branch information
jentfoo committed Jan 10, 2025
1 parent 2e15c54 commit 1958b50
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 79 deletions.
6 changes: 2 additions & 4 deletions axis.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ func (a *axisPainter) Render() (Box, error) {
return BoxZero, nil
}
top := a.p
theme := opt.Theme
if theme == nil {
theme = top.theme
}
theme := getPreferredTheme(opt.Theme, top.theme)

strokeWidth := opt.StrokeWidth
if strokeWidth == 0 {
Expand Down Expand Up @@ -155,6 +152,7 @@ func (a *axisPainter) Render() (Box, error) {
case PositionTop:
labelPaddingTop = 0
x1 = p.Width()
// TODO - should this reference opt.FontStyle or fontStyle with defaults set
y0 = labelMargin + int(opt.FontStyle.FontSize)
ticksPaddingTop = int(opt.FontStyle.FontSize)
y1 = y0
Expand Down
3 changes: 1 addition & 2 deletions bar_chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
}
// generate marker point by hand
points[j] = Point{
// centered position
X: x + barWidth>>1,
X: x + (barWidth >> 1), // centered position
Y: top,
}
// return if the label does not need to be displayed
Expand Down
9 changes: 4 additions & 5 deletions chart_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import (
)

type ChartOption struct {
// OutputFormat specifies the output type of chart, "svg" or "png", default value is "png"
// OutputFormat specifies the output type of chart, "svg" or "png", default value is "png".
OutputFormat string
// Width is the width of chart, default width is 600.
Width int
// Height is the height of chart, default height is 400
// Height is the height of chart, default height is 400.
Height int
// Theme specifies the colors used for the chart. Built in themes can be loaded using GetTheme with
// "light", "dark", "vivid-light", "vivid-dark", "ant" or "grafana".
Theme ColorPalette
// Padding specifies the padding for chart, default padding is [20, 10, 10, 10]
// Padding specifies the padding for chart, default padding is [20, 10, 10, 10].
Padding Box
// XAxis are options for the x-axis.
XAxis XAxisOption
Expand All @@ -33,7 +33,7 @@ type ChartOption struct {
Box Box
// SeriesList provides the data series.
SeriesList SeriesList
// RadarIndicators are radar indicator list for radar charts
// RadarIndicators are radar indicator list for radar charts.
RadarIndicators []RadarIndicator
// SymbolShow set this to *false or *true (using False() or True()) to force if the symbols should be shown or hidden.
SymbolShow *bool
Expand All @@ -50,7 +50,6 @@ type ChartOption struct {
// Children are child charts to render together.
Children []ChartOption
parent *Painter
// TODO - review how this is set on other Option structs
// ValueFormatter to format numeric values into labels.
ValueFormatter ValueFormatter
}
Expand Down
8 changes: 4 additions & 4 deletions echarts.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,17 +482,17 @@ func renderEcharts(options, outputType string) ([]byte, error) {
}
opt := o.ToOption()
opt.OutputFormat = outputType
if d, err := Render(opt); err != nil {
if p, err := Render(opt); err != nil {
return nil, err
} else {
return d.Bytes()
return p.Bytes()
}
}

func RenderEChartsToPNG(options string) ([]byte, error) {
return renderEcharts(options, "png")
return renderEcharts(options, ChartOutputPNG)
}

func RenderEChartsToSVG(options string) ([]byte, error) {
return renderEcharts(options, "svg")
return renderEcharts(options, ChartOutputSVG)
}
27 changes: 20 additions & 7 deletions painter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,32 @@ import (
"github.com/go-analyze/charts/chartdraw"
)

// ValueFormatter defines a function that can be used to format numeric values.
type ValueFormatter func(float64) string

var defaultValueFormatter = func(val float64) string {
return FormatValueHumanizeShort(val, 2, false)
}

// Painter is the primary struct for drawing charts/graphs.
type Painter struct {
render chartdraw.Renderer
box Box
parent *Painter
style chartdraw.Style
theme ColorPalette
font *truetype.Font
outputFormat string
valueFormatter ValueFormatter
}

// PainterOptions contains parameters for creating a new Painter.
type PainterOptions struct {
// OutputFormat specifies the output type, "svg" or "png", default value is "png"
// OutputFormat specifies the output type, "svg" or "png", default is "png".
OutputFormat string
// Width is the width of the draw painter.
Width int
// Height is the height of the draw painter.
Height int
// TODO - is this the best place for font configuration?
// Font is the font used for rendering text.
Font *truetype.Font
}
Expand Down Expand Up @@ -87,7 +88,7 @@ func PainterPaddingOption(padding Box) PainterOption {
}
}

// PainterBoxOption sets the box of draw painter
// PainterBoxOption sets a specific box for the Painter to draw within.
func PainterBoxOption(box Box) PainterOption {
return func(p *Painter) {
if box.IsZero() {
Expand All @@ -114,7 +115,8 @@ func PainterStyleOption(style chartdraw.Style) PainterOption {
}
}

// PainterThemeOption sets the theme of draw painter
// PainterThemeOption sets a color palette theme default for the Painter.
// This theme is used if the specific chart options don't have a theme set.
func PainterThemeOption(theme ColorPalette) PainterOption {
return func(p *Painter) {
if theme == nil {
Expand Down Expand Up @@ -184,13 +186,13 @@ func (p *Painter) setOptions(opts ...PainterOption) {

func (p *Painter) Child(opt ...PainterOption) *Painter {
child := &Painter{
valueFormatter: p.valueFormatter,
render: p.render,
box: p.box.Clone(),
parent: p,
style: p.style,
theme: p.theme,
font: p.font,
outputFormat: p.outputFormat,
valueFormatter: p.valueFormatter,
}
child.setOptions(opt...)
return child
Expand Down Expand Up @@ -412,14 +414,17 @@ func (p *Painter) Fill() *Painter {
return p
}

// Width returns the drawable width of the painter's box.
func (p *Painter) Width() int {
return p.box.Width()
}

// Height returns the drawable height of the painter's box.
func (p *Painter) Height() int {
return p.box.Height()
}

// MeasureText will provide the rendered size of the text for the provided font style.
func (p *Painter) MeasureText(text string) Box {
return p.render.MeasureText(text)
}
Expand All @@ -439,6 +444,9 @@ func (p *Painter) MeasureTextMaxWidthHeight(textList []string) (int, int) {
return maxWidth, maxHeight
}

// LineStroke draws a line in the graph from point to point with the specified stroke color/width.
// Points with values of math.MaxInt32 will be skipped, resulting in a gap.
// Single or isolated points will result in just a dot being drawn at the point.
func (p *Painter) LineStroke(points []Point) *Painter {
var valid []Point
for _, pt := range points {
Expand All @@ -457,6 +465,8 @@ func (p *Painter) LineStroke(points []Point) *Painter {
return p.Stroke()
}

// drawStraightPath draws a simple (non-curved) path for the given points.
// If dotForSinglePoint is true, single points are drawn as 2px radius dots.
func (p *Painter) drawStraightPath(points []Point, dotForSinglePoint bool) {
pointCount := len(points)
if pointCount == 0 {
Expand Down Expand Up @@ -576,6 +586,8 @@ func (p *Painter) SetBackground(width, height int, color Color, inside ...bool)
p.FillStroke()
return p
}

// MarkLine draws a horizontal line with a small circle and arrow at the right.
func (p *Painter) MarkLine(x, y, width int) *Painter {
arrowWidth := 16
arrowHeight := 10
Expand All @@ -590,6 +602,7 @@ func (p *Painter) MarkLine(x, y, width int) *Painter {
return p
}

// Polygon draws a polygon with the specified center, radius, and number of sides.
func (p *Painter) Polygon(center Point, radius float64, sides int) *Painter {
points := getPolygonPoints(center, radius, sides)
for i, item := range points {
Expand Down
14 changes: 0 additions & 14 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"strings"

"github.com/dustin/go-humanize"

"github.com/go-analyze/charts/chartdraw"
)

// True returns a pointer to a true bool, useful for configuration.
Expand Down Expand Up @@ -113,18 +111,6 @@ func sumInt(values []int) int {
return sum
}

// measureTextMaxWidthHeight returns maxWidth and maxHeight of text list
func measureTextMaxWidthHeight(textList []string, p *Painter) (int, int) {
maxWidth := 0
maxHeight := 0
for _, text := range textList {
box := p.MeasureText(text)
maxWidth = chartdraw.MaxInt(maxWidth, box.Width())
maxHeight = chartdraw.MaxInt(maxHeight, box.Height())
}
return maxWidth, maxHeight
}

func reverseStringSlice(stringList []string) {
for i, j := 0, len(stringList)-1; i < j; i, j = i+1, j-1 {
stringList[i], stringList[j] = stringList[j], stringList[i]
Expand Down
45 changes: 2 additions & 43 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/go-analyze/charts/chartdraw"
)

func TestGetDefaultInt(t *testing.T) {
Expand Down Expand Up @@ -126,53 +123,15 @@ func TestGetRadius(t *testing.T) {
assert.Equal(t, 40.0, getRadius(100, ""))
}

func TestMeasureTextMaxWidthHeight(t *testing.T) {
t.Parallel()

p, err := NewPainter(PainterOptions{
Width: 400,
Height: 300,
})
require.NoError(t, err)
style := FontStyle{
FontSize: 10,
}
p.SetStyle(chartdraw.Style{FontStyle: style})

maxWidth, maxHeight := measureTextMaxWidthHeight([]string{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
}, p)
assert.Equal(t, 31, maxWidth)
assert.Equal(t, 12, maxHeight)
}

func TestReverseSlice(t *testing.T) {
t.Parallel()

arr := []string{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
}
reverseStringSlice(arr)
assert.Equal(t, []string{
"Sun",
"Sat",
"Fri",
"Thu",
"Wed",
"Tue",
"Mon",
"Sun", "Sat", "Fri", "Thu", "Wed", "Tue", "Mon",
}, arr)

numbers := []int{1, 3, 5, 7, 9}
Expand Down

0 comments on commit 1958b50

Please sign in to comment.