# Chartkick Create beautiful JavaScript charts with one line of Ruby. No more fighting with charting libraries! [See it in action](https://chartkick.com) :fire: For admin charts and dashboards, check out [Blazer](https://github.com/ankane/blazer/), and for advanced visualizations, check out [Vega](https://github.com/ankane/vega) :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) [![Build Status](https://github.com/ankane/chartkick/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/chartkick/actions) ## Quick Start Add this line to your application’s Gemfile: ```ruby gem "chartkick" ``` Then follow the instructions for your JavaScript setup: - [Importmap](#importmap) (Rails 7 default) - [esbuild, rollup.js, or Webpack](#esbuild-rollupjs-or-webpack) - [Webpacker](#webpacker) (Rails 6 default) - [Sprockets](#sprockets) This sets up Chartkick with [Chart.js](https://www.chartjs.org/). For other charting libraries and frameworks, see [these instructions](#additional-charting-libraries). ### Importmap In `config/importmap.rb`, add: ```ruby pin "chartkick", to: "chartkick.js" pin "Chart.bundle", to: "Chart.bundle.js" ``` And in `app/javascript/application.js`, add: ```js import "chartkick" import "Chart.bundle" ``` ### esbuild, rollup.js, or Webpack Run: ```sh yarn add chartkick chart.js ``` And in `app/javascript/application.js`, add: ```js import "chartkick/chart.js" ``` Note: For rollup.js, this requires `format: "iife"` in `rollup.config.js`. ### Webpacker Run: ```sh yarn add chartkick chart.js ``` And in `app/javascript/packs/application.js`, add: ```js import "chartkick/chart.js" ``` ### Sprockets In `app/assets/javascripts/application.js`, add: ```js //= require chartkick //= require Chart.bundle ``` ## 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 [ {name: "Workout", data: {"2021-01-01" => 3, "2021-01-02" => 4}}, {name: "Call parents", data: {"2021-01-01" => 5, "2021-01-02" => 3}} ] %> ``` or ```erb <%= line_chart Feat.group(:goal_id).group_by_week(:created_at).count %> ``` ## Data Data can be a hash, array, or URL. #### Hash ```erb <%= line_chart({"2021-01-01" => 2, "2021-01-02" => 3}) %> ``` #### Array ```erb <%= line_chart [["2021-01-01", 2], ["2021-01-02", 3]] %> ``` #### URL 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. Min and max for x-axis - *Chart.js* ```erb <%= line_chart data, xmin: "2021-01-01", xmax: "2022-01-01" %> ``` Colors ```erb <%= line_chart data, colors: ["#b00", "#666"] %> ``` 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" %> ``` Straight lines between points instead of a curve ```erb <%= line_chart data, curve: false %> ``` Hide points ```erb <%= line_chart data, points: false %> ``` Show or hide legend ```erb <%= line_chart data, legend: false %> ``` Specify legend position ```erb <%= line_chart data, legend: "bottom" %> ``` Donut chart ```erb <%= pie_chart data, donut: true %> ``` Prefix, useful for currency - *Chart.js, Highcharts* ```erb <%= line_chart data, prefix: "$" %> ``` Suffix, useful for percentages - *Chart.js, Highcharts* ```erb <%= line_chart data, suffix: "%" %> ``` Set a thousands separator - *Chart.js, Highcharts* ```erb <%= line_chart data, thousands: "," %> ``` Set a decimal separator - *Chart.js, Highcharts* ```erb <%= line_chart data, decimal: "," %> ``` Set significant digits - *Chart.js, Highcharts* ```erb <%= line_chart data, precision: 3 %> ``` Set rounding - *Chart.js, Highcharts* ```erb <%= line_chart data, round: 2 %> ``` Show insignificant zeros, useful for currency - *Chart.js, Highcharts* ```erb <%= line_chart data, round: 2, zeros: true %> ``` Friendly byte sizes - *Chart.js* ```erb <%= line_chart data, bytes: true %> ``` Specify the message when data is loading ```erb <%= line_chart data, loading: "Loading..." %> ``` Specify the message when data is empty ```erb <%= line_chart data, empty: "No data" %> ``` Refresh data from a remote source every `n` seconds ```erb <%= line_chart url, refresh: 60 %> ``` You can pass options directly to the charting library with: ```erb <%= line_chart data, library: {backgroundColor: "#eee"} %> ``` See the documentation for [Chart.js](https://www.chartjs.org/docs/), [Google Charts](https://developers.google.com/chart/interactive/docs/gallery), and [Highcharts](https://api.highcharts.com/highcharts) for more info. For Chart.js plugins, check out [this guide](guides/Chartjs-Plugins.md). To customize datasets in Chart.js, use: ```erb <%= line_chart data, dataset: {borderWidth: 10} %> ``` You can pass this option to individual series as well. ### Global Options To set options for all of your charts, create an initializer `config/initializers/chartkick.rb` with: ```ruby Chartkick.options = { height: "400px", colors: ["#b00", "#666"] } ``` Customize the html ```ruby Chartkick.options[:html] = '