Home

Awesome

Vega.rb

Interactive charts for Ruby, powered by Vega and Vega-Lite

See it in action

Works with Rails, iRuby, and other frameworks

Build Status

Installation

Add this line to your application’s Gemfile:

gem "vega"

Then follow the instructions for how you plan to use it:

Importmap

Add to config/importmap.rb:

pin "vega", to: "vega.js"
pin "vega-lite", to: "vega-lite.js"
pin "vega-embed", to: "vega-embed.js"

And add to app/javascript/application.js:

import "vega"
import "vega-lite"
import "vega-embed"

window.dispatchEvent(new Event("vega:load"))

Bun, esbuild, or Webpack

Run:

bun add vega vega-lite vega-embed
# or
yarn add vega vega-lite vega-embed

And add to app/javascript/application.js:

import embed from "vega-embed"

window.vegaEmbed = embed
window.dispatchEvent(new Event("vega:load"))

Sprockets

Add to app/assets/javascripts/application.js:

//= require vega
//= require vega-lite
//= require vega-embed

iRuby

No additional set up is needed.

Other

For Sinatra and other web frameworks, download Vega, Vega-Lite, and Vega-Embed and include them on pages with charts:

<script src="vega.js"></script>
<script src="vega-lite.js"></script>
<script src="vega-embed.js"></script>

Getting Started

Vega is a visualization grammar, and Vega-Lite is a high-level grammar built on top of it. We recommend using Vega-Lite by default and moving to Vega for advanced use cases.

Create visualizations by chaining together methods:

Vega.lite.data(data).mark("bar").height(200)

There are methods for each of the top-level properties. The docs are a great source of examples:

Example

Create a bar chart

Vega.lite
  .data([{city: "A", sales: 28}, {city: "B", sales: 55}, {city: "C", sales: 43}])
  .mark(type: "bar", tooltip: true)
  .encoding(
    x: {field: "city", type: "nominal"},
    y: {field: "sales", type: "quantitative"}
  )

The chart will automatically render in iRuby. For Rails, render it in your view:

<%= Vega.lite.data(...) %>

Vega-Lite

Start a Vega-Lite chart with:

Vega.lite

Data

Docs

Data can be an array

data([{x: "A", y: 1}, {x: "B", y: 2}])

Or a URL

data("https://www.example.com/data.json")

Or a Rover data frame

data(df)

Or a data generator

data(sequence: {start: 0, stop: 10, step: 1, as: "x"})

Transforms

Docs

transform(bin: true, field: "a", as: "binned a")

Marks

Docs

Bar chart

mark("bar")

Line chart

mark("line")

Pie chart

mark("pie")

Area chart

mark("area")

Enable tooltips

mark(type: "bar", tooltip: true)

Encoding

Docs

encoding(x: {field: "a", type: "ordinal"})

Projection

Docs

projection(type: "albersUsa")

View Composition

Docs

Faceting

facet(row: {field: "x"})

Layering

layer(view)

Concatenation

hconcat(view)
vconcat(view)
concat(view)

Repeating

repeat(row: ["a", "b", "c"])

Resolving

resolve(scale: {color: "independent"})

Selections

Docs

selection(x: {type: "single"})

Parameters

Docs

params(name: "cornerRadius", value: 5)

Config

Docs

Set the font

config(font: "Helvetica")

Top-Level Properties

Docs

Set width and height

width(500).height(300)

Set the background color

background("#000")

Set padding

padding(5)
# or
padding(left: 5, top: 5, right: 5, bottom: 5)

Embed Options

Docs

Set embed options

embed_options(actions: true)

Vega

You can also use Vega directly. In this case, you don’t need to include Vega-Lite in the JavaScript files.

Start a Vega chart with:

Vega.start

Spec

You can also create a specification by hand

spec = {
  "$schema" => "https://vega.github.io/schema/vega-lite/v5.json",
  "data" => {"url" => "https://www.example.com"},
  # ...
}

And render it in Rails

<%= vega_chart spec %>

Or display it in iRuby

Vega.display(spec)

Get the spec for a chart

chart.spec

Exporting Charts (experimental)

Export charts to PNG, SVG, or PDF. This requires Node.js and npm 7+. Run:

yarn add vega-cli vega-lite

For PNG, use:

File.binwrite("chart.png", chart.to_png)

For SVG, use:

File.binwrite("chart.svg", chart.to_svg)

For PDF, use:

File.binwrite("chart.pdf", chart.to_pdf)

Content Security Policy (CSP)

Styles and Frames

Enable unsafe inline styles and blob frames on actions that have charts

class ChartsController < ApplicationController
  content_security_policy only: :index do |policy|
    policy.style_src :self, :unsafe_inline
    policy.frame_src :blob
  end
end

Nonce

Automatically add a nonce when configured in Rails with:

<%= vega_chart chart %>

Interpreter

By default, the Vega parser uses the Function constructor, which can cause issues with CSP.

For Importmap, add to config/importmap.rb:

pin "vega-interpreter", to: "vega-interpreter.js"

And add to app/javascript/application.js:

import "vega-interpreter"

For Bun, run:

bun add vega-interpreter

For esbuild or Webpack, run:

yarn add vega-interpreter

For Sprockets, add to app/assets/javascripts/application.js:

//= require vega-interpreter

And set embed options for your charts

embed_options(ast: true)

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/vega-ruby.git
cd vega-ruby
bundle install
bundle exec rake test

Resources for contributors: