# Chartkick
Create beautiful JavaScript charts with one line of Ruby. No more fighting with charting libraries!
[See it in action](http://ankane.github.io/chartkick/)
:fire: For admin charts and dashboards, check out [Blazer](https://github.com/ankane/blazer/)
:two_hearts: A perfect companion to [Groupdate](https://github.com/ankane/groupdate), [Hightop](https://github.com/ankane/hightop), and [ActiveMedian](https://github.com/ankane/active_median)
## Charts
Line chart
```erb
<%= line_chart User.group_by_day(:created_at).count %>
```
Pie chart
```erb
<%= pie_chart Goal.group(:name).count %>
```
Column chart
```erb
<%= column_chart Task.group_by_hour_of_day(:created_at, format: "%l %P").count %>
```
Bar chart
```erb
<%= bar_chart Shirt.group(:size).sum(:price) %>
```
Area chart
```erb
<%= area_chart Visit.group_by_minute(:created_at).maximum(:load_time) %>
```
Scatter chart
```erb
<%= scatter_chart City.pluck(:size, :population) %>
```
Geo chart - *Google Charts*
```erb
<%= geo_chart Medal.group(:country).count %>
```
Timeline - *Google Charts*
```erb
<%= timeline [
["Washington", "1789-04-29", "1797-03-03"],
["Adams", "1797-03-03", "1801-03-03"],
["Jefferson", "1801-03-03", "1809-03-03"]
] %>
```
Multiple series
```erb
<%= line_chart @goals.map { |goal|
{name: goal.name, data: goal.feats.group_by_week(:created_at).count}
} %>
```
or
```erb
<%= line_chart Feat.group(:goal_id).group_by_week(:created_at).count %>
```
### Say Goodbye To Timeouts
Make your pages load super fast and stop worrying about timeouts. Give each chart its own endpoint.
```erb
<%= line_chart completed_tasks_charts_path %>
```
And in your controller, pass the data as JSON.
```ruby
class ChartsController < ApplicationController
def completed_tasks
render json: Task.group_by_day(:completed_at).count
end
end
```
For multiple series, add `chart_json` at the end.
```ruby
render json: Task.group(:goal_id).group_by_day(:completed_at).count.chart_json
```
### Options
Id, width, and height
```erb
<%= line_chart data, id: "users-chart", width: "800px", height: "500px" %>
```
Min and max values
```erb
<%= line_chart data, min: 1000, max: 5000 %>
```
`min` defaults to 0 for charts with non-negative values. Use `nil` to let the charting library decide.
Colors
```erb
<%= line_chart data, colors: ["pink", "#999"] %>
```
Stacked columns or bars
```erb
<%= column_chart data, stacked: true %>
```
Discrete axis
```erb
<%= line_chart data, discrete: true %>
```
Label (for single series)
```erb
<%= line_chart data, label: "Value" %>
```
Axis titles
```erb
<%= line_chart data, xtitle: "Time", ytitle: "Population" %>
```
You can pass options directly to the charting library with:
```erb
<%= line_chart data, library: {backgroundColor: "#eee"} %>
```
See the documentation for [Google Charts](https://developers.google.com/chart/interactive/docs/gallery), [Highcharts](http://api.highcharts.com/highcharts), and [Chart.js](http://www.chartjs.org/docs/) for more info.
### Global Options
To set options for all of your charts, create an initializer `config/initializers/chartkick.rb` with:
```ruby
Chartkick.options = {
height: "400px",
colors: ["pink", "#999"]
}
```
Customize the html
```ruby
Chartkick.options[:html] = '
Loading...
'
```
You capture the JavaScript in a content block with:
```ruby
Chartkick.options[:content_for] = :charts_js
```
Then, in your layout:
```erb
<%= yield :charts_js %> <%# Rails %>
<%= yield_content :charts_js %> <%# Padrino %>
```
This is great for including all of your JavaScript at the bottom of the page.
### Data
Pass data as a Hash or Array
```erb
<%= pie_chart({"Football" => 10, "Basketball" => 5}) %>
<%= pie_chart [["Football", 10], ["Basketball", 5]] %>
```
For multiple series, use the format
```erb
<%= line_chart [
{name: "Series A", data: series_a},
{name: "Series B", data: series_b}
] %>
```
Times can be a time, a timestamp, or a string (strings are parsed)
```erb
<%= line_chart({20.day.ago => 5, 1368174456 => 4, "2013-05-07 00:00:00 UTC" => 7}) %>
```
## Installation
Add this line to your application's Gemfile:
```ruby
gem "chartkick"
```
Next, choose your charting library.
**Note:** In the instructions below, `application.js` must be included **before** the helper methods in your views, unless using the `:content_for` option.
#### Chart.js
In `application.js`, add:
```js
//= require Chart.bundle
//= require chartkick
```
#### Google Charts
In `application.js`, add:
```js
//= require chartkick
```
In your views, before `application.js`, add:
```erb
<%= javascript_include_tag "https://www.google.com/jsapi" %>
```
#### Highcharts
Download [highcharts.js](https://code.highcharts.com/highcharts.js) into `vendor/assets/javascripts`.
In `application.js`, add:
```js
//= require highcharts
//= require chartkick
```
Works with Highcharts 2.1+
### For Sinatra
You must include `chartkick.js` manually. [Download it here](https://raw.github.com/ankane/chartkick/master/app/assets/javascripts/chartkick.js)
```html
```
### For Padrino
You must include `chartkick.js` manually. [Download it here](https://raw.github.com/ankane/chartkick/master/app/assets/javascripts/chartkick.js)
```erb
<%= javascript_include_tag "https://www.google.com/jsapi", "chartkick" %>
```
### Localization
To specify a language for Google Charts, add:
```javascript
Chartkick.configure({"language": "de"});
```
after the JavaScript files and before your charts.
## JavaScript API
Access a chart with:
```javascript
var chart = Chartkick.charts["chart-id"];
```
Get the underlying chart object with:
```javascript
chart.getChartObject();
```
You can also use:
```javascript
chart.getElement();
chart.getData();
chart.getOptions();
```
## No Ruby? No Problem
Check out [chartkick.js](https://github.com/ankane/chartkick.js)
## Tutorials
- [Make Easy Graphs and Charts on Rails with Chartkick](https://www.sitepoint.com/make-easy-graphs-and-charts-on-rails-with-chartkick/)
- [Practical Graphs on Rails: Chartkick in Practice](https://www.sitepoint.com/graphs-on-rails-chartkick-in-practice/)
## Upgrading
### 2.0
Breaking changes
- Chart.js is now the default adapter if multiple are loaded - yay open source!
- Axis types are automatically detected - no need for `discrete: true`
- Better date support - dates are no longer treated as UTC
## Credits
Chartkick uses [iso8601.js](https://github.com/Do/iso8601.js) to parse dates and times.
## History
View the [changelog](https://github.com/ankane/chartkick/blob/master/CHANGELOG.md)
Chartkick follows [Semantic Versioning](http://semver.org/)
## Contributing
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- [Report bugs](https://github.com/ankane/chartkick/issues)
- Fix bugs and [submit pull requests](https://github.com/ankane/chartkick/pulls)
- Write, clarify, or fix documentation
- Suggest or add new features