Go to file
2016-07-15 17:15:06 -07:00
drawing some report card feedback. 2016-07-15 13:40:24 -07:00
images adding image. 2016-07-15 16:58:27 -07:00
testserver more gofmt -s changes. 2016-07-15 13:45:33 -07:00
.travis.yml fixing bug with annotations with axis turned off. 2016-07-10 16:26:18 -07:00
annotation_series_test.go more gofmt -s changes. 2016-07-15 13:45:33 -07:00
annotation_series.go inching up coverage. 2016-07-12 20:34:59 -07:00
axis.go gridlines. 2016-07-12 19:14:14 -07:00
bollinger_band_series_test.go adding GetLastBoundedValue and tests 2016-07-15 13:27:45 -07:00
bollinger_band_series.go adding a helper method, DrawBoundedSeries to help w/ bounded series drawing. 2016-07-15 17:15:06 -07:00
box_test.go removing point, adding tests. 2016-07-12 19:38:24 -07:00
box.go slightly more rigorous bounds checking and auto-fit 2016-07-12 16:47:52 -07:00
chart_test.go some regression tests 2016-07-13 11:50:22 -07:00
chart.go bollinger bounds 2016-07-15 09:02:50 -07:00
continuous_series.go mostly works. 2016-07-10 10:43:04 -07:00
defaults.go DID NOT KNOW THAT 2016-07-15 13:42:04 -07:00
drawing_helpers.go adding a helper method, DrawBoundedSeries to help w/ bounded series drawing. 2016-07-15 17:15:06 -07:00
grid_line_test.go gofmt -s 2016-07-15 13:43:53 -07:00
grid_line.go pulling generate grid lines into its own function 2016-07-12 19:22:02 -07:00
LICENSE license and readme. 2016-07-07 20:37:57 -07:00
moving_average_series_test.go ditto w/ the other test. 2016-07-14 13:14:02 -07:00
moving_average_series.go small ma fixes 2016-07-14 13:11:03 -07:00
range_test.go bug fixes and refinements. 2016-07-11 23:32:31 -07:00
range.go ??? 2016-07-11 18:48:51 -07:00
raster_renderer.go fixing dashes. 2016-07-14 18:53:54 -07:00
README.md readme updates. 2016-07-15 17:00:50 -07:00
renderable.go api tweaks. 2016-07-14 18:29:06 -07:00
renderer_provider.go snapshot. 2016-07-10 01:11:47 -07:00
renderer.go ??? 2016-07-11 18:48:51 -07:00
ring_buffer_test.go moving averages! dashes! 2016-07-14 09:27:23 -07:00
ring_buffer.go moving averages! dashes! 2016-07-14 09:27:23 -07:00
roboto.go initial commit. 2016-07-06 18:54:00 -07:00
series.go adding GetName() to the series interface 2016-07-14 16:31:26 -07:00
style_test.go inching up coverage. 2016-07-10 23:06:14 -07:00
style.go missed font size 2016-07-14 19:45:23 -07:00
tick_test.go bug fixes and refinements. 2016-07-11 23:32:31 -07:00
tick.go some regression tests 2016-07-13 11:50:22 -07:00
time_series_test.go updates 2016-07-09 20:14:11 -07:00
time_series.go some regression tests 2016-07-13 11:50:22 -07:00
util_test.go adding tests. 2016-07-14 12:30:57 -07:00
util.go tests. 2016-07-15 09:17:51 -07:00
value_formatter_provider.go mostly works. 2016-07-10 10:43:04 -07:00
value_formatter_test.go inching up coverage. 2016-07-10 23:06:14 -07:00
value_formatter.go adding percent value format 2016-07-14 11:21:41 -07:00
value_provider.go bollinger bounds 2016-07-15 09:02:50 -07:00
vector_renderer_test.go slightly more rigorous bounds checking and auto-fit 2016-07-12 16:47:52 -07:00
vector_renderer.go slightly more rigorous bounds checking and auto-fit 2016-07-12 16:47:52 -07:00
xaxis_test.go more gofmt -s changes. 2016-07-15 13:45:33 -07:00
xaxis.go coverage at 63.8% 2016-07-12 22:04:30 -07:00
yaxis_test.go more gofmt -s changes. 2016-07-15 13:45:33 -07:00
yaxis.go updates 2016-07-12 22:55:46 -07:00

go-chart

Build Status

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

The v1.0 release has been tagged so things should be more or less stable, if something changes please log an issue.

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.

Usage

The chart code to produce the above is as follows:

// note this assumes that xvalues and yvalues
// have been pulled from a pricing service.
graph := chart.Chart{
    Width:  1024,
    Height: 400,
    YAxis: chart.YAxis {
        Style: chart.Style{
            Show: true,
        },
    },
    XAxis: chart.XAxis {
        Style: chart.Style{
            Show: true,
        },
    },
    Series: []chart.Series{
        chart.TimeSeries{
            XValues: xvalues,
            YValues: yvalues,
            Style: chart.Style {
                FillColor: chart.DefaultSeriesStrokeColors[0].WithAlpha(64),
            },
        },
        chart.AnnotationSeries{
            Name: "Last Value",
            Style: chart.Style{
                Show:        true,
                StrokeColor: chart.DefaultSeriesStrokeColors[0],
            },
            Annotations: []chart.Annotation{
                chart.Annotation{
                    X:     chart.TimeToFloat64(xvalues[len(xvalues)-1]),
                    Y:     yvalues[len(yvalues)-1],
                    Label: chart.FloatValueFormatter(yvalues[len(yvalues)-1]),
                },
            },
        },
    },
}
graph.Render(chart.PNG, buffer) //thats it!

The key areas to note are that we have to explicitly turn on two features, the axes and add the last value label annotation series. When calling .Render(..) we add a parameter, chart.PNG that tells the renderer to use a raster renderer. Another option is to use chart.SVG which will use the vector renderer and create an svg representation of the chart.

Alternate Usage

You can alternately leave a bunch of features turned off and constrain the proportions to something like a spark line:

The code to produce the above would be:

// note this assumes that xvalues and yvalues
// have been pulled from a pricing service.
graph := chart.Chart{
    Width:  1024,
    Height: 100,
    Series: []chart.Series{
        chart.TimeSeries{
            XValues: xvalues,
            YValues: yvalues,
        },
    },
}
graph.Render(chart.PNG, buffer)

2 Y-Axis Charts

It is also possible to draw series against 2 separate y-axis with their own ranges (usually good for comparison charts). In order to map the series to an alternate axis make sure to set the YAxis property of the series to YAxisSecondary.

graph := chart.Chart{
    Title: stock.Name,
    TitleStyle: chart.Style{
        Show: false,
    },
    Width:  width,
    Height: height,
    XAxis: chart.XAxis{
        Style: chart.Style{
            Show: true,
        },
    },
    YAxis: chart.YAxis{
        Style: chart.Style{
            Show: true,
        },
    },
    Series: []chart.Series{
        chart.TimeSeries{
            Name:    "vea",
            XValues: vx,
            YValues: vy,
            Style: chart.Style{
                Show: true,
                StrokeColor: chart.GetDefaultSeriesStrokeColor(0),
                FillColor:   chart.GetDefaultSeriesStrokeColor(0).WithAlpha(64),
            },
        },
        chart.TimeSeries{
            Name:    "spy",
            XValues: cx,
            YValues: cy,
            YAxis:   chart.YAxisSecondary,  // key (!)
            Style: chart.Style{
                Show: true,
                StrokeColor: chart.GetDefaultSeriesStrokeColor(1),
                FillColor:   chart.GetDefaultSeriesStrokeColor(1).WithAlpha(64),
            },
        },
        chart.AnnotationSeries{
            Name: fmt.Sprintf("%s - Last Value", "vea"),
            Style: chart.Style{
                Show:        true,
                StrokeColor: chart.GetDefaultSeriesStrokeColor(0),
            },
            Annotations: []chart.Annotation{
                chart.Annotation{
                    X:     float64(vx[len(vx)-1].Unix()),
                    Y:     vy[len(vy)-1],
                    Label: fmt.Sprintf("%s - %s", "vea", chart.FloatValueFormatter(vy[len(vy)-1])),
                },
            },
        },
        chart.AnnotationSeries{
            Name: fmt.Sprintf("%s - Last Value", "goog"),
            Style: chart.Style{
                Show:        true,
                StrokeColor: chart.GetDefaultSeriesStrokeColor(1),
            },
            YAxis: chart.YAxisSecondary, // key (!)
            Annotations: []chart.Annotation{
                chart.Annotation{
                    X:     float64(cx[len(cx)-1].Unix()),
                    Y:     cy[len(cy)-1],
                    Label: fmt.Sprintf("%s - %s", "goog", chart.FloatValueFormatter(cy[len(cy)-1])),
                },
            },
        },
    },
}
graph.Render(chart.PNG, buffer)

Moving Averages

You can now also graph a moving average of a series using a special MovingAverageSeries that takes an InnerSeries as a required argument.

There is a helper method, GetLastValue on the MovingAverageSeries to aid in creating a last value annotation for the series.

More Intense Technical Analysis

You can also have series that produce two values, i.e. a series that implements BoundedValueProvider and the GetBoundedValue(int)(x,y1,y2 float64) method.

Like the MovingAverageSeries this series takes an InnerSeries argument as required, and defaults to 10 samples and a K value of 2.0 (or two standard deviations in either direction).

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

This library is super early but contributions are welcome.