CINXE.COM
Let’s Make A Bar Chart Tutorial | Vega
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <link rel="shortcut icon" href="https://vega.github.io/favicon.ico"/> <link rel="stylesheet" href="/vega/assets/syntax.css"> <link rel="stylesheet" href="/vega/assets/main.css"> <script src="/vega/vega.min.js"></script> <!-- Begin Jekyll SEO tag v2.8.0 --> <title>Let’s Make A Bar Chart Tutorial | Vega</title> <meta name="generator" content="Jekyll v3.10.0" /> <meta property="og:title" content="Let’s Make A Bar Chart Tutorial" /> <meta property="og:locale" content="en_US" /> <meta name="description" content="Vega - A Visualization Grammar. Vega is a visualization grammar, a declarative format for creating, saving, and sharing interactive visualization designs. With Vega, you can describe the visual appearance and interactive behavior of a visualization in a JSON format, and generate web-based views using Canvas or SVG." /> <meta property="og:description" content="Vega - A Visualization Grammar. Vega is a visualization grammar, a declarative format for creating, saving, and sharing interactive visualization designs. With Vega, you can describe the visual appearance and interactive behavior of a visualization in a JSON format, and generate web-based views using Canvas or SVG." /> <link rel="canonical" href="https://vega.github.io/vega/tutorials/bar-chart/" /> <meta property="og:url" content="https://vega.github.io/vega/tutorials/bar-chart/" /> <meta property="og:site_name" content="Vega" /> <meta property="og:type" content="website" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="Let’s Make A Bar Chart Tutorial" /> <meta name="twitter:site" content="@vega_vis" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebPage","description":"Vega - A Visualization Grammar. Vega is a visualization grammar, a declarative format for creating, saving, and sharing interactive visualization designs. With Vega, you can describe the visual appearance and interactive behavior of a visualization in a JSON format, and generate web-based views using Canvas or SVG.","headline":"Let’s Make A Bar Chart Tutorial","url":"https://vega.github.io/vega/tutorials/bar-chart/"}</script> <!-- End Jekyll SEO tag --> </head> <body> <div class="fill"> <header> <nav class="page-centered"> <div class="dropdown"> <a class="vega-title" href="/vega/">Vega</a> <div class="dropdown-content"> <a href="https://vega.github.io/vega-lite/">Vega-Lite</a> <a href="https://altair-viz.github.io/">Altair</a> <a href="https://vega.github.io/vega-lite-api/">Vega-Lite API</a> </div> </div> <div class="vega-links"> <div class="primary-links"> <a href="/vega/examples/" >Examples</a> <a href="/vega/tutorials/" aria-current="page">Tutorials</a> <a href="/vega/docs/" >Documentation</a> <a href="/vega/usage/" >Usage</a> <a href="/vega/about/" >About</a> </div> <div class="secondary-links"> <a href="https://github.com/vega/vega">GitHub</a> <a href="https://vega.github.io/editor/#/custom/vega">Try Online</a> </div> </div> </nav> </header> <section> <div class="page-centered page-main"> <section class="page-content"> <h1>Let's Make A Bar Chart Tutorial</h1> <p>This tutorial introduces the basics of Vega. We’ll look at a bar chart with tooltips and deconstruct it into its component elements. After completing the tutorial, you should be ready to start exploring and modifying Vega visualizations.</p> <p>Here is one of the most basic (but also most useful!) forms of visualization, the humble bar chart:</p> <div class="embed"> <div id="bar-chart" class="view"></div> <a href="./bar-chart.vg.json">View Source</a> <a id="bar-chart-png" href="#">Export PNG</a> <a id="bar-chart-svg" href="#">Export SVG</a> </div> <script> var spec = { "$schema": "https://vega.github.io/schema/vega/v5.json", "width": 400, "height": 200, "padding": 5, "data": [ { "name": "table", "values": [ {"category": "A", "amount": 28}, {"category": "B", "amount": 55}, {"category": "C", "amount": 43}, {"category": "D", "amount": 91}, {"category": "E", "amount": 81}, {"category": "F", "amount": 53}, {"category": "G", "amount": 19}, {"category": "H", "amount": 87} ] } ], "signals": [ { "name": "tooltip", "value": {}, "on": [ {"events": "rect:mouseover", "update": "datum"}, {"events": "rect:mouseout", "update": "{}"} ] } ], "scales": [ { "name": "xscale", "type": "band", "domain": {"data": "table", "field": "category"}, "range": "width", "padding": 0.05, "round": true }, { "name": "yscale", "domain": {"data": "table", "field": "amount"}, "nice": true, "range": "height" } ], "axes": [ { "orient": "bottom", "scale": "xscale" }, { "orient": "left", "scale": "yscale" } ], "marks": [ { "type": "rect", "from": {"data":"table"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "category"}, "width": {"scale": "xscale", "band": 1}, "y": {"scale": "yscale", "field": "amount"}, "y2": {"scale": "yscale", "value": 0} }, "update": { "fill": {"value": "steelblue"} }, "hover": { "fill": {"value": "red"} } } }, { "type": "text", "encode": { "enter": { "align": {"value": "center"}, "baseline": {"value": "bottom"}, "fill": {"value": "#333"} }, "update": { "x": {"scale": "xscale", "signal": "tooltip.category", "band": 0.5}, "y": {"scale": "yscale", "signal": "tooltip.amount", "offset": -2}, "text": {"signal": "tooltip.amount"}, "fillOpacity": [ {"test": "isNaN(tooltip.amount)", "value": 0}, {"value": 1} ] } } } ] } ; function image(view, type) { return function(event) { event.preventDefault(); view.toImageURL(type).then(function(url) { var link = document.createElement('a'); link.setAttribute('href', url); link.setAttribute('target', '_blank'); link.setAttribute('download', 'bar-chart.' + type); link.dispatchEvent(new MouseEvent('click')); }).catch(function(error) { console.error(error); }); }; } var view = new vega.View(vega.parse(spec), { loader: vega.loader({baseURL: '/vega/'}), logLevel: vega.Warn, renderer: 'svg' }).initialize('#bar-chart').hover().run(); document.querySelector('#bar-chart-png').addEventListener('click', image(view, 'png')); document.querySelector('#bar-chart-svg').addEventListener('click', image(view, 'svg')); </script> <p>Here is the Vega specification that defines this bar chart. First read through the full definition. We’ll then examine each part in turn.</p> <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> </span><span class="nl">"$schema"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://vega.github.io/schema/vega/v5.json"</span><span class="p">,</span><span class="w"> </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">400</span><span class="p">,</span><span class="w"> </span><span class="nl">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span><span class="w"> </span><span class="nl">"padding"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="nl">"values"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">28</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"B"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">55</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"C"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">43</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"D"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">91</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"E"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">81</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"F"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">53</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"G"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">19</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"H"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">87</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="nl">"signals"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="nl">"on"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"events"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rect:mouseover"</span><span class="p">,</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="s2">"datum"</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"events"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rect:mouseout"</span><span class="p">,</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{}"</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="nl">"scales"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"band"</span><span class="p">,</span><span class="w"> </span><span class="nl">"domain"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"category"</span><span class="p">},</span><span class="w"> </span><span class="nl">"range"</span><span class="p">:</span><span class="w"> </span><span class="s2">"width"</span><span class="p">,</span><span class="w"> </span><span class="nl">"padding"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.05</span><span class="p">,</span><span class="w"> </span><span class="nl">"round"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"domain"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"amount"</span><span class="p">},</span><span class="w"> </span><span class="nl">"nice"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nl">"range"</span><span class="p">:</span><span class="w"> </span><span class="s2">"height"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="nl">"axes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"orient"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bottom"</span><span class="p">,</span><span class="w"> </span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"orient"</span><span class="p">:</span><span class="w"> </span><span class="s2">"left"</span><span class="p">,</span><span class="w"> </span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="nl">"marks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rect"</span><span class="p">,</span><span class="w"> </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"data"</span><span class="p">:</span><span class="s2">"table"</span><span class="p">},</span><span class="w"> </span><span class="nl">"encode"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"enter"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"x"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"category"</span><span class="p">},</span><span class="w"> </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"band"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">},</span><span class="w"> </span><span class="nl">"y"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"amount"</span><span class="p">},</span><span class="w"> </span><span class="nl">"y2"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"fill"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"steelblue"</span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"hover"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"fill"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text"</span><span class="p">,</span><span class="w"> </span><span class="nl">"encode"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"enter"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"align"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"center"</span><span class="p">},</span><span class="w"> </span><span class="nl">"baseline"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bottom"</span><span class="p">},</span><span class="w"> </span><span class="nl">"fill"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"#333"</span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"x"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"signal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip.category"</span><span class="p">,</span><span class="w"> </span><span class="nl">"band"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.5</span><span class="p">},</span><span class="w"> </span><span class="nl">"y"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"signal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip.amount"</span><span class="p">,</span><span class="w"> </span><span class="nl">"offset"</span><span class="p">:</span><span class="w"> </span><span class="mi">-2</span><span class="p">},</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"signal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip.amount"</span><span class="p">},</span><span class="w"> </span><span class="nl">"fillOpacity"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"isNaN(tooltip.amount)"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>We’ll now walk through the visualization definition visiting each of these components:</p> <ol> <li><a href="#visualization-size">Visualization Size</a></li> <li><a href="#data">Data</a></li> <li><a href="#scales">Scales</a></li> <li><a href="#axes">Axes</a></li> <li><a href="#marks">Marks</a></li> <li><a href="#signals">Signals</a></li> <li><a href="#next-steps">Next Steps</a></li> </ol> <h2 id="visualization-size"><a name="visualization-size"></a>Visualization Size</h2> <p>The first set of top-level properties determine the size of the visualization:</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">400</span><span class="err">,</span><span class="w"> </span><span class="nl">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="err">,</span><span class="w"> </span><span class="nl">"padding"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="err">,</span><span class="w"> </span><span class="nl">"autosize"</span><span class="p">:</span><span class="w"> </span><span class="s2">"pad"</span><span class="err">,</span><span class="w"> </span></code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">width</code> and <code class="language-plaintext highlighter-rouge">height</code> values determine the size of the <em>data rectangle</em>: the area of the chart in which data is plotted. Additional components, such as axes and legends, may take up additional space.</p> <p>The <code class="language-plaintext highlighter-rouge">padding</code> determines the margin between the chart content and the border of the view.</p> <p>The <code class="language-plaintext highlighter-rouge">autosize</code> property determines how the final chart size is determined:</p> <ul> <li><code class="language-plaintext highlighter-rouge">"pad"</code> (the default) introduces extra space to accommodate all visualized marks, including axes and legends. The data rectangle size is unchanged. If any marks are placed at extreme positions outside the data rectangle, the view component may become very large!</li> <li><code class="language-plaintext highlighter-rouge">"fit"</code> tries to fit the entire chart (data rectangle, axes, legends, but <em>not</em> padding) within the provided <code class="language-plaintext highlighter-rouge">width</code> and <code class="language-plaintext highlighter-rouge">height</code>. Vega will shrink the data rectangle to accommodate axes and legends. In some cases clipping may occur, for instance if a legend is very tall.</li> <li><code class="language-plaintext highlighter-rouge">"none"</code> disables automatic sizing. The total chart size is determined solely by the <code class="language-plaintext highlighter-rouge">width</code> and <code class="language-plaintext highlighter-rouge">height</code> plus <code class="language-plaintext highlighter-rouge">padding</code>. There are no modifications to accommodate axes, legends, etc.</li> </ul> <p>For more details, see the <a href="../../docs/specification">top-level specification</a> documentation.</p> <h2 id="data"><a name="data"></a>Data</h2> <p>The <code class="language-plaintext highlighter-rouge">data</code> property is an array of data definitions. Each entry in the data array must be an object with a unique <code class="language-plaintext highlighter-rouge">name</code> for the data set. As shown here, data can be directly defined inline using the <code class="language-plaintext highlighter-rouge">values</code> property. In this example, we have an array of data objects with fields named <code class="language-plaintext highlighter-rouge">category</code> (a string label) and <code class="language-plaintext highlighter-rouge">amount</code> (a number).</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="nl">"values"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">28</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"B"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">55</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"C"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">43</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"D"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">91</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"E"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">81</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"F"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">53</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"G"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">19</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"category"</span><span class="p">:</span><span class="w"> </span><span class="s2">"H"</span><span class="p">,</span><span class="w"> </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="mi">87</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="err">,</span><span class="w"> </span></code></pre></div></div> <p>In Vega specifications, data can be:</p> <ul> <li>loaded from the web by using the <code class="language-plaintext highlighter-rouge">url</code> property (including JSON and CSV files),</li> <li>derived from a previously defined data set using the <code class="language-plaintext highlighter-rouge">source</code> property, or</li> <li>left undefined and dynamically set when the visualization is constructed.</li> </ul> <p>Only <em>one</em> of the <code class="language-plaintext highlighter-rouge">values</code>, <code class="language-plaintext highlighter-rouge">url</code> or <code class="language-plaintext highlighter-rouge">source</code> properties may be defined.</p> <p>Data sets in Vega can be modified using a collection of <a href="../../docs/transforms">transforms</a> such as filtering, aggregation and layout operations. Transformations are specified using the <code class="language-plaintext highlighter-rouge">transform</code> property, which takes an array of transform definitions.</p> <p>For more details, see the <a href="../../docs/data">data</a> and <a href="../../docs/transforms">transform</a> documentation.</p> <h2 id="scales"><a name="scales"></a>Scales</h2> <p>Scale functions map data values to visual values, such as pixel positions or colors:</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"scales"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"band"</span><span class="p">,</span><span class="w"> </span><span class="nl">"domain"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"category"</span><span class="p">},</span><span class="w"> </span><span class="nl">"range"</span><span class="p">:</span><span class="w"> </span><span class="s2">"width"</span><span class="p">,</span><span class="w"> </span><span class="nl">"padding"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.05</span><span class="p">,</span><span class="w"> </span><span class="nl">"round"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"domain"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"amount"</span><span class="p">},</span><span class="w"> </span><span class="nl">"nice"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nl">"range"</span><span class="p">:</span><span class="w"> </span><span class="s2">"height"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="err">,</span><span class="w"> </span></code></pre></div></div> <p>Here we’ve defined two scales, one each for the X and Y axes. The X-axis uses an ordinal <code class="language-plaintext highlighter-rouge">band</code> scale, which maps a <code class="language-plaintext highlighter-rouge">domain</code> of ordered elements (in this case letters) to a visual <code class="language-plaintext highlighter-rouge">range</code>. The Y-axis uses a quantitative <code class="language-plaintext highlighter-rouge">linear</code> scale. A linear scale type is used by default, and so is not explicitly included in the <code class="language-plaintext highlighter-rouge">yscale</code> definition above.</p> <p>Each scale definition should have a <strong>unique name</strong>. Though to be precise, scale definitions nested within <code class="language-plaintext highlighter-rouge">group</code> marks <em>can</em> repeat names to override previously defined scales – but that is a more advanced concept.</p> <p>The <code class="language-plaintext highlighter-rouge">range</code> settings of <code class="language-plaintext highlighter-rouge">"width"</code> and <code class="language-plaintext highlighter-rouge">"height"</code> are conveniences provided by Vega, and in this case map to the arrays <code class="language-plaintext highlighter-rouge">[0, 400]</code> and <code class="language-plaintext highlighter-rouge">[200, 0]</code>, as defined by the size of the visualization. Ranges can also be defined explicitly as arrays of values: two-element numerical arrays should be used for spatial mappings, longer arrays (e.g., of RGB hex values like <code class="language-plaintext highlighter-rouge">"#ffa804"</code>) can be used as the range of <code class="language-plaintext highlighter-rouge">ordinal</code> scales to specify custom palettes.</p> <p>The <code class="language-plaintext highlighter-rouge">domain</code> property determines the input domain for the scale. The domain can be defined directly as an array of values (a quantitative range or list of ordinal values) or determined dynamically from the data. In the example above, the domain consists of the minimum and maximum values of the <code class="language-plaintext highlighter-rouge">amount</code> field in the <code class="language-plaintext highlighter-rouge">table</code> data set. By default, quantitative scales automatically include the zero value. To disable this feature, include the property <code class="language-plaintext highlighter-rouge">"zero": false</code> in the scale definition.</p> <p>The <code class="language-plaintext highlighter-rouge">xscale</code> definition also includes a fractional <code class="language-plaintext highlighter-rouge">padding</code> to add spacing between bars and a <code class="language-plaintext highlighter-rouge">round</code> parameter to make sure the bars snap to pixel boundaries. Notice that <code class="language-plaintext highlighter-rouge">yscale</code> includes the property <code class="language-plaintext highlighter-rouge">"nice": true</code>. This optional property tells Vega that the scale domain can be made “nice” so that it is more human-friendly and readable. For example, if the raw data domain is <code class="language-plaintext highlighter-rouge">[0, 94.345]</code> it is made “nicer” as <code class="language-plaintext highlighter-rouge">[0, 100]</code>.</p> <p>For more details, see the <a href="../../docs/scales">scales</a> documentation.</p> <h2 id="axes"><a name="axes"></a>Axes</h2> <p>Axes visualize scales using ticks and labels to help viewers interpret a chart.</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"axes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"orient"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bottom"</span><span class="p">,</span><span class="w"> </span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"orient"</span><span class="p">:</span><span class="w"> </span><span class="s2">"left"</span><span class="p">,</span><span class="w"> </span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="err">,</span><span class="w"> </span></code></pre></div></div> <p>At minimum, an axis definition must specify the axis orientation and the scale to visualize. Here we add an X-axis at the <code class="language-plaintext highlighter-rouge">bottom</code> of the chart, and a Y-axis to the <code class="language-plaintext highlighter-rouge">left</code> of the chart.</p> <p>Now let’s look at how we might further customize the axes:</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"axes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"orient"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bottom"</span><span class="p">,</span><span class="w"> </span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"orient"</span><span class="p">:</span><span class="w"> </span><span class="s2">"right"</span><span class="p">,</span><span class="w"> </span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"tickCount"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="nl">"offset"</span><span class="p">:</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="err">,</span><span class="w"> </span></code></pre></div></div> <p>Here we’ve adjusted the Y-axis in multiple ways, resulting in the modified chart below. By setting <code class="language-plaintext highlighter-rouge">"tickCount": 5</code>, we’ve requested that the axis show roughly five tick marks, rather than the ten or so shown previously. By setting <code class="language-plaintext highlighter-rouge">"orient": "right"</code>, we’ve requested that the axis be placed on the right side of the chart, rather than the previous left position. Finally, setting <code class="language-plaintext highlighter-rouge">"offset": 6</code> adjusts the axis position, in this case moving it to the right by 6 pixels. Here’s the modified visualization:</p> <div class="embed"> <div id="bar-chart-axes" class="view"></div> <a href="./bar-chart-axes.vg.json">View Source</a> <a id="bar-chart-axes-png" href="#">Export PNG</a> <a id="bar-chart-axes-svg" href="#">Export SVG</a> </div> <script> var spec = { "$schema": "https://vega.github.io/schema/vega/v5.json", "width": 400, "height": 200, "padding": 5, "data": [ { "name": "table", "values": [ {"category": "A", "amount": 28}, {"category": "B", "amount": 55}, {"category": "C", "amount": 43}, {"category": "D", "amount": 91}, {"category": "E", "amount": 81}, {"category": "F", "amount": 53}, {"category": "G", "amount": 19}, {"category": "H", "amount": 87} ] } ], "signals": [ { "name": "tooltip", "value": {}, "on": [ {"events": "rect:mouseover", "update": "datum"}, {"events": "rect:mouseout", "update": "{}"} ] } ], "scales": [ { "name": "xscale", "type": "band", "domain": {"data": "table", "field": "category"}, "range": "width", "padding": 0.05, "round": true }, { "name": "yscale", "domain": {"data": "table", "field": "amount"}, "nice": true, "range": "height" } ], "axes": [ { "orient": "bottom", "scale": "xscale" }, { "orient": "right", "scale": "yscale", "tickCount": 5, "offset": 6 } ], "marks": [ { "type": "rect", "from": {"data":"table"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "category"}, "width": {"scale": "xscale", "band": 1}, "y": {"scale": "yscale", "field": "amount"}, "y2": {"scale": "yscale", "value": 0} }, "update": { "fill": {"value": "steelblue"} }, "hover": { "fill": {"value": "red"} } } }, { "type": "text", "encode": { "enter": { "align": {"value": "center"}, "baseline": {"value": "bottom"}, "fill": {"value": "#333"} }, "update": { "x": {"scale": "xscale", "signal": "tooltip.category", "band": 0.5}, "y": {"scale": "yscale", "signal": "tooltip.amount", "offset": -2}, "text": {"signal": "tooltip.amount"}, "fillOpacity": [ {"test": "isNaN(tooltip.amount)", "value": 0}, {"value": 1} ] } } } ] } ; function image(view, type) { return function(event) { event.preventDefault(); view.toImageURL(type).then(function(url) { var link = document.createElement('a'); link.setAttribute('href', url); link.setAttribute('target', '_blank'); link.setAttribute('download', 'bar-chart-axes.' + type); link.dispatchEvent(new MouseEvent('click')); }).catch(function(error) { console.error(error); }); }; } var view = new vega.View(vega.parse(spec), { loader: vega.loader({baseURL: '/vega/'}), logLevel: vega.Warn, renderer: 'svg' }).initialize('#bar-chart-axes').hover().run(); document.querySelector('#bar-chart-axes-png').addEventListener('click', image(view, 'png')); document.querySelector('#bar-chart-axes-svg').addEventListener('click', image(view, 'svg')); </script> <p>For more details, see the <a href="../../docs/axes">axes</a> documentation.</p> <h2 id="marks"><a name="marks"></a>Marks</h2> <p>Marks are the primary elements of a visualization: they are graphical primitives whose properties (such as position, size, shape, and color) can be used to visually encode data. Vega provides a set of marks that serve as building blocks that can be combined to form rich visualizations. Here, we simply use rectangles (<code class="language-plaintext highlighter-rouge">rect</code> marks) to construct a bar chart.</p> <p>Every mark must have a <code class="language-plaintext highlighter-rouge">type</code> property, which determines which kind of mark (<code class="language-plaintext highlighter-rouge">rect</code>, <code class="language-plaintext highlighter-rouge">area</code>, <code class="language-plaintext highlighter-rouge">line</code>, <code class="language-plaintext highlighter-rouge">symbol</code>, etc.) to use. Next, we must specify the data to be visualized using the <code class="language-plaintext highlighter-rouge">from</code> property. In most cases, one simply needs to reference a named data set defined in the top-level <code class="language-plaintext highlighter-rouge">data</code> property. If no <code class="language-plaintext highlighter-rouge">from</code> property is provided, a single mark instance will be created.</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"marks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rect"</span><span class="p">,</span><span class="w"> </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"data"</span><span class="p">:</span><span class="s2">"table"</span><span class="p">},</span><span class="w"> </span><span class="nl">"encode"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"enter"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"x"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"category"</span><span class="p">},</span><span class="w"> </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"band"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">},</span><span class="w"> </span><span class="nl">"y"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"amount"</span><span class="p">},</span><span class="w"> </span><span class="nl">"y2"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"fill"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"steelblue"</span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"hover"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"fill"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span></code></pre></div></div> <p>Visual mark properties, such as position and color, are specified using named <em>encoding sets</em> defined within the <code class="language-plaintext highlighter-rouge">encode</code> property. The standard encoding sets are the <code class="language-plaintext highlighter-rouge">enter</code> set (for properties that should be set when the mark is first created), the <code class="language-plaintext highlighter-rouge">exit</code> set (for property settings when a mark is about to be removed), the <code class="language-plaintext highlighter-rouge">update</code> set (to update settings upon changes), and the <code class="language-plaintext highlighter-rouge">hover</code> set (to set properties upon mouse hover). In the example above, the <code class="language-plaintext highlighter-rouge">enter</code> set is first evaluated, followed by the <code class="language-plaintext highlighter-rouge">update</code> set, to create the bar chart. Upon mouse over, the <code class="language-plaintext highlighter-rouge">hover</code> set is evaluated to color the hovered bar in red. When the mouse leaves a bar, the <code class="language-plaintext highlighter-rouge">update</code> set is evaluated again to return the bar to its original color. Note that if we omit the <code class="language-plaintext highlighter-rouge">update</code> set, a mouse hover would cause the bar to turn permanently red!</p> <p>Now let’s take a closer look at the specific mark definitions in the <code class="language-plaintext highlighter-rouge">enter</code> set:</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"x"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"category"</span><span class="p">}</span><span class="err">,</span><span class="w"> </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"band"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">}</span><span class="err">,</span><span class="w"> </span><span class="nl">"y"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"field"</span><span class="p">:</span><span class="w"> </span><span class="s2">"amount"</span><span class="p">}</span><span class="err">,</span><span class="w"> </span><span class="nl">"y2"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>The first two properties (<code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">width</code>) set the horizontal position and width of the bar. The <code class="language-plaintext highlighter-rouge">x</code> mark property (the leftmost edge of the bar) is set to the value obtained by applying the scale named <code class="language-plaintext highlighter-rouge">"xscale"</code> (defined in <code class="language-plaintext highlighter-rouge">scales</code> above) to the data field <code class="language-plaintext highlighter-rouge">category</code>.</p> <p>The <code class="language-plaintext highlighter-rouge">width</code> property is set to a value provided by the band scale <code class="language-plaintext highlighter-rouge">xscale</code>. Band scales chop up a spatial range into a set of uniformly sized “bands”. Including <code class="language-plaintext highlighter-rouge">"band": 1</code> retrieves the full size of the band for the scale. The <code class="language-plaintext highlighter-rouge">1</code> value indicates what fraction of the band size to include; using <code class="language-plaintext highlighter-rouge">"band": 0.5</code> would use half of the band.</p> <p>The second two properties (<code class="language-plaintext highlighter-rouge">y</code> and <code class="language-plaintext highlighter-rouge">y2</code>) determine the vertical position and height of the bars. Similar to <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">width</code>, one <em>could</em> use <code class="language-plaintext highlighter-rouge">y</code> and <code class="language-plaintext highlighter-rouge">height</code> properties. However, here it is easier to specify the bar heights using two end points: one for the top of the bar (<code class="language-plaintext highlighter-rouge">y</code>) and one for the bottom of the bar (<code class="language-plaintext highlighter-rouge">y2</code>). We hardwire the value <code class="language-plaintext highlighter-rouge">0</code> and pass it through the linear <code class="language-plaintext highlighter-rouge">yscale</code> to ensure that one edge of each bar is always at zero. It actually does not matter which of <code class="language-plaintext highlighter-rouge">y</code> or <code class="language-plaintext highlighter-rouge">y2</code> is greater than the other; Vega will set the positions correctly. You can similarly use <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">x2</code>, which can be useful for creating visualizations such as horizontal bar charts and timelines.</p> <p>In addition to standard graphical marks (rectangles, arcs, plotting symbols, etc), Vega also supports nested marks through the special <a href="../../docs/marks/group"><code class="language-plaintext highlighter-rouge">group</code></a> mark type. Groups are marks that can contain other marks, for example to create <a href="http://en.wikipedia.org/wiki/Small_multiple">small multiple displays</a>. Groups can also include custom <code class="language-plaintext highlighter-rouge">scales</code> and <code class="language-plaintext highlighter-rouge">axes</code> definitions that are specific to a group instance.</p> <p>For more details, see the <a href="../../docs/marks">marks</a> documentation.</p> <h2 id="signals"><a name="signals"></a>Signals</h2> <p>Signals act as dynamic variables: expressions that are automatically reevaluated when other signal values change, or when input events occur. Each signal must have a unique <code class="language-plaintext highlighter-rouge">name</code> and an initial <code class="language-plaintext highlighter-rouge">value</code>; other properties define how the signal value can change.</p> <p>Here we use a signal to define a tooltip interaction. In this example, the value of the <code class="language-plaintext highlighter-rouge">tooltip</code> signal changes in response to <code class="language-plaintext highlighter-rouge">mouseover</code> and <code class="language-plaintext highlighter-rouge">mouseout</code> events on <code class="language-plaintext highlighter-rouge">rect</code> marks. Every time these events occur, the corresponding expression is evaluated and set as the <code class="language-plaintext highlighter-rouge">tooltip</code> value. Thus, when the mouse pointer is moved over a rectangle mark, <code class="language-plaintext highlighter-rouge">tooltip</code> is equal to the mark’s backing datum; when the pointer is moved off the rectangle, <code class="language-plaintext highlighter-rouge">tooltip</code> is an empty object.</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"signals"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="nl">"on"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"events"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rect:mouseover"</span><span class="p">,</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="s2">"datum"</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"events"</span><span class="p">:</span><span class="w"> </span><span class="s2">"rect:mouseout"</span><span class="p">,</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{}"</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="err">,</span><span class="w"> </span></code></pre></div></div> <p>Our <code class="language-plaintext highlighter-rouge">tooltip</code> signal tracks the datum for the currently highlighted bar. We now use this signal to dynamically adjust the visual encoding rules of a text label:</p> <div class="language-json suppress-error highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> </span><span class="nl">"marks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="err">...</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text"</span><span class="p">,</span><span class="w"> </span><span class="nl">"encode"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"enter"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"align"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"center"</span><span class="p">},</span><span class="w"> </span><span class="nl">"baseline"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bottom"</span><span class="p">},</span><span class="w"> </span><span class="nl">"fill"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"#333"</span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"update"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"x"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"signal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip.category"</span><span class="p">,</span><span class="w"> </span><span class="nl">"band"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.5</span><span class="p">},</span><span class="w"> </span><span class="nl">"y"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"scale"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yscale"</span><span class="p">,</span><span class="w"> </span><span class="nl">"signal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip.amount"</span><span class="p">,</span><span class="w"> </span><span class="nl">"offset"</span><span class="p">:</span><span class="w"> </span><span class="mi">-2</span><span class="p">},</span><span class="w"> </span><span class="nl">"text"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"signal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tooltip.amount"</span><span class="p">},</span><span class="w"> </span><span class="nl">"fillOpacity"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="nl">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"isNaN(tooltip.amount)"</span><span class="p">,</span><span class="w"> </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span></code></pre></div></div> <p>A single text mark instance serves as our tooltip text (note that the <code class="language-plaintext highlighter-rouge">from</code> property is omitted). The position and text values are drawn directly from the <code class="language-plaintext highlighter-rouge">tooltip</code> signal. To only show the tooltip text when the mouse pointer is over a rectangle, we set the <code class="language-plaintext highlighter-rouge">fillOpacity</code> using <em>production rules</em>: a chain of if-then-else rules for visual encoding. If <code class="language-plaintext highlighter-rouge">tooltip</code> is an empty object, the tooltip text is fully transparent since <code class="language-plaintext highlighter-rouge">isNaN(tooltip.amount)</code> is <code class="language-plaintext highlighter-rouge">true</code>, otherwise it is opaque.</p> <p>Signals can be applied throughout a specification. For example, they can be used to specify the properties of <a href="../../docs/transforms">transforms</a>, <a href="../../docs/scales">scales</a> and <a href="../../docs/marks">mark encodings</a>. For more details, see the <a href="../../docs/signals">signals</a> documentation.</p> <h2 id="next-steps"><a name="next-steps"></a>Next Steps</h2> <p>We’ve now worked through a full Vega visualization! Next, we recommend experimenting with and modifying this example. Copy & paste the full specification above into the online <strong><a href="https://vega.github.io/editor">Vega Editor</a></strong> or fork <a href="https://bl.ocks.org/domoritz/cd636b15fa0e187b51b73fc60b4d3014">our example Block</a>.</p> <ul> <li>Can you adjust the scales and axes?</li> <li>Can you change the chart from a vertical bar chart to a horizontal bar chart?</li> <li>Can you visualize a new data set with a similar structure?</li> </ul> <p>You should then be ready to understand and modify other examples. Many of the more advanced examples include data transforms that organize data elements and perform layout. As you experiment with different examples, you may find it useful to refer to the documentation for each of the main specification components.</p> </section> </div> </section> </div> <footer> <div class="page-centered"> <span class="edit-page"> <a href="https://github.com/vega/vega/edit/main/docs/tutorials/bar-chart/index.md">Edit this Page</a> </span> <span class="fill"></span> <a href="http://idl.cs.washington.edu" title="UW Interactive Data Lab" class="logo"> <img src="/vega/assets/idl-logo.png"/> </a> </div> </footer> </body> </html>