go chart is a basic charting library in native golang.

go-chart

CircleCI Go Report Card

Package chart is a very simple golang native charting library that supports timeseries and continuous line charts.

Master should now be on the v3.x codebase, which overhauls the api significantly. Per usual, see examples for more information.

Installation

To install chart run the following:

> go get -u github.com/wcharczuk/go-chart

Most of the components are interchangeable so feel free to crib whatever you want.

Output Examples

Spark Lines:

Single axis:

Two axis:

Other Chart Types

Pie Chart:

The code for this chart can be found in examples/pie_chart/main.go.

Stacked Bar:

The code for this chart can be found in examples/stacked_bar/main.go.

Code Examples

Actual chart configurations and examples can be found in the ./examples/ directory. They are simple CLI programs that write to output.png (they are also updated with go generate.

Usage

Everything starts with the chart.Chart object. The bare minimum to draw a chart would be the following:

import (
    ...
    "bytes"
    ...
    "github.com/wcharczuk/go-chart" //exposes "chart"
)

graph := chart.Chart{
    Series: []chart.Series{
        chart.ContinuousSeries{
            XValues: []float64{1.0, 2.0, 3.0, 4.0},
            YValues: []float64{1.0, 2.0, 3.0, 4.0},
        },
    },
}

buffer := bytes.NewBuffer([]byte{})
err := graph.Render(chart.PNG, buffer)

Explanation of the above: A chart can have many Series, a Series is a collection of things that need to be drawn according to the X range and the Y range(s).

Here, we have a single series with x range values as float64s, rendered to a PNG. Note; we can pass any type of io.Writer into Render(...), meaning that we can render the chart to a file or a resonse or anything else that implements io.Writer.

API Overview

Everything on the chart.Chart object has defaults that can be overriden. Whenever a developer sets a property on the chart object, it is to be assumed that value will be used instead of the default.

The best way to see the api in action is to look at the examples in the ./_examples/ directory.

Design Philosophy

I wanted to make a charting library that used only native golang, that could be stood up on a server (i.e. it had built in fonts).

The goal with the API itself is to have the "zero value be useful", and to require the user to not code more than they absolutely needed.

Contributions

Contributions are welcome though this library is in a holding pattern for the forseable future.

Owner
Will Charczuk
How do I bio.
Will Charczuk
Comments
  • Colormap Support

    Colormap Support

    After examining current Go chart options, I find this one to be best-in-class for aesthetics and detail. For my purposes, I'm only missing one key feature: colormaps.

    Specifically, for plotting X/Y scatterplots, I have a Z axis of values associated with each X/Y point. I need that Z axis to have its values from Z-min to Z-max mapped to a color range for each point, as shown here.

    A good set of colormaps is discussed here and here. As you can see there, the viridis colormap is consistently high performing for the human eye.

  • Can't create a chart of a constant function

    Can't create a chart of a constant function

    Because of the way checkRanges is implemented here: https://github.com/wcharczuk/go-chart/blob/master/chart.go#L274, one can't plot something like f(x)=3.14.

  • ZValues in chart.ContinuousSeries

    ZValues in chart.ContinuousSeries

    So I was indeed able to use our features from #33 to plot my z values. But it was pretty ugly. I had to index the z value from the x and y float64 values. The only way I could see to do this was to hash x and y using sprintf("%.3f_%.3f", x, y) and map it to the z value:

    zFirst := zSequence[0]
    zMin, zMax := zFirst, zFirst
    for _, z := range zSequence[1:] {
    	if z < zMin {
    		zMin = z
    	}
    	if z > zMax {
    		zMax = z
    	}
    }
    
    getHash := func(x, y float64) string {
    	hash := sprintf("%.3f_%.3f", x, y)
    	return hash
    }
    
    zHash := map[string]float64{}
    for i, x := range xSequence {
    	y := ySequence[i]
    	z := zSequence[i]
    	hash := getHash(x, y)
    	zHash[hash] = z
    }
    
    viridisOfZ := func(xr, yr chart.Range, x, y float64) drawing.Color {
    	hash := getHash(x, y)
    	z := zHash[hash]
    	return chart.Viridis(z, zMin, zMax)
    }
    

    I think it would be much better to just add and process an optional ZValues in chart.ContinuousSeries the same way XValues and YValues are processed. Then we would need to change DotColorProvider to have tho following signature:

    type DotColorProvider func(xrange, yrange, zrange Range, x, y, z float64) drawing.Color
    

    If the ZValues are not defined, the runtime can just send this function 0 for z and have zrange be from 0 to 0.

    With this functionality added, my entire program above could be reduced to

    viridisOfZ := func(xr, yr, zr chart.Range, x, y, z float64) drawing.Color {
    	return chart.Viridis(z, zr.GetMin(), zr.GetMax())
    }
    

    I think you would have a much easier time implementing this one than I since you know the flow of the plotting section of the package.

  • Program stuck while running the following code

    Program stuck while running the following code

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/wcharczuk/go-chart"
    )
    
    func drawChart() {
    	sbc := chart.BarChart{
    		Height:   512,
    		BarWidth: 60,
    		XAxis: chart.Style{
    			Show: true,
    		},
    		YAxis: chart.YAxis{
    			Style: chart.Style{
    				Show: true,
    			},
    		},
    		Bars: []chart.Value{
    			{Value: 0, Label: "Blue"},
    			{Value: 0, Label: "Green"},
    			{Value: 0, Label: "Gray"},
    			{Value: 0, Label: "Orange"},
    			{Value: 0, Label: "Test"},
    			{Value: 0, Label: "??"},
    			{Value: 0, Label: "!!"},
    		},
    	}
    
    	println("rendering")
    	err := sbc.Render(chart.PNG, os.Stdout)
    	if err != nil {
    		fmt.Printf("Error rendering chart: %v\n", err)
    	}
    }
    
    func main() {
    	drawChart()
    }
    
  • Adds the ability to draw an XY scatter plot.

    Adds the ability to draw an XY scatter plot.

    This PR introduces two new fields on Style: DotWidth and DotColor. It also tweaks some aspects of the raster renderer, namely the .Circle function and some of the inner workings of the drawing package.

    Important consideration; so far only Draw.LineSeries uses these new fields, support in other types of plots is ongoing.

    Also adds an example for scatter plots in _examples/scatter/main.go.

  • Allow creation of XY scatter plots (i.e. disable line between points)

    Allow creation of XY scatter plots (i.e. disable line between points)

    I'm experimenting with go-chart to replace some python charting (matplotlib), and I need to produce an XY scatter plot with values against time (see attached as a sample).

    When I plot these series using go-chart it draws lines between the points, and I couldn't figure out how to plot points/ticks only.

    Is it possible? Is this something you're considering? How would you recommend going about this if I were to help implement it? :)

    Sample XY scatter plot

    garbage-collection-durations

  • Invert Y Axis

    Invert Y Axis

    As a user I would like to be able to invert a chart axis so that I can show values as having a low absolute value but a high relative value at the top of the graph.

    Context I'm charting rank values with 1 being the highest rank and 100 being a lower relative rank. I would like to be able to invert the Y axis so that the higher rank shows as being higher on the chart.

  • Custom Formatter text angle

    Custom Formatter text angle

    My custom formatter is overlapping the text so I need to either adjust the tick intervals or angle the test. I can see some references in the code to setting text angle but I can't see how it's exposed.

    What are my options here.

    Also, thanks for being responsive to my other issues :)

  • Incorrect SVG rendering of PieChart when one segment makes up >50% of pie

    Incorrect SVG rendering of PieChart when one segment makes up >50% of pie

    I've tried a few different pie charts and and it looks like when one of the segments makes up >50% of the pie that segment is drawn using 360-angle, which in the example below is the orange segment.

    This is the png version that I was expecting the svg version to look like: screenshot

    And here is a screenshot of the svg that I got: screen shot 2017-09-27 at 07 17 11

    Code Snippet:

    	palette := summaryPalette{chart.AlternateColorPalette, myOverrideColors}
    
    	pie := chart.PieChart{
    		Width:  width,
    		Height: height,
    		Values: []chart.Value{
    			{Value: notAtDepotRemaining.Value, Label: fmt.Sprintf("Remaining %.0f %s", notAtDepotRemaining.Value, notAtDepotRemaining.Unit)},
    			{Value: notAtDepotUsed.Value, Label: fmt.Sprintf("Empty %.0f %s", notAtDepotUsed.Value, notAtDepotUsed.Unit)},
    			{Value: depotUsed.Value, Label: fmt.Sprintf("Returned %.0f %s", depotUsed.Value, depotUsed.Unit)},
    			{Value: depotRemaining.Value, Label: fmt.Sprintf("Stock %.0f %s", depotRemaining.Value, depotRemaining.Unit)},
    		},
    		ColorPalette: palette,
    	}
    
            ext := path.Ext(r.URL.Path)
    	switch ext {
    	case ".png":
    		w.Header().Set("Content-Type", "image/png")
    		if err := pie.Render(chart.PNG, w); err != nil {
    			return fmt.Errorf("PNG: %s", err)
    		}
    
    	case ".svg":
    		w.Header().Set("Content-Type", "image/svg+xml")
    		if err := pie.Render(chart.SVG, w); err != nil {
    			return fmt.Errorf("SVG: %s", err)
    		}
    
    	default:
    		http.NotFound(w, r)
    	}
    
  • It's possible to reduce number of labels on X Axis?

    It's possible to reduce number of labels on X Axis?

    It's possible to show less values / labels on X Axis? It would be great if it could only show minimum, maximum, the middle and maybe 1 or 2 between those.

    stats

  • go get github.com/wcharczuk/go-chart failed

    go get github.com/wcharczuk/go-chart failed

    $ go get github.com/wcharczuk/go-chart

    github.com/wcharczuk/go-chart

    E:\Code\Go\src\github.com\wcharczuk\go-chart\vector_renderer.go:173: vr.fc.MeasureString(body).Ceil undefined (type fixed.Int26_6 has no field or method Ceil)

    intel i7 amd64 win10

  • Fix donut chart when there is only one element

    Fix donut chart when there is only one element

    When there was only one value for the pie chart the circle was not drawn. The style of the value was not used, and the radius of the circle was not matching the value when there are more than one elements.

    It seems that "Circle" does not print a correct circle, the shape is weird. To print the donut hole it does not use "Circle", so I used the same code to draw a single element.

  • Single element donut charts renders as an empty canvas

    Single element donut charts renders as an empty canvas

    I had a requirement to generate charts that somtimes contain only 1 element(100%)/ But having only one element as input values ends up with just the canvas. Single item donut charts seem to have some custom handling here . https://github.com/wcharczuk/go-chart/blob/c1468e8ae4ed7c6f564f3bb54ae90b563dcf65ce/donut_chart.go#L134

    func main() {
    	donut := chart.DonutChart{
    		Width:  512,
    		Height: 512,
    		Values: []chart.Value{
    			{
    				Value: 1,
    			},
    		},
    	}
    	f, _ := os.Create("donut.png")
    	donut.Render(chart.PNG, f)
    	
    }
    

    Output(just a white canvas): donut

    Workaround As a workaround I ended up with adding an extra value with a very small value(1e-7) and very small stroke width which triggered the usual rendering. Its not ideal as you can still see a tiny white line but its something.

    Values: []chart.Value{
    			{
    				Value: 1,
    				Style: chart.Style{
    					StrokeWidth: 1e-7,
    				},
    			},
    			{
    				Value: 1e-7,
    				Style: chart.Style{
    					StrokeWidth: 1e-7,
    				},
    			},
    		},
    

    Output donut

  • How to reorder bar charts?

    How to reorder bar charts?

    Trying to put Politics & Government on right side of chart. Despire reordering passed graph.Bars Politics & Government is second anyway

    	for i, value := range values {
    		j := 0 // 0-9
    		switch value.Label {
    		case "Family & Relationships":
    			j = 0
    		case "Entertainment & Music":
    			j = 9
    		case "Society & Culture":
    			j = 2
    		case "Health":
    			j = 3
    		case "Business & Finance":
    			j = 4
    		case "Education & Reference":
    			j = 5
    		case "Sports":
    			j = 6
    		case "Science & Mathematics":
    			j = 7
    		case "Computers & Internet":
    			j = 8
    		case "Politics & Government":
    			values[i].Label = "ХУЙ" // TODO: изменить порядок баров
    			j = 2
    		default:
    			pp.Println("category not found", value.Label)
    		}
    		values[i], values[j] = values[j], values[i]
    	}
    
    	graph := chart.BarChart{
    		Title: text,
    		TitleStyle: chart.Style{
    			Padding: chart.Box{Bottom: 50},
    			Font:    font,
    		},
    		ColorPalette: nil,
    		Width:        1100,
    		Height:       600,
    		DPI:          0,
    		BarWidth:     60,
    		Background:   chart.Style{},
    		Canvas:       chart.Style{},
    		XAxis:        chart.Style{},
    		YAxis: chart.YAxis{
    			AxisType: chart.YAxisPrimary, // TODO: need chart.YAxisSecondary but Yaxis just crops. Waiting for fixing
    		},
    		BarSpacing: 0,
    		Font:       nil,
    		Bars:       values,
    		Elements:   nil,
    	}
    

    https://i.yapx.cc/UNGAJ.png

  • Legend style improvements

    Legend style improvements

    This PR builds on top of #199 and it improves some visual issues such as some poorly chosen paddings and it fixes the issue that for several legends users weren't able to provide custom paddings.

    To get a feeling how I adjusted the default paddings between vertical legend elements:

    Old: output_old

    New: output_new

    PS: This is a clone of https://github.com/wcharczuk/go-chart/pull/190 since my PR was stale and I wanted to create a clone of this project. Hence I merged other changes into my branch. To have a clean feature branch, I created a new one.

  • Implement Legend with fixed length line on the left side

    Implement Legend with fixed length line on the left side

    Hey there,

    I had some issues with #185 - the line in the legend was just way too long in my charts. So I implemented a legend type that puts the line on the left hand side. That way the legend looks a lot cleaner than before for legends with (at least) one long and one short label.

    Let me know what you think about it.

    Cheers, Rico

    PS: This is a clone of https://github.com/wcharczuk/go-chart/pull/189 since my PR was stale and I wanted to create a clone of this project. Hence I merged other changes into my branch. To have a clean feature branch, I created a new one.

Data visualization with chart, Create CSV file, Read Write CSV file

Data visualization with chart, Create CSV file, Read Write CSV file, Read from json file and many more in single project ......

Jan 13, 2022
Stock chart + gxui

chartgxui Stock chart + gxui This application is privacy practice example and non-commercial use. It has only limited experience of dealing with marke

Feb 14, 2022
🎨 The adorable charts library for Golang
🎨 The adorable charts library for Golang

go-echarts ?? The adorable charts library for Golang. If a language can be used to build web scrapers, it definitely needs to provide a graceful data

Dec 30, 2022
go-echarts 🎨 The adorable charts library for Golang
go-echarts 🎨 The adorable charts library for Golang

go-echarts ?? The adorable charts library for Golang. If a language can be used to build web scrapers, it definitely needs to provide a graceful data

Jan 4, 2023
Ltree Visualizer - A golang library to visualize postgres ltree type data using DOT language and Graphviz
Ltree Visualizer - A golang library to visualize postgres ltree type data using DOT language and Graphviz

Ltree Visualizer A golang library to visualize postgres ltree type data using DOT language and Graphviz What is Ltree? Ltree is a data type which is u

Jun 12, 2022
A charts library for Golang
A charts library for Golang

go-charts go-charts基于go-chart生成数据图表,无其它模块的依赖纯golang的实现,支持svg与png的输出,Apache ECharts在前端开发中得到众多开发者的认可,go-charts兼容Apache ECharts的配置参数,简单快捷的生成相似的图表(svg或png

Dec 29, 2022
Gfx - Golang file system extension library
Gfx - Golang file system extension library

gfx Golang文件操作扩展库,包含工作和生活中关于文件操作的各种有用的使用方法,包括 更友好的API 文件创建 文件删除 文件复制 一切皆可配置 文件名

Mar 10, 2022
3D Wireframe Drawing Library for Go
3D Wireframe Drawing Library for Go

pinhole 3D Wireframe Drawing Library for Go Javascript Version Demo Why does this exist? I needed a CPU based 3D rendering library with a very simple

Dec 10, 2022
fswatch, this library could help watching filesystem changes, like macOS fswatch

fswatch go library for simple UNIX file system watching fswatch provides simple UNIX file system watching in Go. It is based around the Watcher struct

Jan 7, 2022
Globe wireframe visualizations in Golang
Globe wireframe visualizations in Golang

globe Globe wireframe visualizations in Golang backed by pinhole. Getting Started Install globe with $ go get -u github.com/mmcloughlin/globe Start wi

Jan 7, 2023
🚀Statsview is a real-time Golang runtime stats visualization profiler
🚀Statsview is a real-time Golang runtime stats visualization profiler

Statsview is a real-time Golang runtime stats visualization profiler. It is built top on another open-source project, go-echarts, which helps statsview to show its graphs on the browser.

Dec 29, 2022
A golang implementation of endlessh exporting Prometheus metrics, visualized by a Grafana dashboard.
A golang implementation of endlessh exporting Prometheus metrics, visualized by a Grafana dashboard.

endlessh-go A golang implementation of endlessh exporting Prometheus metrics, visualized by a Grafana dashboard. Introduction Endlessh is a great idea

Dec 23, 2022
Interactive dependency graph visualization tool for golang
Interactive dependency graph visualization tool for golang

Interactive dependency graph visualization tool for golang using the awesome cytoscape graph visualizer.

Sep 1, 2022
go chart is a basic charting library in native golang.
go chart is a basic charting library in native golang.

go-chart Package chart is a very simple golang native charting library that supports timeseries and continuous line charts. Master should now be on th

Dec 30, 2022
HSM package provides a simple state chart library written in Go.

UML HSM HSM package provides a simple state chart library written in Go. Supported UML State Chart Features Feature Implemented Test case Simple state

Apr 14, 2022
Find out where you fall on the Open-Source Character Alignment Chart

gitaligned Find out where you fall on the Open-Source Character Alignment Chart Binaries available in releases. If you prefer to install from source,

Dec 28, 2022
A helm v3 plugin to adopt existing k8s resources into a new generated helm chart

helm-adopt Overview helm-adopt is a helm plugin to adopt existing k8s resources into a new generated helm chart, the idea behind the plugin was inspir

Dec 15, 2022
Creates Helm chart from Kubernetes yaml

Helmify CLI that creates Helm charts from kubernetes yamls. Helmify reads a list of supported k8s objects from stdin and converts it to a helm chart.

Dec 28, 2022
An example microservice demo using kubernetes concepts like deployment, services, persistent volume and claims, secrets and helm chart

Docker vs Kubernetes Docker Kubernetes container tech, isolated env for apps infra management, multiple containers automated builds and deploy apps -

Dec 13, 2021
Data visualization with chart, Create CSV file, Read Write CSV file

Data visualization with chart, Create CSV file, Read Write CSV file, Read from json file and many more in single project ......

Jan 13, 2022