Vega.rb
Interactive charts for Ruby, powered by Vega and Vega-Lite
Works with Rails, iRuby, and other frameworks
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"))
esbuild or Webpack
Run:
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"))
Webpacker
Run:
yarn add vega vega-lite vega-embed
And add to app/javascript/packs/application.js
:
window.vegaEmbed = require("vega-embed").default
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
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
transform(bin: true, field: "a", as: "binned a")
Marks
Bar chart
mark("bar")
Line chart
mark("line")
Pie chart
mark("pie")
Area chart
mark("area")
Enable tooltips
mark(type: "bar", tooltip: true)
Encoding
encoding(x: {field: "a", type: "ordinal"})
Projection
projection(type: "albersUsa")
View Composition
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
selection(x: {type: "single"})
Parameters
params(name: "cornerRadius", value: 5)
Config
Set the font
config(font: "Helvetica")
Top-Level Properties
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
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 Webpacker, 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:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
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: