Create beautiful JavaScript charts with one line of Ruby

Overview

Chartkick

Create beautiful JavaScript charts with one line of Ruby. No more fighting with charting libraries!

See it in action

Chartkick 4.0 was recently released - see how to upgrade

🔥 For admin charts and dashboards, check out Blazer, and for advanced visualizations, check out Vega

💕 A perfect companion to Groupdate, Hightop, and ActiveMedian

Build Status

Quick Start

Add this line to your application’s Gemfile:

gem "chartkick"

For Rails 6 / Webpacker, run:

yarn add chartkick chart.js

And in app/javascript/packs/application.js, add:

import "chartkick/chart.js"

For Rails 5 / Sprockets, in app/assets/javascripts/application.js, add:

//= require chartkick
//= require Chart.bundle

This sets up Chartkick with Chart.js. For other charting libraries, see detailed instructions.

Charts

Line chart

<%= line_chart User.group_by_day(:created_at).count %>

Pie chart

<%= pie_chart Goal.group(:name).count %>

Column chart

<%= column_chart Task.group_by_hour_of_day(:created_at, format: "%l %P").count %>

Bar chart

<%= bar_chart Shirt.group(:size).sum(:price) %>

Area chart

<%= area_chart Visit.group_by_minute(:created_at).maximum(:load_time) %>

Scatter chart

<%= scatter_chart City.pluck(:size, :population) %>

Geo chart - Google Charts

<%= geo_chart Medal.group(:country).count %>

Timeline - Google Charts

<%= timeline [
  ["Washington", "1789-04-29", "1797-03-03"],
  ["Adams", "1797-03-03", "1801-03-03"],
  ["Jefferson", "1801-03-03", "1809-03-03"]
] %>

Multiple series

<%= line_chart @goals.map { |goal|
    {name: goal.name, data: goal.feats.group_by_week(:created_at).count}
} %>

or

<%= 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.

<%= line_chart completed_tasks_charts_path %>

And in your controller, pass the data as JSON.

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.

render json: Task.group(:goal_id).group_by_day(:completed_at).count.chart_json

Options

Id, width, and height

<%= line_chart data, id: "users-chart", width: "800px", height: "500px" %>

Min and max values

<%= 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

<%= line_chart data, xmin: "2021-01-01", xmax: "2022-01-01" %>

Colors

<%= line_chart data, colors: ["#b00", "#666"] %>

Stacked columns or bars

<%= column_chart data, stacked: true %>

Discrete axis

<%= line_chart data, discrete: true %>

Label (for single series)

<%= line_chart data, label: "Value" %>

Axis titles

<%= line_chart data, xtitle: "Time", ytitle: "Population" %>

Straight lines between points instead of a curve

<%= line_chart data, curve: false %>

Hide points

<%= line_chart data, points: false %>

Show or hide legend

<%= line_chart data, legend: false %>

Specify legend position

<%= line_chart data, legend: "bottom" %>

Donut chart

<%= pie_chart data, donut: true %>

Prefix, useful for currency - Chart.js, Highcharts

<%= line_chart data, prefix: "$" %>

Suffix, useful for percentages - Chart.js, Highcharts

<%= line_chart data, suffix: "%" %>

Set a thousands separator - Chart.js, Highcharts

<%= line_chart data, thousands: "," %>

Set a decimal separator - Chart.js, Highcharts

<%= line_chart data, decimal: "," %>

Set significant digits - Chart.js, Highcharts

<%= line_chart data, precision: 3 %>

Set rounding - Chart.js, Highcharts

<%= line_chart data, round: 2 %>

Show insignificant zeros, useful for currency - Chart.js, Highcharts

<%= line_chart data, round: 2, zeros: true %>

Friendly byte sizes - Chart.js

<%= line_chart data, bytes: true %>

Specify the message when data is loading

<%= line_chart data, loading: "Loading..." %>

Specify the message when data is empty

<%= line_chart data, empty: "No data" %>

Refresh data from a remote source every n seconds

<%= line_chart url, refresh: 60 %>

You can pass options directly to the charting library with:

<%= line_chart data, library: {backgroundColor: "#eee"} %>

See the documentation for Chart.js, Google Charts, and Highcharts for more info.

To customize datasets in Chart.js, use:

<%= 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:

Chartkick.options = {
  height: "400px",
  colors: ["#b00", "#666"]
}

Customize the html

Chartkick.options[:html] = '<div id="%{id}" style="height: %{height};">%{loading}</div>'

You capture the JavaScript in a content block with:

Chartkick.options[:content_for] = :charts_js

Then, in your layout, use:

<%= yield :charts_js %>

For Padrino, use yield_content instead of yield.

This is great for including all of your JavaScript at the bottom of the page.

Data

Pass data as a hash or array

<%= pie_chart({"Football" => 10, "Basketball" => 5}) %>
<%= pie_chart [["Football", 10], ["Basketball", 5]] %>

For multiple series, use the format

<%= line_chart [
  {name: "Series A", data: series_a},
  {name: "Series B", data: series_b}
] %>

Times can be a time or a string (strings are parsed)

<%= line_chart({20.day.ago => 5, "2021-05-07 00:00:00 UTC" => 7}) %>

Multiple Series

You can pass a few options with a series:

  • name
  • data
  • color
  • dataset - Chart.js only
  • points - Chart.js only
  • curve - Chart.js only

Code

If you want to use the charting library directly, get the code with:

<%= line_chart data, code: true %>

The code will be logged to the JavaScript console. JavaScript functions cannot be logged, so it may not be identical.

Download Charts

Chart.js only

Give users the ability to download charts. It all happens in the browser - no server-side code needed.

<%= line_chart data, download: true %>

Safari will open the image in a new window instead of downloading.

Set the filename

<%= line_chart data, download: {filename: "boom"} %>

Set the background color

<%= line_chart data, download: {background: "#ffffff"} %>

Set title

<%= line_chart data, title: "Awesome chart" %>

Installation

Add this line to your application's Gemfile:

gem "chartkick"

Next, choose your charting library.

Chart.js

For Rails 6 / Webpacker, run:

yarn add chartkick chart.js

And in app/javascript/packs/application.js, add:

import "chartkick/chart.js"

For Rails 5 / Sprockets, in app/assets/javascripts/application.js, add:

//= require chartkick
//= require Chart.bundle

Google Charts

In your layout or views, add:

<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>

For Rails 6 / Webpacker, run:

yarn add chartkick

And in app/javascript/packs/application.js, add:

import "chartkick"

For Rails 5 / Sprockets, in app/assets/javascripts/application.js, add:

//= require chartkick

To specify a language or Google Maps API key, use:

Chartkick.configure({language: "de", mapsApiKey: "..."})

before your charts.

Highcharts

For Rails 6 / Webpacker, run:

yarn add chartkick highcharts

And in app/javascript/packs/application.js, add:

import "chartkick/highcharts"

For Rails 5 / Sprockets, download highcharts.js into vendor/assets/javascripts (or use yarn add highcharts in Rails 5.1+), and in app/assets/javascripts/application.js, add:

//= require chartkick
//= require highcharts

Sinatra and Padrino

Download chartkick.js and include it manually.

<script src="chartkick.js"></script>

Then include the charting library.

Chart.js - download Chart.js and the date-fns adapter bundle

<script src="chart.js"></script>
<script src="chartjs-adapter-date-fns.bundle.js"></script>

Google Charts

<script src="https://www.gstatic.com/charts/loader.js"></script>

Highcharts - download highcharts.js

<script src="highcharts.js"></script>

Multiple Libraries

If more than one charting library is loaded, choose between them with:

<%= line_chart data, adapter: "google" %> <!-- or highcharts or chartjs -->

JavaScript API

Access a chart with:

var chart = Chartkick.charts["chart-id"]

Get the underlying chart object with:

chart.getChartObject()

You can also use:

chart.getElement()
chart.getData()
chart.getOptions()
chart.getAdapter()

Update the data with:

chart.updateData(newData)

You can also specify new options:

chart.setOptions(newOptions)
// or
chart.updateData(newData, newOptions)

Refresh the data from a remote source:

chart.refreshData()

Redraw the chart with:

chart.redraw()

Destroy the chart with:

chart.destroy()

Loop over charts with:

Chartkick.eachChart( function(chart) {
  // do something
})

Content Security Policy (CSP)

Check out how to configure CSP

No Ruby? No Problem

Check out chartkick.js

Tutorials

Upgrading

4.0

If you use Sprockets, update the gem and you’re good to go!

If you use Webpacker, run:

yarn upgrade chartkick --latest

If you use Chart.js with Webpacker, also run:

yarn upgrade chart.js --latest

And in app/javascript/packs/application.js, change:

require("chartkick")
require("chart.js")

to:

require("chartkick/chart.js")

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/ankane/chartkick.git
cd chartkick
bundle install
bundle exec rake test
Comments
  • Using javascript functions when passing options to library

    Using javascript functions when passing options to library

    Trying to do some advanced x-axis label formatting with with highcharts;

    <%= column_chart weekly_samples_charts_path, library: {
      xAxis: {
        labels: {
          enabled: true,
          formatter: function() { ... }
        }
      }
    } %>
    

    but this failes, I get undefined methodfunction' for #<#Class:0x007f8dd57e3258:0x007f8dd53cb8c8>` error.

    Is this expected?

    opened by kakoni 23
  • library options hash does not work !!

    library options hash does not work !!

    It's imperative that I use chartkick in my web app; however, there's one issue stopping me from using it: I'm not able to change the background color or use any library options within the 'library' hash when creating the chart. I've tested charting libraries Chart.js and Highcharts.js, and the results are the same. Whatever library options I pass, none of them work. Am I doing something wrong? Here's an example of my chart:

    <%= line_chart User.group(:created_at).count, library: {backgroundColor: "#555"} %>

    I'm using Chartkick 2.0. Is anyone else having this issue?

    opened by al3izz 16
  • Chartkick is not defined

    Chartkick is not defined

    I have ChartKick referenced as outlined in the docs:

    - content_for :head do
      = javascript_include_tag '//www.google.com/jsapi', 'chartkick'
    

    (even referencing in head instead of at bottom of body!) and chartkick is not defined is being thrown. In the inspector, on line 355 of chartkick.js:

    Uncaught TypeError: Cannot read property 'innerText' of undefined 
    

    Any ideas?

    opened by elsom25 13
  • Chartkick 4

    Chartkick 4

    Timeline: when Chart.js 3.0 is released - 4-0-edge branch

    Plan

    • [x] Make charts deferrable by default - deferrable branch + Chartkick.js deferrable branch
    • [x] Better tooltips - no need to hit data point exactly
    • [x] Use JavaScript's Date.parse for times (built-in support for ISO-8601)
    • [x] Use local time for Highcharts - {time: {useUTC: false}} - https://github.com/ankane/react-chartkick/issues/47
    • [x] Show empty (No data) message by default when data is empty
    • [x] Show loading message when updateData is called (with URL or callback, make sure doesn't affect refresh option), with the ability to customize the loading message (https://github.com/ankane/chartkick.js/issues/119)
    • [x] Add support for Chart.js 3
    • [x] Remove type attribute from script tag ("The HTML5 specification urges authors to omit the attribute rather than provide a redundant MIME type." source)
    • [x] Don't rerun JavaScript for Turbolinks preview - deferrable branch
    • [x] Add Chartkick.destroyAll() method - destroyAll branch in Chartkick.js
    • [x] Change gridlines for Chart.js bar charts
    • [x] Require Ruby 2.6+
    • [x] If a single series data format is used for column and bar charts (not [{name: "", data: ...}]) and the colors options is passed, use it for the color of each bar
    • [x] Set nonce automatically when present
    • [x] Add loading option
    • [x] Automatically clean up charts on Turbolinks page change - https://github.com/ankane/chartkick/issues/536#issuecomment-720229441

    Maybe (non-breaking, so can wait until after release)

    • [ ] More chart types - bubble, radar, polar area, combo
    • [ ] Add class and style options

    Probably not

    • [ ] Use data-chartkick-* attributes to avoid inline JavaScript (more CSP friendly, possibly add option if needed to render faster)
    opened by ankane 12
  • Doesn't work with turbolinks

    Doesn't work with turbolinks

    I followed the installations instructions at https://github.com/ankane/chartkick#installation with google charts and the chart won't load when you first start the server. Once you reload the page, the chart will load. I learned that I had to add <%= javascript_include_tag "//www.google.com/jsapi", "chartkick" %> to app/views/layouts/application.html.erb after finding it on: http://stackoverflow.com/questions/19308820/chartkick-rails-4-undefined-method-pie-chart-for-class

    Perhaps the installation instructions need to be updated?

    awaiting response 
    opened by blufiro 12
  • allow user to pass ajaxOptions directly to ajax request

    allow user to pass ajaxOptions directly to ajax request

    Here's a request that allows the field ajaxOptions to be passed to the ajax request. Please let me know if you might consider it. I'm using this with with chartkick-remote and this gist https://gist.github.com/dontfidget/1ad9ab33971b64fe6fef, which allows me to limit the number of concurrent remote requests.

    My controller then has this code:

      include Chartkick::Remote
      chartkick_remote ajaxOptions: {queue: true, queueMaxConcurrency: 2}
    
    

    I've also taken your suggestion and made remote requests the default behavior for views on controllers that call chartkick_remote. Definitely looks better. Thanks.

    opened by ashanbrown 12
  • (Reopening) Chartkick is not defined with turbolinks defer

    (Reopening) Chartkick is not defined with turbolinks defer

    Hi @ankane!

    As usual, thank you so much for your OS contributions, they are huge.

    I'm also having problems with Chartkick and turbolinks with defer. Everything else works just fine, but Chartkick raises that JS exception when the page is opened through clicking a link (it works, tough, when refreshing the page directly in the chartkick view).

    In https://github.com/ankane/chartkick/issues/480#issuecomment-498919626 (#480) you mentioned that there's an edge branch with a solution, but that branch is currently 17 commits behind master.

    Do you plan in releasing that fix in the master branch?

    Thanks!

    opened by feliperaul 11
  • Asynchronous (Remote) Charts Aren't Working

    Asynchronous (Remote) Charts Aren't Working

    The example states:

    Say Goodbye To Timeouts

    Make your pages load super fast and stop worrying about timeouts. Give each chart its own endpoint.

    <%= line_chart completed_tasks_charts_path %> And in your controller, pass the data as JSON.

    class ChartsController < ApplicationController def completed_tasks render json: Task.group_by_day(:completed_at).count end end

    Tried it. Doesn't work. JSON renders fine. The following code gets generated in my specific case:

    new Chartkick.LineChart("chart-9", "/home/visits_by_day", {});
    
    opened by betam4x 11
  • using content_for

    using content_for

    Excellent plugin!!! Having an issue using content_for...

    My Layout

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <%= yield :charts_js %>
      </head>
      <body>
      <%= yield %>
    
      <%= javascript_include_tag 'application' %>
     </body>
    </html>
    

    Then my view

    <%= line_chart ({"Football" => 10, "Basketball" => 5}), content_for: :charts_js %>
    

    Gives me the error: Uncaught ReferenceError: Chartkick is not defined

    How is content_for meant to be used?

    opened by ryanharnwell 11
  • No matter the data, I can't seem to make it do day X axis, always hour

    No matter the data, I can't seem to make it do day X axis, always hour

    Here's the data:

    {"2013-05-20 00:00:00+00":0,"2013-05-21 00:00:00+00":0,"2013-05-22 00:00:00+00":116906}
    

    What am I doing wrong?

    opened by krainboltgreene 11
  • Display google charts negative value left from positive instead of right

    Display google charts negative value left from positive instead of right

    I'm using chartkick gem for building Google Charts in my rails app. But I have a problem with displaying negative values in line chart. Negative value goes after the positive instead of before.

    I have tried to google how to fix it, but didn't find any solution.

    opened by TeTiRoss 10
  • CSP compliance breaks when used with Turbo Drive w/ and random nonce generator

    CSP compliance breaks when used with Turbo Drive w/ and random nonce generator

    Hi there,

    Thank you for your time and work on this library.

    First

    I see there is existing documentation and are a handful of issues related to configuring CSP, but I think this is slightly different because it's related to the interplay between the default recommended nonce generation strategy, turbo and CSP. Apologies if I somehow managed to miss somewhere this is being discussed.

    Describe the bug

    When using turbo drive, it seems very likely folks using a CSP will run into violations due to the generated CSP nonce not matching the nonce used in the script tags on turbo visit.

    To reproduce

    I render a chart successfully on load. I can observe that the nonce generated alongside the script tag matches the csp nonce in the document head. All is well.

    If I navigate away (a turbo drive visit) and back (another turbo drive visit), I observe that the nonce used in the script tags no-longer matches the nonce in the head.


    Would you expect this to work? I suspect this is a limitation of the inline script tag approach under the circumstances described above.

    If anyone else is running into this, you can, of course, disable turbo when clicking whatever thing ultimately lands you on a view displaying a chart, but this can be a kind of jarring user experience.

    Another thing would be to use a session based nonce generation strategy like:

    Rails.application.config.content_security_policy_nonce_generator = -> request { request.session.id.to_s }
    

    I suspect many folks will run into this, since it seems the default recommended strategy at the moment is a unique per request approach:

    
    Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
    

    So perhaps this is partially solved by some additional documentation (which I can help with).

    Thanks again :)

    opened by tonywok 1
  • Better adding of plugins to Chart.js with Chartkick

    Better adding of plugins to Chart.js with Chartkick

    I am trying to register a plugin with Chart.js such as chartjs-plugin-annotation. I am on Rails 7 with Webpack, so I ran yarn add chartkick chart.js and import "chartkick/chart.js" .

    I am trying to do

    import "chartkick/chart.js"
    import annotationPlugin from 'chartjs-plugin-annotation';
    Chart.register(annotationPlugin);
    

    But I get the error Chart is not defined.

    After some digging, I figured how to get to the adapter with

    import "chartkick/chart.js"
    import annotationPlugin from "chartjs-plugin-annotation";
    Chartkick.adapters[0].library.register(annotationPlugin);
    

    But I'm not sure if this is the best way, or if it's worth adding a better way, or simply documenting this.

    opened by alex-benoit 2
  • Make chart download link image visible at all times

    Make chart download link image visible at all times

    I appreciate the client-side ability to download an image file of the chart. The problem is that discoverability is lower than we would like because the user must hover the mouse over the chart area to even see that download image appear. So not so great on desktop and impossible to download on mobile. I noticed that the styles are hardcoded here:

    https://github.com/ankane/chartkick/blob/4ad0c0bce42a5b0ea0c011d8d51dc8f5949d1ef8/vendor/assets/javascripts/chartkick.js#L1841

    At the very least, it would be great to have an option to pass in a boolean to control whether or not the download link is always visible. Another idea is to pass in styles or classes for it.

    opened by stephenhighemprise 1
  • Allow overiding `chart_json` on ActiveRecord

    Allow overiding `chart_json` on ActiveRecord

    Is your feature request related to a problem? Please describe. Consider this class:

    class HourlyForecast < ApplicationRecord
      def self.chart_json
        ..
      end
    end
    
    
    p HourlyForecast.where.method(:chart_json).source_location
    ## Currently
    # ["/---/chartkick-4.0.5/lib/chartkick/enumerable.rb", 4]
    ## Expected
    # ["app/models/hourly_forecast, 2]
    

    Something like that.

    opened by bekicot 0
  • Support for bubble charts

    Support for bubble charts

    Any chance you could add support for bubble charts? Google Charts and Highcharts support them, and I hope you can add them to your product roadmap. Thanks.

    new chart 
    opened by portwood 10
Create beautiful JavaScript charts with one line of React

React Chartkick Create beautiful JavaScript charts with one line of React See it in action Supports Chart.js, Google Charts, and Highcharts Quick Star

Andrew Kane 1.2k Nov 20, 2022
Smoothie Charts: smooooooth JavaScript charts for realtime streaming data

Smoothie Charts is a really small charting library designed for live streaming data. I built it to reduce the headaches I was getting from watching ch

Joe Walnes 2.2k Nov 29, 2022
Beautiful and interactive javascript charts for Java-based web applications.

Wicked Charts Beautiful and interactive JavaScript charts for Java-based web applications. Check out the Changelog Check out the Feature Overview with

adesso SE 85 Aug 23, 2022
Beautiful charts for Angular based on Chart.js

ng2-charts slack Beautiful charts for Angular based on Chart.js Usage & Demo Samples using ng2-charts https://valor-software.com/ng2-charts/ Installat

Valor Software 2.2k Nov 22, 2022
Progressive pie, donut, bar and line charts

Peity Peity (sounds like deity) is a jQuery plugin that converts an element's content into a mini <svg> pie, donut, line or bar chart. Basic Usage HTM

Ben Pickles 4.2k Nov 27, 2022
Chart.js plugin to create charts with a hand-drawn, sketchy, appearance

chartjs-plugin-rough Chart.js plugin to create charts with a hand-drawn, sketchy, appearance Version 0.2 requires Chart.js 2.7.0 or later, and Rough.j

Akihiko Kusanagi 72 Nov 9, 2022
Using ASP.NET Core, SignalR, and ChartJs to create real-time updating charts

Real-time Charts with ASP.NET Core, SignalR, and Chart.js This project shows how to update a real-time chart in your web browser using technologies li

Khalid Abuhakmeh 11 Nov 25, 2022
JavaScript diagramming library for interactive flowcharts, org charts, design tools, planning tools, visual languages.

GoJS, a JavaScript Library for HTML Diagrams GoJS is a JavaScript and TypeScript library for creating and manipulating diagrams, charts, and graphs. S

Northwoods Software Corporation 6.5k Nov 22, 2022
Attractive JavaScript charts for jQuery

flot About flot is a JavaScript plotting library for engineering and scientific applications derived from Flot: http://www.flotcharts.org/ Take a look

Flot 6k Nov 25, 2022
A plugin for the jQuery javascript library to generate small sparkline charts directly in the browser

jQuery Sparklines This jQuery plugin makes it easy to generate a number of different types of sparklines directly in the browser, using online a line

Gareth Watts 1.2k Nov 22, 2022
Ember Charts 3.5 2.3 L2 JavaScript A powerful and easy to use charting library for Ember.js

Ember Charts A charting library built with the Ember.js and d3.js frameworks. It includes time series, bar, pie, and scatter charts which are easy to

Addepar 794 Oct 22, 2022
Reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser.

roughViz.js is a reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser, based on D3v5, roughjs, and handy. Why? Use

Jared Wilber 6.4k Nov 17, 2022
📊 Interactive JavaScript Charts built on SVG

A modern JavaScript charting library to build interactive charts and visualizations with simple API. Our Partner ApexCharts is now a partner of Fusion

ApexCharts 12k Nov 22, 2022
Emprise Javascript Charts

EJSChart 100% Powerful, Clean & Functional Javascript Charts Whether at home, a medium sized or enterprise venture, EJSCharts will seamlessly help you

Emprise Corporation 34 Jun 3, 2021
A simple script for pure javascript charts.

MK Charts A simple pure Javascript for displaying circle charts. Demo: https://mkirschen.de/mk-scripts/mk-charts/ Circle charts To insert a chart all

Marcus Kirschen 5 Aug 3, 2022
Simple HTML5 Charts using the tag

Simple yet flexible JavaScript charting for designers & developers Documentation Currently, there are two versions of the library (2.9.4 and 3.x.x). V

Chart.js 58.8k Nov 22, 2022
Simple responsive charts

Big welcome by the Chartist Guy Checkout the documentation site at http://gionkunz.github.io/chartist-js/ Checkout this lightning talk that gives you

Gion Kunz 21 Nov 20, 2022
Simple, responsive, modern SVG Charts with zero dependencies

Frappe Charts GitHub-inspired modern, intuitive and responsive charts with zero dependencies Explore Demos » Edit at CodePen » Contents Installation U

Frappe 14.6k Nov 28, 2022
📊 A highly interactive data-driven visualization grammar for statistical charts.

English | 简体中文 G2 A highly interactive data-driven visualization grammar for statistical charts. Website • Tutorial Docs • Blog • G2Plot G2 is a visua

AntV team 11.4k Nov 23, 2022