Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offset, Orientation and other config ergonomict tweaks #20

Merged
merged 3 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Notable improvements in our fork include:

* **Axis Improvements:** Significant enhancements to axis rendering, data range selection, and configuration simplification were made in PR [#3](https://github.com/go-analyze/charts/pull/3).
* **Theming:** In PR [#4](https://github.com/go-analyze/charts/pull/4) (and some subsequent changes) we introduced `vivid-light` and `vivid-dark` themes for more vibrant visualizations, alongside API changes for greater theme and font control. Long term we plan to make themes easier to mutate and define.
* **Configuration Simplification:** PR [#5](https://github.com/go-analyze/charts/pull/5) began our effort to streamline chart configuration, making names more descriptive and specific while focusing on a theme-centric approach. Documentation on configuration and use is also being improved. (See also [#15](https://github.com/go-analyze/charts/pull/15))
* **Configuration Simplification:** PR [#5](https://github.com/go-analyze/charts/pull/5) began our effort to streamline chart configuration, making names more descriptive and specific while focusing on a theme-centric approach. Documentation on configuration and use is also being improved. (See also [#15](https://github.com/go-analyze/charts/pull/15), [#20](https://github.com/go-analyze/charts/pull/20))
* **Expanded Testing:** Ongoing test coverage expansions have led to bug discoveries and fixes. This will continue to help ensure that our charts render perfectly for a wide range of configurations and use.

Our library is a work in progress, aiming to become a standout choice for Go developers seeking powerful, yet easy-to-use charting tools. We welcome contributions and feedback as we continue to enhance our library's functionality, configurability, and reliability.
Expand Down Expand Up @@ -89,7 +89,7 @@ func main() {
charts.LegendLabelsOptionFunc([]string{
"Email",
"Search Engine",
}, charts.PositionCenter),
}),
)
// snip...
}
Expand Down Expand Up @@ -146,7 +146,7 @@ func main() {
charts.LegendLabelsOptionFunc([]string{
"Rainfall",
"Evaporation",
}, charts.PositionRight),
}),
charts.MarkLineOptionFunc(0, charts.SeriesMarkDataTypeAverage),
charts.MarkPointOptionFunc(0, charts.SeriesMarkDataTypeMax,
charts.SeriesMarkDataTypeMin),
Expand Down Expand Up @@ -240,7 +240,7 @@ func main() {
charts.TitleOptionFunc(charts.TitleOption{
Text: "Rainfall vs Evaporation",
Subtext: "Fake Data",
Left: charts.PositionCenter,
Offset: charts.OffsetCenter,
}),
charts.PaddingOptionFunc(charts.Box{
Top: 20,
Expand All @@ -249,15 +249,15 @@ func main() {
Left: 20,
}),
charts.LegendOptionFunc(charts.LegendOption{
Orient: charts.OrientVertical,
Veritcal: true,
Data: []string{
"Search Engine",
"Direct",
"Email",
"Union Ads",
"Video Ads",
},
Left: charts.PositionLeft,
Offset: charts.OffsetLeft,
}),
charts.PieSeriesShowLabel(),
)
Expand Down
69 changes: 59 additions & 10 deletions alias.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,81 @@
package charts

import (
"strconv"

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

type Box = chartdraw.Box
type Point = chartdraw.Point
type Color = drawing.Color
type FontStyle = chartdraw.FontStyle

var BoxZero = chartdraw.BoxZero

// Offset provides an ability to configure a shift from the top or left alignments.
type Offset struct {
// OffsetInt provides an ability to configure a shift from the top or left alignments.
type OffsetInt struct {
// Left indicates a vertical spacing adjustment from the top.
Top int
// Left indicates a horizontal spacing adjustment from the left.
Left int
}

type Point struct {
X int
Y int
func (o OffsetInt) WithTop(val int) OffsetInt {
return OffsetInt{
Left: o.Left,
Top: val,
}
}

func (o OffsetInt) WithLeft(val int) OffsetInt {
return OffsetInt{
Left: val,
Top: o.Top,
}
}

// OffsetStr provides an ability to configure a shift from the top or left alignments using flexible string inputs.
type OffsetStr struct {
// Left is the distance between the component and the left side of the container.
// It can be pixel value (20), percentage value (20%), or position description: 'left', 'right', 'center'.
Left string
// Top is the distance between the component and the top side of the container.
// It can be pixel value (20), or percentage value (20%).
Top string
}

var OffsetLeft = OffsetStr{Left: PositionLeft}
var OffsetRight = OffsetStr{Left: PositionRight}
var OffsetCenter = OffsetStr{Left: PositionCenter}

func (o OffsetStr) WithTop(val string) OffsetStr {
return OffsetStr{
Left: o.Left,
Top: val,
}
}

func (o OffsetStr) WithTopI(val int) OffsetStr {
return OffsetStr{
Left: o.Left,
Top: strconv.Itoa(val),
}
}

func (o OffsetStr) WithLeft(val string) OffsetStr {
return OffsetStr{
Left: val,
Top: o.Top,
}
}

func (o OffsetStr) WithLeftI(val int) OffsetStr {
return OffsetStr{
Left: strconv.Itoa(val),
Top: o.Top,
}
}

const (
Expand Down Expand Up @@ -52,8 +106,3 @@ const (
AlignRight = "right"
AlignCenter = "center"
)

const (
OrientHorizontal = "horizontal"
OrientVertical = "vertical"
)
13 changes: 4 additions & 9 deletions axis.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type AxisOption struct {
// TextRotation are the radians for rotating the label.
TextRotation float64
// LabelOffset is the offset of each label.
LabelOffset Offset
LabelOffset OffsetInt
// Unit is a suggestion for how large the axis step is, this is a recommendation only. Larger numbers result in fewer labels.
Unit float64
// LabelCount is the number of labels to show on the axis. Specify a smaller number to reduce writing collisions. This value takes priority over Unit.
Expand Down Expand Up @@ -150,7 +150,6 @@ func (a *axisPainter) Render() (Box, error) {
labelPaddingTop := 0
labelPaddingLeft := 0
labelPaddingRight := 0
orient := ""
textAlign := ""

switch opt.Position {
Expand All @@ -160,31 +159,27 @@ func (a *axisPainter) Render() (Box, error) {
y0 = labelMargin + int(opt.FontStyle.FontSize)
ticksPaddingTop = int(opt.FontStyle.FontSize)
y1 = y0
orient = OrientHorizontal
case PositionLeft:
x0 = p.Width()
y0 = 0
x1 = p.Width()
y1 = p.Height()
orient = OrientVertical
textAlign = AlignRight
ticksPaddingLeft = textMaxWidth + tickLength
labelPaddingRight = width - textMaxWidth
case PositionRight:
orient = OrientVertical
y1 = p.Height()
labelPaddingLeft = width - textMaxWidth
default:
labelPaddingTop = height
x1 = p.Width()
orient = OrientHorizontal
}

labelCount := opt.LabelCount
if labelCount <= 0 {
var maxLabelCount int
// Add 10px and remove one for some minimal extra padding so that letters don't collide
if orient == OrientVertical {
if isVertical {
maxLabelCount = (top.Height() / (textMaxHeight + 10)) - 1
} else {
maxLabelCount = (top.Width() / (textMaxWidth + 10)) - 1
Expand Down Expand Up @@ -227,7 +222,7 @@ func (a *axisPainter) Render() (Box, error) {
LabelCount: labelCount,
TickSpaces: tickSpaces,
Length: tickLength,
Orient: orient,
Vertical: isVertical,
First: opt.DataStartIndex,
})
p.LineStroke([]Point{
Expand All @@ -245,7 +240,7 @@ func (a *axisPainter) Render() (Box, error) {
First: opt.DataStartIndex,
Align: textAlign,
TextList: opt.Data,
Orient: orient,
Vertical: isVertical,
LabelCount: labelCount,
LabelSkipCount: opt.LabelSkipCount,
CenterLabels: centerLabels,
Expand Down
7 changes: 5 additions & 2 deletions bar_chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,20 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
FillColor: fillColor,
})
if flagIs(true, opt.RoundedBarCaps) {
seriesPainter.RoundedRect(chartdraw.Box{
seriesPainter.RoundedRect(Box{
Top: top,
Left: x,
Right: x + barWidth,
Bottom: barMaxHeight - 1,
IsSet: true,
}, barWidth, true, false)
} else {
seriesPainter.Rect(chartdraw.Box{
seriesPainter.Rect(Box{
Top: top,
Left: x,
Right: x + barWidth,
Bottom: barMaxHeight - 1,
IsSet: true,
})
}
// generate marker point by hand
Expand Down Expand Up @@ -156,6 +158,7 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
}
}
labelPainter.Add(LabelValue{
Vertical: true, // label is above bar
Index: index,
Value: item.Value,
FontStyle: fontStyle,
Expand Down
42 changes: 24 additions & 18 deletions bar_chart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,30 @@ func makeBasicBarChartOption() BarChartOption {
Bottom: 10,
},
SeriesList: seriesList,
XAxis: NewXAxisOption([]string{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
}),
YAxis: NewYAxisOptions([]string{
"Rainfall",
"Evaporation",
}),
XAxis: XAxisOption{
Data: []string{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
},
},
YAxis: []YAxisOption{
{
Data: []string{
"Rainfall",
"Evaporation",
},
},
},
}
}

Expand Down
18 changes: 13 additions & 5 deletions chart_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ func LegendOptionFunc(legend LegendOption) OptionFunc {
}

// LegendLabelsOptionFunc set legend labels of chart
func LegendLabelsOptionFunc(labels []string, left ...string) OptionFunc {
func LegendLabelsOptionFunc(labels []string) OptionFunc {
return func(opt *ChartOption) {
opt.Legend = NewLegendOption(labels, left...)
opt.Legend = LegendOption{
Data: labels,
}
}
}

Expand All @@ -134,9 +136,11 @@ func XAxisOptionFunc(xAxisOption XAxisOption) OptionFunc {
}

// XAxisDataOptionFunc set x-axis data of chart
func XAxisDataOptionFunc(data []string, boundaryGap ...*bool) OptionFunc {
func XAxisDataOptionFunc(data []string) OptionFunc {
return func(opt *ChartOption) {
opt.XAxis = NewXAxisOption(data, boundaryGap...)
opt.XAxis = XAxisOption{
Data: data,
}
}
}

Expand All @@ -150,7 +154,11 @@ func YAxisOptionFunc(yAxisOption ...YAxisOption) OptionFunc {
// YAxisDataOptionFunc set y-axis data of chart
func YAxisDataOptionFunc(data []string) OptionFunc {
return func(opt *ChartOption) {
opt.YAxis = NewYAxisOptions(data)
opt.YAxis = []YAxisOption{
{
Data: data,
},
}
}
}

Expand Down
11 changes: 6 additions & 5 deletions chart_option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func TestLineRender(t *testing.T) {
"Video Ads",
"Direct",
"Search Engine",
}, PositionCenter),
}),
)
require.NoError(t, err)
data, err := p.Bytes()
Expand Down Expand Up @@ -220,11 +220,12 @@ func TestBarRender(t *testing.T) {
LegendLabelsOptionFunc([]string{
"Rainfall",
"Evaporation",
}, PositionRight),
}),
MarkLineOptionFunc(0, SeriesMarkDataTypeAverage),
MarkPointOptionFunc(0, SeriesMarkDataTypeMax, SeriesMarkDataTypeMin),
// custom option func
func(opt *ChartOption) {
opt.Legend.Offset = OffsetRight
opt.SeriesList[1].MarkPoint = NewMarkPoint(
SeriesMarkDataTypeMax,
SeriesMarkDataTypeMin,
Expand Down Expand Up @@ -306,7 +307,7 @@ func TestPieRender(t *testing.T) {
TitleOptionFunc(TitleOption{
Text: "Rainfall vs Evaporation",
Subtext: "Fake Data",
Left: PositionCenter,
Offset: OffsetCenter,
}),
PaddingOptionFunc(Box{
Top: 20,
Expand All @@ -315,15 +316,15 @@ func TestPieRender(t *testing.T) {
Left: 20,
}),
LegendOptionFunc(LegendOption{
Orient: OrientVertical,
Vertical: true,
Data: []string{
"Search Engine",
"Direct",
"Email",
"Union Ads",
"Video Ads",
},
Left: PositionLeft,
Offset: OffsetLeft,
}),
PieSeriesShowLabel(),
)
Expand Down
Loading
Loading