-
Notifications
You must be signed in to change notification settings - Fork 7
Feature Overview
This non-exhaustive list demonstrates our chart library's flexibility and feature range. To request a new feature open an issue.
Charts can be rendered to png
(default), jpg
, or svg
(XML vector image for web). Specify the output type when constructing the Painter
. For example, to render a jpg
file:
p := charts.NewPainter(charts.PainterOptions{
OutputFormat: charts.ChartOutputJPG,
Width: 800,
Height: 600,
})
Supported chart types: line
, scatter
, bar
, horizontal bar
, pie
, doughnut
, radar
, funnel
, candlestick
and table
.
A line chart visualizes data points connected by a continuous line, showing trends over time or another dimension.
Point symbols mark data points on the line. Customize shapes (circle
, dot
, square
, diamond
, none
) using the Symbol
field in the series configuration.
opt.SeriesList[0].Symbol = charts.SymbolCircle
opt.SeriesList[1].Symbol = charts.SymbolDiamond
opt.SeriesList[2].Symbol = charts.SymbolSquare
opt.SeriesList[3].Symbol = charts.SymbolDot
Lines can be smoothed using StrokeSmoothingTension
(0-1). Values near 0 create straight lines, values near 1 create heavily smoothed curves.
Adjust line thickness using LineStrokeWidth
.
opt.Symbol = charts.SymbolNone
opt.LineStrokeWidth = 4.0
opt.StrokeSmoothingTension = 0.9
Mark points highlight specific data points, while mark lines draw horizontal lines at those points. Configure using MarkPoint
or MarkLine
on the LineSeries
struct.
for i := range opt.SeriesList {
opt.SeriesList[i].MarkPoint = charts.NewMarkPoint(charts.SeriesMarkTypeMax)
opt.SeriesList[i].MarkLine = charts.NewMarkLine(charts.SeriesMarkTypeAverage)
opt.SeriesList[i].MarkLine.ValueFormatter = func(v float64) string {
return charts.FormatValueHumanizeShort(v, 1, false)
}
}
Fill the area under lines for enhanced visual distinction by setting the FillArea
field. The transparency of the fill can be adjusted with FillOpacity
(0-255: 0=fully transparent, 255=fully opaque).
opt.FillArea = charts.Ptr(true)
opt.FillOpacity = 150
Stacked series line charts layer multiple datasets, with each subsequent series building on top of the previous one. Enabling StackSeries
automatically enables area filling to visualize cumulative trends.
Labels show original values, not summed values.
StackSeries: charts.Ptr(true)
The boundary gap controls spacing between data and chart edges. Control using BoundaryGap
, with charts.Ptr(true)
enabling padding around data points.
Line Chart Boundary Gap Example:
opt.XAxis.BoundaryGap = charts.Ptr(false)
Dual y-axes helps in comparing different data scales on the same chart. Configure a second y-axis by specifying two entries on the YAxis
slice in chart options.
opt.SeriesList[1].YAxisIndex = 1
opt.YAxis = append(opt.YAxis, opt.YAxis[0])
opt.YAxis[0].Theme = opt.Theme.WithYAxisSeriesColor(0)
opt.YAxis[1].Theme = opt.Theme.WithYAxisSeriesColor(1)
A scatter chart displays individual data points to show relationships between variables. Useful for identifying correlations, clusters, and outliers. Scatter charts are the only chart type accepting multiple y-axis points for a single x-axis position.
Customize point symbols for improved readability. Symbol
sets the shape (circle
, dot
, square
, diamond
), and SymbolSize
adjusts the size. Use these to ensure chart legibility based on data density.
Series Specific Symbol Example:
opt.SymbolSize = 4
opt.SeriesList[0].Symbol = charts.SymbolCircle
opt.SeriesList[1].Symbol = charts.SymbolDiamond
opt.SeriesList[2].Symbol = charts.SymbolSquare
opt.SeriesList[3].Symbol = charts.SymbolDot
Trend lines help reveal patterns in scatter plots by fitting a line through the data points. Supported trend line types include:
- "Moving Average": Smooths the data over a window of points
- "Linear": Fits a straight line to the data
- "Cubic": Creates a smooth curve that follows the data trends
Customize each trend line with different colors, widths, and smoothing levels.
Mark Lines are also supported as shown in Line Charts
above.
series := charts.NewSeriesListScatterMultiValue(values, charts.ScatterSeriesOption{
TrendLine: trend,
Label: charts.SeriesLabel{
ValueFormatter: func(f float64) string {
return charts.FormatValueHumanizeShort(f, 0, false)
},
},
})
series[0].MarkLine = charts.NewMarkLine(charts.SeriesMarkTypeMax)
series[1].MarkLine = charts.NewMarkLine(charts.SeriesMarkTypeMax)
A bar chart represents categorical data with rectangular bars. Bar length is proportional to the value it represents.
Control bar dimensions using BarWidth
for individual width and BarMargin
for spacing between bars.
opt.BarWidth = 4
opt.BarMargin = charts.Ptr(0.0)
Style bars with rounded tops using RoundedBarCaps
for a softer visual appearance.
(see Label Positioning example below)
opt.RoundedBarCaps = charts.Ptr(true)
Position labels at different locations relative to bars using SeriesLabelPosition
.
Bar Chart Series Label Example:
opt.SeriesLabelPosition = charts.PositionBottom
Configure Mark Points and Mark Lines on bar charts similar to Line and Scatter charts.
Bar Chart Mark Point and Line Example:
opt.SeriesList[0].MarkLine.AddLines(charts.SeriesMarkTypeAverage)
opt.SeriesList[0].MarkPoint.AddPoints(
charts.SeriesMarkTypeMax,
charts.SeriesMarkTypeMin,
)
opt.SeriesList[1].MarkLine.AddLines(charts.SeriesMarkTypeAverage)
opt.SeriesList[1].MarkPoint.AddPoints(
charts.SeriesMarkTypeMax,
charts.SeriesMarkTypeMin,
)
Stacked bar charts combine multiple series into single bars showing cumulative totals. Enable using StackSeries
, which layers each series on top of the previous one.
Bar Chart Stacked Series Example:
opt.StackSeries = charts.Ptr(true)
A horizontal bar chart displays categories along the vertical axis with horizontal value extensions.
Basic Horizontal Bar Chart Example:
Control horizontal bar dimensions using BarHeight
for individual height and BarMargin
for spacing between bars.
Horizontal Bar Size and Margin Example:
opt.BarHeight = 4
opt.BarMargin = charts.Ptr(0.0)
Mark lines draw lines at specific data points to highlight important values. Configure through HorizontalBarSeries.MarkLine
.
Horizontal Bar Chart Mark Line Example:
opt.SeriesList[0].MarkLine.AddLines(charts.SeriesMarkTypeMax)
opt.SeriesList[1].MarkLine.AddLines(charts.SeriesMarkTypeMax)
A pie chart is a circular chart divided into slices, where each slice represents a proportion of the whole. Each section's angle corresponds to its percentage of the total value.
Unlike most charts (funnel being the exception), data series are not sampled. Each series has a single value. This chart highlights relative sizes of different categories within a dataset.
Set the pie chart radius globally with Radius
in chart options or per-slice with the PieSeries.Radius
field.
largestRadius := 120.0
seriesMax := opt.SeriesList.MaxValue()
for i := range opt.SeriesList {
radiusValue := largestRadius * math.Sqrt(opt.SeriesList[i].Value/seriesMax)
opt.SeriesList[i].Radius = strconv.Itoa(int(math.Ceil(radiusValue)))
}
Configure gaps between slice segments using the SegmentGap
field.
Pie Chart Segment Gap Example:
opt.SegmentGap = 16
A doughnut chart is a pie chart with the center cut out, displaying series in a ring. For series with few items, it provides a more concise option than pie charts.
The doughnut center can display labels, allowing for a more compact chart layout.
Doughnut Chart Styles Example:
opt.CenterValues = "labels"
Configure a gap between segments using the SegmentGap
field.
Doughnut Chart Styles Example:
opt.SegmentGap = 16
A radar chart (spider or web chart) visualizes multivariate data across multiple dimensions. Each axis represents a variable, and points are connected to form a polygon. Especially useful for comparing entities across common metrics.
A candlestick chart displays OHLC (Open, High, Low, Close) data to visualize price movements over time. Each candlestick shows the opening and closing prices as a body, with wicks extending to show the high and low prices. Commonly used in financial markets for technical analysis.
Basic Candlestick Chart Example:

Automatic detection of common candlestick patterns helps identify potential market reversals and continuations.
opt.SeriesList[0].PatternConfig = (&charts.CandlestickPatternConfig{}).
WithPatternsCore() // Enable core patterns
// Or use WithPatternsAll() for all patterns
Aggregate candlestick data from smaller time periods into larger ones. Useful for viewing different time frames of the same data, such as converting 1-minute candles to 5-minute or hourly candles.
minuteSeries := charts.CandlestickSeries{Data: minuteData, Name: "1-Minute"}
fiveMinuteSeries := charts.AggregateCandlestick(minuteSeries, 5)

A funnel chart represents data as progressively decreasing segments, often illustrating process flows like sales conversion rates or user drop-offs. The widest part represents the initial stage, with subsequent stages narrowing based on values.
A heat map visualizes data density and patterns using color gradients. Useful for identifying trends, correlations, and outliers in large datasets.
Our go module can also be used to generate tables, which can either be used alone or rendered on the same painter as the chart to help detail your data values.
Display chart titles and subtext using the Title
field in chart options.
opt.Title = charts.TitleOption{
Text: "Rainfall vs Evaporation",
Subtext: "(Fake Data)",
FontStyle: charts.NewFontStyleWithSize(16),
SubtextFontStyle: charts.NewFontStyleWithSize(10),
}
Position titles with the Offset
field, using percent, pixels, or name.
opt.Title.Offset = charts.OffsetCenter
The legend shows series labels, helping users correlate colors to data.
opt.Legend = charts.LegendOption{
SeriesNames: []string{
"Search Engine", "Direct", "Email", "Union Ads", "Video Ads",
},
FontStyle: charts.NewFontStyleWithSize(10),
}
Change legend orientation with the Vertical
field. Particularly useful for long series lists.
opt.Legend.Vertical = charts.Ptr(true)
(See above examples: Scatter, Pie)
Position legends with the Offset
field with standard positions (left
, right
, top
, bottom
), percentages, or absolute values. Constants like OffsetCenter
or OffsetRight
simplify common cases.
opt.Legend.Offset: charts.OffsetStr{
Left: "80%",
Top: charts.PositionBottom,
}
(See above examples: Scatter, Pie)
Optionally specify a title to be rendered below the x-axis.
opt.XAxis.Title = "x-axis"
opt.XAxis.TitleFontStyle.FontColor = ColorNavy
opt.XAxis.TitleFontStyle.FontSize = 18
Rotate x-axis labels using LabelRotation
(radian value). Useful for long labels that might overlap.
opt.XAxis.LabelRotation = charts.DegreesToRadians(45)
Optionally specify a title rendered left or right of the y-axis.
opt.YAxis[0].Title = "left y-axis"
opt.YAxis[0].TitleFontStyle.FontColor = ColorNavy
opt.YAxis[0].TitleFontStyle.FontSize = 18
opt.YAxis[1].Title = "right y-axis"
opt.YAxis[1].TitleFontStyle = opt.YAxis[0].TitleFontStyle
Customize axis labels with a ValueFormatter
.
opt.YAxis[0].ValueFormatter = func(f float64) string {
return charts.FormatValueHumanizeShort(f, 1, true)
}
Our library selects minimum and maximum values that clearly show the data scale and produce human-friendly units.
Explicitly set y-axis minimum and maximum values using Min
and Max
fields for better control. You can also hint to the library how many labels should be rendered.
opt.YAxis[0].Min = charts.Ptr(0.0)
opt.YAxis[0].LabelCount = charts.Ptr(6)
Series data labels allow you to display values directly on chart elements, providing immediate context for data points. Labels can be shown or hidden on a per-series basis and support extensive formatting customization through the LabelFormatter
on the SeriesLabel
struct.
Control label visibility using the Show
field in SeriesLabel
:
opt.SeriesList[0].Label.Show = charts.Ptr(true) // Show labels
opt.SeriesList[1].Label.Show = charts.Ptr(false) // Hide labels
The LabelFormatter
provides complete control over label content and per-point styling. It's a function that takes the data point index, series name, and value, returning the label text and optional styling.
opt.SeriesList[0].Label.LabelFormatter = func(index int, name string, val float64) (string, *charts.LabelStyle) {
return fmt.Sprintf("%.1f", val), &charts.LabelStyle{
FontStyle: charts.FontStyle{FontColor: charts.ColorRed},
}
}
The library provides several pre-built formatters for common use cases:
-
LabelFormatterThresholdMin(threshold)
: Only shows labels for values above the specified threshold -
LabelFormatterThresholdMax(threshold)
: Only shows labels for values at or below the specified threshold
-
LabelFormatterTopN(values, n)
: Shows labels only for the top N highest values in the dataset

-
LabelFormatterGradientGreenRed(values)
: Colors labels from green (minimum) to red (maximum) -
LabelFormatterGradientRedGreen(values)
: Colors labels from red (minimum) to green (maximum) -
LabelFormatterGradientColor(values, colors...)
: Colors labels with a custom gradient between multiple colors
Gradient Label Colors Example:

Individual labels can override default styling by returning a LabelStyle
from the LabelFormatter
. This includes:
- Font properties (color, size, family)
- Background colors with optional corner radius
- Border styling (color and width)
opt.SeriesList[0].Label.LabelFormatter = func(index int, name string, val float64) (string, *charts.LabelStyle) {
return fmt.Sprintf("%.1f", val), &charts.LabelStyle{
FontStyle: charts.FontStyle{FontColor: charts.ColorWhite},
BackgroundColor: charts.ColorBlue,
CornerRadius: 4,
BorderColor: charts.ColorNavy,
BorderWidth: 1.0,
}
}
When creating dashboards or reports with multiple charts, layout builders eliminate the need for manual coordinate calculations or combining rendered images.
The grid-based approach is the easiest way to create aligned, structured layouts. Define a grid with fixed columns and rows, then position cells within that grid.
Multiple Charts Layout Example:
painters, err := p.LayoutByGrid(2, 2). // 2 columns, 2 rows
CellAt("topCenter", 0, 0).Span(2, 1). // Name cell 0,0 topCenter and span across both columns
CellAt("bottomLeft", 0, 1). // Name cell 0,1 bottomLeft
CellAt("bottomRight", 1, 1). // Name cell 1,1 bottomRight
Build()

The row-based approach provides more flexibility for progressive layouts, particularly when vertical alignment is not desired.
painters, err := p.LayoutByRows().
// First row: single column, 300px height
Height("300").Columns("topCenter").
// Second row: three equal columns that occupy the remaining vertical space
Row().Columns("bottomLeft", "bottomCenter", "bottomRight").
Build()
Themes offer the ability to configure the color styling across your charts.
Themes are designed for easy customization. For example, the winter
theme has a light blue background and blue text. To use a white
background with black text, adjust the theme as follows:
theme := charts.GetTheme(charts.ThemeWinter).
WithBackgroundColor(charts.ColorWhite).
WithTextColor(charts.ColorBlack)