vicanso / go-charts

A charts library for Golang
MIT License
213 stars 32 forks source link
chart charting-library charts echarts go go-chart go-charts golang svg

go-charts

license Build Status

中文

go-charts base on go-chart,it is simpler way for generating charts, which supports svg and png format and themes: light, dark, grafana and ant. The default format is png and the default theme is light.

Apache ECharts is popular among Front-end developers, so go-charts supports the option of Apache ECharts. Developers can generate charts almost the same as Apache ECharts.

Screenshot of common charts, the left part is light theme, the right part is grafana theme.

go-charts

go-table

Chart Type

These chart types are supported: line, bar, horizontal bar, pie, radar or funnel and table.

Example

More examples can be found in the ./examples/ directory.

Line Chart

package main

import (
    charts "github.com/vicanso/go-charts/v2"
)

func main() {
    values := [][]float64{
        {
            120,
            132,
            101,
            134,
            90,
            230,
            210,
        },
        {
            // snip...
        },
        {
            // snip...
        },
        {
            // snip...
        },
        {
            // snip...
        },
    }
    p, err := charts.LineRender(
        values,
        charts.TitleTextOptionFunc("Line"),
        charts.XAxisDataOptionFunc([]string{
            "Mon",
            "Tue",
            "Wed",
            "Thu",
            "Fri",
            "Sat",
            "Sun",
        }),
        charts.LegendLabelsOptionFunc([]string{
            "Email",
            "Union Ads",
            "Video Ads",
            "Direct",
            "Search Engine",
        }, charts.PositionCenter),
    )

    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...
}

Bar Chart

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    values := [][]float64{
        {
            2.0,
            4.9,
            7.0,
            23.2,
            25.6,
            76.7,
            135.6,
            162.2,
            32.6,
            20.0,
            6.4,
            3.3,
        },
        {
            // snip...  
        },
    }
    p, err := charts.BarRender(
        values,
        charts.XAxisDataOptionFunc([]string{
            "Jan",
            "Feb",
            "Mar",
            "Apr",
            "May",
            "Jun",
            "Jul",
            "Aug",
            "Sep",
            "Oct",
            "Nov",
            "Dec",
        }),
        charts.LegendLabelsOptionFunc([]string{
            "Rainfall",
            "Evaporation",
        }, charts.PositionRight),
        charts.MarkLineOptionFunc(0, charts.SeriesMarkDataTypeAverage),
        charts.MarkPointOptionFunc(0, charts.SeriesMarkDataTypeMax,
            charts.SeriesMarkDataTypeMin),
        // custom option func
        func(opt *charts.ChartOption) {
            opt.SeriesList[1].MarkPoint = charts.NewMarkPoint(
                charts.SeriesMarkDataTypeMax,
                charts.SeriesMarkDataTypeMin,
            )
            opt.SeriesList[1].MarkLine = charts.NewMarkLine(
                charts.SeriesMarkDataTypeAverage,
            )
        },
    )
    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...
}

Horizontal Bar Chart

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    values := [][]float64{
        {
            18203,
            23489,
            29034,
            104970,
            131744,
            630230,
        },
        {
            // snip...  
        },
    }
    p, err := charts.HorizontalBarRender(
        values,
        charts.TitleTextOptionFunc("World Population"),
        charts.PaddingOptionFunc(charts.Box{
            Top:    20,
            Right:  40,
            Bottom: 20,
            Left:   20,
        }),
        charts.LegendLabelsOptionFunc([]string{
            "2011",
            "2012",
        }),
        charts.YAxisDataOptionFunc([]string{
            "Brazil",
            "Indonesia",
            "USA",
            "India",
            "China",
            "World",
        }),
    )
    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...
}

Pie Chart

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    values := []float64{
        1048,
        735,
        580,
        484,
        300,
    }
    p, err := charts.PieRender(
        values,
        charts.TitleOptionFunc(charts.TitleOption{
            Text:    "Rainfall vs Evaporation",
            Subtext: "Fake Data",
            Left:    charts.PositionCenter,
        }),
        charts.PaddingOptionFunc(charts.Box{
            Top:    20,
            Right:  20,
            Bottom: 20,
            Left:   20,
        }),
        charts.LegendOptionFunc(charts.LegendOption{
            Orient: charts.OrientVertical,
            Data: []string{
                "Search Engine",
                "Direct",
                "Email",
                "Union Ads",
                "Video Ads",
            },
            Left: charts.PositionLeft,
        }),
        charts.PieSeriesShowLabel(),
    )
    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...  
}

Radar Chart

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    values := [][]float64{
        {
            4200,
            3000,
            20000,
            35000,
            50000,
            18000,
        },
        {
            // snip...
        },
    }
    p, err := charts.RadarRender(
        values,
        charts.TitleTextOptionFunc("Basic Radar Chart"),
        charts.LegendLabelsOptionFunc([]string{
            "Allocated Budget",
            "Actual Spending",
        }),
        charts.RadarIndicatorOptionFunc([]string{
            "Sales",
            "Administration",
            "Information Technology",
            "Customer Support",
            "Development",
            "Marketing",
        }, []float64{
            6500,
            16000,
            30000,
            38000,
            52000,
            25000,
        }),
    )
    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...
}

Funnel Chart

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    values := []float64{
        100,
        80,
        60,
        40,
        20,
    }
    p, err := charts.FunnelRender(
        values,
        charts.TitleTextOptionFunc("Funnel"),
        charts.LegendLabelsOptionFunc([]string{
            "Show",
            "Click",
            "Visit",
            "Inquiry",
            "Order",
        }),
    )
    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...
}

Table

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    header := []string{
        "Name",
        "Age",
        "Address",
        "Tag",
        "Action",
    }
    data := [][]string{
        {
            "John Brown",
            "32",
            "New York No. 1 Lake Park",
            "nice, developer",
            "Send Mail",
        },
        {
            "Jim Green  ",
            "42",
            "London No. 1 Lake Park",
            "wow",
            "Send Mail",
        },
        {
            "Joe Black  ",
            "32",
            "Sidney No. 1 Lake Park",
            "cool, teacher",
            "Send Mail",
        },
    }
    spans := map[int]int{
        0: 2,
        1: 1,
        // 设置第三列的span
        2: 3,
        3: 2,
        4: 2,
    }
    p, err := charts.TableRender(
        header,
        data,
        spans,
    )
    if err != nil {
        panic(err)
    }

    buf, err := p.Bytes()
    if err != nil {
        panic(err)
    }
    // snip...
}

ECharts Render

package main

import (
    "github.com/vicanso/go-charts/v2"
)

func main() {
    buf, err := charts.RenderEChartsToPNG(`{
        "title": {
            "text": "Line"
        },
        "xAxis": {
            "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
        },
        "series": [
            {
                "data": [150, 230, 224, 218, 135, 147, 260]
            }
        ]
    }`)
    // snip...
}

ECharts Option

The name with [] is new parameter, others are the same as echarts.

Performance

Generate a png chart will be less than 20ms. It's better than using chrome headless with echarts.

BenchmarkMultiChartPNGRender-8                78          15216336 ns/op         2298308 B/op       1148 allocs/op
BenchmarkMultiChartSVGRender-8               367           3356325 ns/op        20597282 B/op       3088 allocs/op