The project is in a healthy, maintained state
Create beautiful, interactive, and responsive web charts in ruby app powered by apexcharts.js.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
 Dependencies

Development

Runtime

~> 0.2.8
 Project Readme

Gem Version Build Test Status Downloads Commits License codebeat badge README Score
Buy Me a Coffee at ko-fi.com

About

ApexCharts.RB is a ruby charting library that's going to give your ruby app beautiful, interactive, and responsive charts powered by ApexCharts.JS. On top of those sweet advantages, you'll also get extra features that you can't get by just including ApexCharts.JS to your ruby app, namely view/template helpers for creating charts, options shortcuts, application wide default options, reusable custom theme palette, and so on.

Trusted By

Organization/Company Use Case
Reports/charts related to Operating Room utilization statistics
Enterprise dashboards to visualize account receivables data
Ticket sales for clients (visitor attractions and tour operators)

If your organization/company uses ApexCharts.RB in production, please comment on this discussion.

README Versions

This README might not be for the version you use.
Choose the right README:

v0.1.11 | v0.1.10 | v0.1.9 | v0.1.8 | v0.1.7 | v0.1.6 | v0.1.5 | v0.1.4 | v0.1.3 | v0.1.2 | v0.1.1

Table of Contents

  • About
  • Trusted By
  • README Versions
  • Table of Contents
  • Usage
    • Cartesian Charts
      • Line Chart
      • Stepline Chart
      • Area Chart
      • Column Chart
      • Bar Chart
      • Range Bar Chart
      • Scatter Chart
      • Candlestick Chart
      • Box Plot Chart
      • Mixed Charts
      • Syncing Charts
      • Brush Chart
      • Annotations
      • Multiple Y-Axes
    • Heatmap Chart
    • Radar Chart
    • Bubble Chart
    • Polar Charts
      • Pie Chart
      • Donut Chart
      • Radial Bar Chart
  • Data Formats
    • Cartesian Charts
      • Candlestick Chart
      • Box Plot Chart
    • Heatmap Chart
    • Radar Chart
    • Bubble Chart
    • Polar Charts
  • Options
    • Global Options
    • Formatter Function
    • Defer Chart Rendering
  • Schema
  • Reusable Custom Palette
  • Use Alongside Other Charting Libraries
    • Alongside Chartkick
      • Chartkick (Chart.js) and ApexCharts
      • Chartkick (Google Charts) and ApexCharts
      • Chartkick (Highcharts) and ApexCharts
  • Installation
  • Web Support
    • Rails
    • Sinatra
    • Plain HTML+ERB (Without Framework)
  • Contributing
  • License
  • Like the charts?

Usage

Cartesian Charts

Example series used for cartesian charts:

<% series = [
  {name: "Inactive", data: @inactive_properties},
  {name: "Active", data: @active_properties}
] %>

To build the data, you can use gem groupdate.
In my case, it was:

@inactive_properties = Property.inactive.group_by_week(:created_at).count
@active_properties = Property.active.group_by_week(:created_at).count

and I'll get the data in this format:

{
  Sun, 29 Jul 2018=>1,
  Sun, 05 Aug 2018=>6,
  ..
}

PS: Property can be any model you have and inactive and active are just some normal ActiveRecord scopes. Keep scrolling down to see accepted data formats.

Example options used for cartesian charts:

<% options = {
  title: 'Properties Growth',
  subtitle: 'Grouped Per Week',
  xtitle: 'Week',
  ytitle: 'Properties',
  stacked: true
} %>

Line Chart

<%= line_chart(series, options) %>

Example Line Chart

Stepline Chart

<%= line_chart(series, {**options, theme: 'palette7', curve: 'stepline'}) %>

Example Stepline Chart

Area Chart

<%= area_chart(series, {**options, theme: 'palette5'}) %>

Example Area Chart

Column Chart

<%= column_chart(series, {**options, theme: 'palette4'}) %>

Example Column Chart

Bar Chart

<%= bar_chart(series, {**options, xtitle: 'Properties', ytitle: 'Week', height: 800, theme: 'palette7'}) %>

Example Bar Chart

Range Bar Chart

<% range_bar_series = [{
      name: "Series A",
      data: {
        'A' => [1, 5],
        'B' => [4, 6],
        'C' => [5, 8],
        'D' => [3, 11]
      }
    }, {
      name: "Series B",
      data: {
        'A' => [2, 6],
        'B' => [1, 3],
        'C' => [7, 8],
        'D' => [5, 9]
      }
  }]
%>

<%= range_bar_chart(range_bar_series, theme: 'palette3') %>

Example Range Bar Chart

Scatter Chart

<%= scatter_chart(series, {**options, theme: 'palette3'}) %>

Example Scatter Chart

Candlestick Chart

Candlestick chart is typically used to illustrate movements in the price of a financial instrument over time. This chart is also popular by the name "ohlc chart". That's why you can call it with ohlc_chart too.
So, here's how you make it.

Given:

<%
  require 'date'

  def candlestick_data
    @acc = rand(6570..6650)
    60.times.map {|i| [Date.today - 60 + i, ohlc] }.to_h
  end

  def ohlc
    open = @acc + rand(-20..20)
    high = open + rand(0..100)
    low = open - rand(0..100)
    @acc = close = open + rand(-((high-low)/3)..((high-low)/2))
    [open, high, low, close]
  end

  candlestick_options = {
    plot_options: {
      candlestick: {
        colors: {
          upward: '#3C90EB',
          downward: '#DF7D46'
        }
      }
    }
  }
%>

You can make candlestick chart with this:

<%= candlestick_chart(candlestick_data, candlestick_options) %>

Example Candlestick Chart

Box Plot Chart

Given:

<%
  require 'date'

  def box_plot_data
    20.times.map {|i| [Date.today - 20 + i, box_plot_datum] }.to_h
  end

  def box_plot_datum
    level = 1000
    max = level + rand(50..300)
    min = level - rand(50..300)
    q1 = min + rand(10..50)
    q3 = max - rand(10..50)
    median = (min + q1 + q3 + max)/4
    [min, q1, median, q3, max]
  end

  box_plot_options = {
    plot_options: {
      boxPlot: {
        colors: {
          upper: '#aaffaa',
          lower: '#ffaaFF'
        }
      }
    }
  }
%>

You can make box plot chart with this:

<%= box_plot_chart(box_plot_data, box_plot_options) %>

Example Box Plot Chart

Mixed Charts

You can mix charts by using mixed_charts or combo_charts methods. For example, given that:

@total_properties = Property.group_by_week(:created_at).count

and

<% total_series = {
  name: "Total", data: @total_properties
} %>

you can do this:

<%= combo_charts({**options, theme: 'palette4', stacked: false, data_labels: false}) do %>
  <% line_chart(total_series) %>
  <% area_chart(series.last) %>
  <% column_chart(series.first) %>
<% end %>

Example Mixed Charts

Syncing Charts

You can synchronize charts by using syncing_charts or synchronized_charts methods. For example:

<%= syncing_charts(chart: {toolbar: false}, height: 250, style: 'display: inline-block; width: 32%;') do %>
  <% mixed_charts(theme: 'palette4', data_labels: false) do %>
    <% line_chart({name: "Total", data: @total_properties}) %>
    <% area_chart({name: "Active", data: @active_properties}) %>
  <% end %>
  <% area_chart({name: "Active", data: @active_properties}, theme: 'palette6') %>
  <% line_chart({name: "Inactive", data: @active_properties}, theme: 'palette8') %>
<% end %>

Example Syncing Charts

Brush Chart

<%= area_chart(total_series, {
  **options, chart_id: 'the-chart', xtitle: nil, theme: 'palette2'
}) %>
<%= mixed_charts(brush_target: 'the-chart', theme: 'palette7') do %>
  <% column_chart(series.first) %>
  <% line_chart(series.last) %>
<% end %>

Example Brush Chart

Annotations

All cartesian charts can have annotations, for example:

<%= area_chart(series, {**options, theme: 'palette9'}) do %>
  <% x_annotation(value: ('2019-01-06'..'2019-02-24'), text: "Busy Time", color: 'green') %>
  <% y_annotation(value: 29, text: "Max Properties", color: 'blue') %>
  <% point_annotation(value: ['2018-10-07', 24], text: "First Peak", color: 'magenta') %>
<% end %>

Example Area Chart with Annotations

Multiple Y-Axes

There's no fancy shortcut for multiple Y axes yet, but it is allowed. Here is an example for that.

<% series = [
    {
      name: 'Income',
      type: 'column',
      data: [1.4, 2, 2.5, 1.5, 2.5, 2.8, 3.8, 4.6]
    },
    {
      name: 'Cashflow',
      type: 'column',
      data: [1.1, 3, 3.1, 4, 4.1, 4.9, 6.5, 8.5]
    },
    {
      name: 'Revenue',
      data: [20, 29, 37, 36, 44, 45, 50, 58]
    }
  ]

  xaxis = {
    title: {text: 'Year'},
    categories: [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016]
  }

  yaxis = [
    {title: {text: "Income"}},
    {
      title: {text: "Operating Cashflow"},
      opposite: true,
      seriesName: 'Cashflow'
    },
    {
      title: {text: "Revenue"},
      opposite: true,
      seriesName: 'Revenue'
    }
  ]
%>
<%= line_chart(series, xaxis: xaxis, yaxis: yaxis) %>

Example Chart with multiple Y-Axes

Heatmap Chart

<% heatmap_series = 17.downto(10).map do |n|
  {
    name: "#{n}:00",
    data: 15.times.map do |i|
      ["W#{i+1}", rand(90)]
    end.to_h
  }
end %>
<%= heatmap_chart(heatmap_series) %>

Example Heatmap Chart

Radar Chart

<% radar_series = [
  {
    name: "What it should be",
    data: { "Code review"=>10, "Issues"=>5, "Pull request"=>25, "Commits"=>60 }
  },
  {
    name: "What it really is",
    data: { "Code review"=>1, "Issues"=>3, "Pull request"=>7, "Commits"=>89 }
  }
] %>
<%= radar_chart(
  radar_series,
  {title: "GitHub Radar", markers: {size: 4}, theme: 'palette4'}
) %>

Example Radar Chart

Bubble Chart

<% bubble_series = (1..4).map do |n|
  {
    name: "Bubble#{n}",
    data: 20.times.map{[rand(750),rand(10..60),rand(70)]}
  }
end %>
<%= bubble_chart(bubble_series, data_labels: false, theme: 'palette6') %>

Example Bubble Chart

Polar Charts

Pie Chart

<%= pie_chart([
  {name: "Series A", data: 25},
  {name: "Series B", data: 100},
  {name: "Series C", data: 200},
  {name: "Series D", data: 125}
], legend: "left") %>

Example Pie Chart

Donut Chart

<%= donut_chart([25, 100, 200, 125], theme: 'palette4') %>

Example Pie Chart

Radial Bar Chart

Also called circle_chart.

<%= radial_bar_chart([
  {name: "Circle A", data: 25},
  {name: "Circle B", data: 40},
  {name: "Circle C", data: 80},
  {name: "Circle D", data: 45}
], legend: true) %>

Example Circle Chart

Data Formats

Cartesian Charts

The data format for line, stepline, area, column, bar, and scatter charts should be in following format per-series:

{
  <x value> => <y value>,
  <x value> => <y value>,
  ...
}

or this:

[
  [<x value>, <y value>],
  [<x value>, <y value>],
  ...
]

Candlestick Chart

Candlestick chart is just like other cartesian charts, only the y value is an array of 4 members which called the OHLC (Open-High-Low-Close):

{
  <x value> => [<Open>, <High>, <Low>, <Close>],
  <x value> => [<Open>, <High>, <Low>, <Close>],
  ...
}

or this:

[
  [<x value>, [<Open>, <High>, <Low>, <Close>]],
  [<x value>, [<Open>, <High>, <Low>, <Close>]],
  ...
]

Box Plot Chart

Box plot chart is similar to candlestick chart, only the y value is an array of 5 members (Minimum-First Quartile-Median-Third Quartile-Maximum):

{
  <x value> => [<Min>, <Q1>, <Median>, <Q3>, <Max>],
  <x value> => [<Min>, <Q1>, <Median>, <Q3>, <Max>],
  ...
}

or this:

[
  [<x value>, [<Min>, <Q1>, <Median>, <Q3>, <Max>]],
  [<x value>, [<Min>, <Q1>, <Median>, <Q3>, <Max>]],
  ...
]

Heatmap Chart

The data format for heatmap chart per-series is similar to cartesian charts. But instead of y values they are heat values. The series names will be the y values.

{
  <x value> => <heat value>,
  <x value> => <heat value>,
  ...
}

or this:

[
  [<x value>, <heat value>],
  [<x value>, <heat value>],
  ...
]

Radar Chart

The data format for radar chart per-series is also similar but instead of x values they are variables and instead of y values they are the only values for the variables with type of Numeric.

{
  <variable> => <value>,
  <variable> => <value>,
  ...
}

or this:

[
  [<variable>, <value>],
  [<variable>, <value>],
  ...
]

Bubble Chart

Bubble chart is similar to scatter chart, only they have one more value for bubble size:

[
  [<x value>, <bubble size>, <y value>],
  [<x value>, <bubble size>, <y value>],
  ...
]

Polar Charts

The data format for donut, pie, and radial bar are the simplest. They are just any single value of type Numeric.

Options

ApexCharts.RB supports all options from ApexCharts.JS, but instead of camelCase, you can write them in snake_case.

ApexCharts.RB also provides shortcuts to some ApexCharts.JS options, such as title. In ApexCharts.JS you would have to write

title: { text: "Some title" }

In ApexCharts.RB you can write

title: "Some title"

if you just want to add the text.

xtitle and ytitle are even greater shortcuts. Instead of

xaxis: { title: { text: "x title" } }

you can write

xtitle: "x title"
options = {
  animations: false, # Shortcut for chart: { animations: { enabled: false } }
  chart: {
    fontFamily: "Helvetica, Arial, sans-serif",
    toolbar: {
      show: false
    }
  },
  curve: "straight", # Shortcut for stroke: { curve: "straight" }
  markers: {
    size: 5,
  },
  tooltip: false, # Shortcut for tooltip: { enabled: false }
  xtitle: "Boars per capita"
}

These options can be passed to any chart helper like <%= line_chart(series, options) %>.

Global Options

To use default options globally, you can specify config for default options before calling your charts. In Rails, put it in initializers directory. For example:

# config/initializers/apexcharts.rb

ApexCharts.config.default_options = {
  data_labels: false,
  tootip: true,
  theme: 'my-theme'
}

All charts will then automatically pick up these global options, which can be overwritten individually by any options passed to the relevant chart helper.

Formatter Function

To use a simple formatter function (e.g. formatter in tooltip, data_labels, and labels), you can add functionable-json to your Gemfile and use it like so:

<%= area_chart series, tooltip: {y: {formatter: function(val) { return '$' + parseFloat(val).toLocaleString() }}} %>

Or, without the functionable-json gem, use function as object as follows:

<%= area_chart series, tooltip: {y: {formatter: {function: {args: "val", body: "return '$' + parseFloat(val).toLocaleString();"}} }} %>

Defer Chart Rendering

It's possible to defer chart rendering by passing the argument defer: true as options.

<%= line_chart series, defer: true %>

Schema

To use dry-schema as an alternative options schema, you can specify the following config before calling your charts:

ApexCharts.config.schema = :dry_schema

or

ApexCharts.configure do |config|
  config.schema = :dry_schema
end

Reusable Custom Palette

To create palettes to be used anywhere on your any parts of your app, you can use ApexCharts::Theme.create.

For example, in rails app, you would write it in initializers:

# config/initializers/apexcharts.rb
ApexCharts::Theme.create "rainbow", ["#ff0000", "#00ff00", "#0000ff"]

and later somewhere in your app views:

# e.g. app/views/home/index.html.slim
...
= line_chart chart_data, theme: "rainbow"
...

If later for some reason I don't know you want to destroy the palette you can use:

ApexCharts::Theme.destroy "rainbow"

Use Alongside Other Charting Libraries

You can prefix the helper methods name with your chosen words to avoid name clashing with other charting libraries (e.g. chartkick, google_charts, etc.) you already use. Just set the APEXCHARTS_PREFIX environment variable to a string before you start your app server, say, 'awesome_' and then on your views/templates use the chart helpers as awesome_line_chart, awesome_area_chart, and so on.

Besides setting the environtment variable, if you just want a quick prefix, you can instead do this on your Gemfile:

gem 'apexcharts', require: 'apex_charts/prefix_with_apex'

and you'll get apex_line_chart, apex_area_chart, etc.

The prefix you set only applies to the outer chart helpers. The inner chart helpers is not prefixed. For example:

<%= awesome_syncing_chart(syncing_options) do %>
  <% combo_chart(mixed_options) do %>
    <% line_chart(line_series) %>
    <% area_chart(area_series) %>
  <% end %>
<% end %>

Alongside Chartkick

Given:

<% series = [
  {name: 'Verified', data: @verified_users},
  {name: 'Unverified', data: @unverified_users}
] %>
<% options = {
  legend: 'bottom', title: 'Users Grouped By Week For The Last 1 Year',
  ytitle: 'Users', width: '100%', height: '300px'
} %>

Chartkick (Chart.js) and ApexCharts

<div style="display: inline-block; width: 48%;">
  <%= area_chart(series, {**options, adapter: 'chartjs'}) %>
</div>
<div style="display: inline-block; width: 48%;">
  <%= apex_area_chart(series, options) %>
</div>

Chartkick (Chart.js) And ApexCharts

Chartkick (Google Charts) and ApexCharts

<div style="display: inline-block; width: 48%;">
  <%= area_chart(series, {**options, adapter: 'google'}) %>
</div>

<div style="display: inline-block; width: 48%;">
  <%= apex_area_chart(series, options) %>
</div>

Chartkick (Google Charts) And ApexCharts

Chartkick (Highcharts) and ApexCharts

<div style="display: inline-block; width: 48%;">
  <%= area_chart(series, {**options, adapter: 'highcharts'}) %>
</div>

<div style="display: inline-block; width: 48%;">
  <%= apex_area_chart(series, options) %>
</div>

Chartkick (Highcharts) And ApexCharts

Installation

Add this line to your application's Gemfile:

gem 'groupdate' # optional
gem 'apexcharts'

And then execute:

$ bundle

Web Support

Rails

Require it in your app/assets/javascripts/application.js.

//= require apexcharts

Or, if you use webpacker, you can run:

$ yarn add apexcharts

and then require it in your app/javascript/packs/application.js.

// AMD
window.ApexCharts = require("apexcharts") // expose to window

// or
// ES6
import ApexCharts from 'apexcharts'
window.ApexCharts = ApexCharts

Sinatra

Require it after you require 'sinatra/base' and add helper Sinatra::ApexCharts in the class that inherits from Sinatra::Base.

require 'sinatra/base'
require 'apexcharts'

class SimpleApp < Sinatra::Base
  helpers Sinatra::ApexCharts
end

To add the asset (ApexCharts.JS), include a script tag in your template as follows:

template :index do
  <<~INDEX
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
    <% series = {...} %>
    <%= pie_chart(series, legend: "left") %>
  INDEX
end

For more details, see example.

Plain HTML+ERB (Without Framework)

Insert this to the top of your .html.erb files:

<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<% require 'apexcharts' %>
<% include ApexCharts::Helper %>

You can then generate the static html page with e.g.

$ erb sample.html.erb > sample.html

Contributing

Everyone is encouraged to help improve this project by:

  • Reporting bugs
  • Fixing bugs and submiting pull requests
  • Fixing documentation
  • Suggesting new features

License

The gem is available as open source under the terms of the MIT License.

Articles