{"id":1680891,"url":"https://ankane.github.io/chartkick","last_synced_at":"2025-02-25T13:31:40.136Z","repository":{"id":8346873,"uuid":"9906653","full_name":"ankane/chartkick","owner":"ankane","description":"Create beautiful JavaScript charts with one line of Ruby","archived":false,"fork":false,"pushed_at":"2025-02-19T15:56:03.000Z","size":2233,"stargazers_count":6399,"open_issues_count":6,"forks_count":571,"subscribers_count":101,"default_branch":"master","last_synced_at":"2025-02-24T22:36:59.136Z","etag":null,"topics":["chartjs","charts","google-charts","highcharts","visualization"],"latest_commit_sha":null,"homepage":"https://chartkick.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ankane.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-05-07T07:39:38.000Z","updated_at":"2025-02-23T19:57:09.000Z","dependencies_parsed_at":"2024-01-09T13:10:26.839Z","dependency_job_id":"e083d14b-fb80-45e0-b763-b59f660eecc4","html_url":"https://github.com/ankane/chartkick","commit_stats":{"total_commits":534,"total_committers":29,"mean_commits":"18.413793103448278","dds":0.4775280898876404,"last_synced_commit":"a6abb37df69e61a881cb4277eeb7ddf6e3fe6ac4"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fchartkick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fchartkick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fchartkick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fchartkick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ankane","download_url":"https://codeload.github.com/ankane/chartkick/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240632493,"owners_count":19832499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chartjs","charts","google-charts","highcharts","visualization"],"created_at":"2024-01-18T05:29:59.649Z","updated_at":"2025-02-25T13:31:40.099Z","avatar_url":"https://github.com/ankane.png","language":"Ruby","readme":"# Chartkick\n\nCreate beautiful JavaScript charts with one line of Ruby. No more fighting with charting libraries!\n\n[See it in action](https://chartkick.com)\n\n: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)\n\n: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)\n\n[![Build Status](https://github.com/ankane/chartkick/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/chartkick/actions)\n\n## Quick Start\n\nAdd this line to your application’s Gemfile:\n\n```ruby\ngem \"chartkick\"\n```\n\nThen follow the instructions for your JavaScript setup:\n\n- [Importmap](#importmap) (Rails 7+ default)\n- [Bun, esbuild, rollup.js, or Webpack](#bun-esbuild-rollupjs-or-webpack)\n- [Sprockets](#sprockets)\n\nThis sets up Chartkick with [Chart.js](https://www.chartjs.org/). For other charting libraries and frameworks, see [these instructions](#additional-charting-libraries).\n\n### Importmap\n\nIn `config/importmap.rb`, add:\n\n```ruby\npin \"chartkick\", to: \"chartkick.js\"\npin \"Chart.bundle\", to: \"Chart.bundle.js\"\n```\n\nAnd in `app/javascript/application.js`, add:\n\n```js\nimport \"chartkick\"\nimport \"Chart.bundle\"\n```\n\n### Bun, esbuild, rollup.js, or Webpack\n\nRun:\n\n```sh\nbun add chartkick chart.js\n# or\nyarn add chartkick chart.js\n```\n\nAnd in `app/javascript/application.js`, add:\n\n```js\nimport \"chartkick/chart.js\"\n```\n\n### Sprockets\n\nIn `app/assets/javascripts/application.js`, add:\n\n```js\n//= require chartkick\n//= require Chart.bundle\n```\n\n## Charts\n\nLine chart\n\n```erb\n\u003c%= line_chart User.group_by_day(:created_at).count %\u003e\n```\n\nPie chart\n\n```erb\n\u003c%= pie_chart Goal.group(:name).count %\u003e\n```\n\nColumn chart\n\n```erb\n\u003c%= column_chart Task.group_by_hour_of_day(:created_at, format: \"%l %P\").count %\u003e\n```\n\nBar chart\n\n```erb\n\u003c%= bar_chart Shirt.group(:size).sum(:price) %\u003e\n```\n\nArea chart\n\n```erb\n\u003c%= area_chart Visit.group_by_minute(:created_at).maximum(:load_time) %\u003e\n```\n\nScatter chart\n\n```erb\n\u003c%= scatter_chart City.pluck(:size, :population) %\u003e\n```\n\nGeo chart - *Google Charts*\n\n```erb\n\u003c%= geo_chart Medal.group(:country).count %\u003e\n```\n\nTimeline - *Google Charts*\n\n```erb\n\u003c%= timeline [\n  [\"Washington\", \"1789-04-29\", \"1797-03-03\"],\n  [\"Adams\", \"1797-03-03\", \"1801-03-03\"],\n  [\"Jefferson\", \"1801-03-03\", \"1809-03-03\"]\n] %\u003e\n```\n\nMultiple series\n\n```erb\n\u003c%= line_chart [\n  {name: \"Workout\", data: {\"2025-01-01\" =\u003e 3, \"2025-01-02\" =\u003e 4}},\n  {name: \"Call parents\", data: {\"2025-01-01\" =\u003e 5, \"2025-01-02\" =\u003e 3}}\n] %\u003e\n```\n\nor\n\n```erb\n\u003c%= line_chart Feat.group(:goal_id).group_by_week(:created_at).count %\u003e\n```\n\n## Data\n\nData can be a hash, array, or URL.\n\n#### Hash\n\n```erb\n\u003c%= line_chart({\"2025-01-01\" =\u003e 2, \"2025-01-02\" =\u003e 3}) %\u003e\n```\n\n#### Array\n\n```erb\n\u003c%= line_chart [[\"2025-01-01\", 2], [\"2025-01-02\", 3]] %\u003e\n```\n\n#### URL\n\nMake your pages load super fast and stop worrying about timeouts. Give each chart its own endpoint.\n\n```erb\n\u003c%= line_chart completed_tasks_charts_path %\u003e\n```\n\nAnd in your controller, pass the data as JSON.\n\n```ruby\nclass ChartsController \u003c ApplicationController\n  def completed_tasks\n    render json: Task.group_by_day(:completed_at).count\n  end\nend\n```\n\nFor multiple series, add `chart_json` at the end.\n\n```ruby\nrender json: Task.group(:goal_id).group_by_day(:completed_at).count.chart_json\n```\n\n## Options\n\nId, width, and height\n\n```erb\n\u003c%= line_chart data, id: \"users-chart\", width: \"800px\", height: \"500px\" %\u003e\n```\n\nMin and max values\n\n```erb\n\u003c%= line_chart data, min: 1000, max: 5000 %\u003e\n```\n\n`min` defaults to 0 for charts with non-negative values. Use `nil` to let the charting library decide.\n\nMin and max for x-axis - *Chart.js*\n\n```erb\n\u003c%= line_chart data, xmin: \"2025-01-01\", xmax: \"2025-02-01\" %\u003e\n```\n\nColors\n\n```erb\n\u003c%= line_chart data, colors: [\"#b00\", \"#666\"] %\u003e\n```\n\nStacked columns or bars\n\n```erb\n\u003c%= column_chart data, stacked: true %\u003e\n```\n\nDiscrete axis\n\n```erb\n\u003c%= line_chart data, discrete: true %\u003e\n```\n\nLabel (for single series)\n\n```erb\n\u003c%= line_chart data, label: \"Value\" %\u003e\n```\n\nAxis titles\n\n```erb\n\u003c%= line_chart data, xtitle: \"Time\", ytitle: \"Population\" %\u003e\n```\n\nStraight lines between points instead of a curve\n\n```erb\n\u003c%= line_chart data, curve: false %\u003e\n```\n\nHide points\n\n```erb\n\u003c%= line_chart data, points: false %\u003e\n```\n\nShow or hide legend\n\n```erb\n\u003c%= line_chart data, legend: false %\u003e\n```\n\nSpecify legend position\n\n```erb\n\u003c%= line_chart data, legend: \"bottom\" %\u003e\n```\n\nDonut chart\n\n```erb\n\u003c%= pie_chart data, donut: true %\u003e\n```\n\nPrefix, useful for currency - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, prefix: \"$\" %\u003e\n```\n\nSuffix, useful for percentages - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, suffix: \"%\" %\u003e\n```\n\nSet a thousands separator - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, thousands: \",\" %\u003e\n```\n\nSet a decimal separator - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, decimal: \",\" %\u003e\n```\n\nSet significant digits - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, precision: 3 %\u003e\n```\n\nSet rounding - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, round: 2 %\u003e\n```\n\nShow insignificant zeros, useful for currency - *Chart.js, Highcharts*\n\n```erb\n\u003c%= line_chart data, round: 2, zeros: true %\u003e\n```\n\nFriendly byte sizes - *Chart.js*\n\n```erb\n\u003c%= line_chart data, bytes: true %\u003e\n```\n\nSpecify the message when data is loading\n\n```erb\n\u003c%= line_chart data, loading: \"Loading...\" %\u003e\n```\n\nSpecify the message when data is empty\n\n```erb\n\u003c%= line_chart data, empty: \"No data\" %\u003e\n```\n\nRefresh data from a remote source every `n` seconds\n\n```erb\n\u003c%= line_chart url, refresh: 60 %\u003e\n```\n\nYou can pass options directly to the charting library with:\n\n```erb\n\u003c%= line_chart data, library: {backgroundColor: \"#eee\"} %\u003e\n```\n\nSee 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).\n\nTo customize datasets in Chart.js, use:\n\n```erb\n\u003c%= line_chart data, dataset: {borderWidth: 10} %\u003e\n```\n\nYou can pass this option to individual series as well.\n\n### Global Options\n\nTo set options for all of your charts, create an initializer `config/initializers/chartkick.rb` with:\n\n```ruby\nChartkick.options = {\n  height: \"400px\",\n  colors: [\"#b00\", \"#666\"]\n}\n```\n\nCustomize the html\n\n```ruby\nChartkick.options[:html] = '\u003cdiv id=\"%{id}\" style=\"height: %{height};\"\u003e%{loading}\u003c/div\u003e'\n```\n\nYou capture the JavaScript in a content block with:\n\n```ruby\nChartkick.options[:content_for] = :charts_js\n```\n\nThen, in your layout, use:\n\n```erb\n\u003c%= yield :charts_js %\u003e\n```\n\nFor Padrino, use `yield_content` instead of `yield`.\n\nThis is great for including all of your JavaScript at the bottom of the page.\n\n### Multiple Series\n\nYou can pass a few options with a series:\n\n- `name`\n- `data`\n- `color`\n- `dataset` - *Chart.js only*\n- `points` - *Chart.js only*\n- `curve` - *Chart.js only*\n\n### Code\n\nIf you want to use the charting library directly, get the code with:\n\n```erb\n\u003c%= line_chart data, code: true %\u003e\n```\n\nThe code will be logged to the JavaScript console. JavaScript functions cannot be logged, so it may not be identical.\n\n### Download Charts\n\n*Chart.js only*\n\nGive users the ability to download charts. It all happens in the browser - no server-side code needed.\n\n```erb\n\u003c%= line_chart data, download: true %\u003e\n```\n\nSafari will open the image in a new window instead of downloading.\n\nSet the filename\n\n```erb\n\u003c%= line_chart data, download: {filename: \"boom\"} %\u003e\n```\n\nSet the background color\n\n```erb\n\u003c%= line_chart data, download: {background: \"#ffffff\"} %\u003e\n```\n\nSet title\n\n```erb\n\u003c%= line_chart data, title: \"Awesome chart\" %\u003e\n```\n\n## Additional Charting Libraries\n\n- [Google Charts](#google-charts)\n- [Highcharts](#highcharts)\n\n### Google Charts\n\nIn your layout or views, add:\n\n```erb\n\u003c%= javascript_include_tag \"https://www.gstatic.com/charts/loader.js\" %\u003e\n```\n\nFor Importmap (Rails 7+ default), in `config/importmap.rb`, add:\n\n```ruby\npin \"chartkick\", to: \"chartkick.js\"\n```\n\nAnd in `app/javascript/application.js`, add:\n\n```js\nimport \"chartkick\"\n```\n\nFor Bun, esbuild, rollup.js, or Webpack, run:\n\n```sh\nbun add chartkick\n# or\nyarn add chartkick\n```\n\nAnd in `app/javascript/packs/application.js`, add:\n\n```js\nimport \"chartkick\"\n```\n\nFor Sprockets, in `app/assets/javascripts/application.js`, add:\n\n```js\n//= require chartkick\n```\n\nTo specify a language or Google Maps API key, use:\n\n```js\nChartkick.configure({language: \"de\", mapsApiKey: \"...\"})\n```\n\nbefore your charts.\n\n### Highcharts\n\nFor Importmap (Rails 7+ default), run:\n\n```sh\nbin/importmap pin highcharts --download\n```\n\nAnd in `config/importmap.rb`, add:\n\n```ruby\npin \"chartkick\", to: \"chartkick.js\"\n```\n\nAnd in `app/javascript/application.js`, add:\n\n```js\nimport \"chartkick\"\nimport Highcharts from \"highcharts\"\n\nwindow.Highcharts = Highcharts\n```\n\nFor Bun, esbuild, rollup.js, or Webpack, run:\n\n```sh\nbun add chartkick highcharts\n# or\nyarn add chartkick highcharts\n```\n\nAnd in `app/javascript/packs/application.js`, add:\n\n```js\nimport \"chartkick/highcharts\"\n```\n\nFor Sprockets, download [highcharts.js](https://code.highcharts.com/highcharts.js) into `vendor/assets/javascripts` (or use `yarn add highcharts`), and in `app/assets/javascripts/application.js`, add:\n\n```js\n//= require chartkick\n//= require highcharts\n```\n\n### Multiple Libraries\n\nIf more than one charting library is loaded, choose between them with:\n\n```erb\n\u003c%= line_chart data, adapter: \"google\" %\u003e \u003c!-- or highcharts or chartjs --\u003e\n```\n\n## Sinatra and Padrino\n\nDownload [chartkick.js](https://raw.githubusercontent.com/ankane/chartkick/master/vendor/assets/javascripts/chartkick.js) and include it manually.\n\n```html\n\u003cscript src=\"chartkick.js\"\u003e\u003c/script\u003e\n```\n\nThen include the charting library.\n\nChart.js - download [Chart.js](https://unpkg.com/chart.js@4/dist/chart.umd.js) and the [date-fns adapter bundle](https://unpkg.com/chartjs-adapter-date-fns@3/dist/chartjs-adapter-date-fns.bundle.js)\n\n```html\n\u003cscript src=\"chart.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"chartjs-adapter-date-fns.bundle.js\"\u003e\u003c/script\u003e\n```\n\nGoogle Charts\n\n```html\n\u003cscript src=\"https://www.gstatic.com/charts/loader.js\"\u003e\u003c/script\u003e\n```\n\nHighcharts - download [highcharts.js](https://code.highcharts.com/highcharts.js)\n\n```html\n\u003cscript src=\"highcharts.js\"\u003e\u003c/script\u003e\n```\n\n## JavaScript API\n\nAccess a chart with:\n\n```javascript\nvar chart = Chartkick.charts[\"chart-id\"]\n```\n\nGet the underlying chart object with:\n\n```javascript\nchart.getChartObject()\n```\n\nYou can also use:\n\n```javascript\nchart.getElement()\nchart.getData()\nchart.getOptions()\nchart.getAdapter()\n```\n\nUpdate the data with:\n\n```javascript\nchart.updateData(newData)\n```\n\nYou can also specify new options:\n\n```javascript\nchart.setOptions(newOptions)\n// or\nchart.updateData(newData, newOptions)\n```\n\nRefresh the data from a remote source:\n\n```javascript\nchart.refreshData()\n```\n\nRedraw the chart with:\n\n```javascript\nchart.redraw()\n```\n\nDestroy the chart with:\n\n```javascript\nchart.destroy()\n```\n\nLoop over charts with:\n\n```javascript\nChartkick.eachChart(function (chart) {\n  // do something\n})\n```\n\n## Content Security Policy (CSP)\n\nCheck out [how to configure CSP](https://github.com/ankane/chartkick/blob/master/guides/Content-Security-Policy.md)\n\n## Tutorials\n\n- [Charts with Chartkick and Groupdate](https://gorails.com/episodes/charts-with-chartkick-and-groupdate)\n- [Creando gráficos en Ruby on Rails con Chartkick y Chart.js](https://www.youtube.com/watch?v=W92AlkwQn3M)\n- [Make Easy Graphs and Charts on Rails with Chartkick](https://www.sitepoint.com/make-easy-graphs-and-charts-on-rails-with-chartkick/)\n- [Practical Graphs on Rails: Chartkick in Practice](https://www.sitepoint.com/graphs-on-rails-chartkick-in-practice/)\n\n## History\n\nView the [changelog](https://github.com/ankane/chartkick/blob/master/CHANGELOG.md)\n\n## Contributing\n\nEveryone is encouraged to help improve this project. Here are a few ways you can help:\n\n- [Report bugs](https://github.com/ankane/chartkick/issues)\n- Fix bugs and [submit pull requests](https://github.com/ankane/chartkick/pulls)\n- Write, clarify, or fix documentation\n- Suggest or add new features\n\nTo get started with development:\n\n```sh\ngit clone https://github.com/ankane/chartkick.git\ncd chartkick\nbundle install\nbundle exec rake test\n```\n","funding_links":[],"categories":["Data Visualization"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/ankane.github.io%2Fchartkick","html_url":"https://awesome.ecosyste.ms/projects/ankane.github.io%2Fchartkick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/ankane.github.io%2Fchartkick/lists"}