UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

290 lines (280 loc) 58.2 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:pls="http://www.w3.org/2005/01/pronunciation-lexicon" xmlns:ssml="http://www.w3.org/2001/10/synthesis" xmlns:svg="http://www.w3.org/2000/svg"><head><title>Chapter 5. Data</title><link rel="stylesheet" type="text/css" href="core.css"/><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"/><link rel="up" href="index.html" title="Interactive Data Visualization for the Web"/><link rel="prev" href="ch04.html" title="Chapter 4. Setup"/><link rel="next" href="ch06.html" title="Chapter 6. Drawing with Data"/></head><body><section class="chapter" title="Chapter 5. Data" epub:type="chapter" id="data-chapter5"><div class="titlepage"><div><div><h2 class="title">Chapter 5. Data</h2></div></div></div><p><span class="emphasis"><em>Data</em></span> is an extremely broad term, only slightly less vague than the nearly all-encompassing <span class="emphasis"><em>information</em></span>. What is data? (What <span class="emphasis"><em>isn’t</em></span> data?) What kinds of data are there, and what can we use with D3?<a id="ix_data" class="indexterm"/></p><p>Broadly speaking, data is structured information with potential for meaning.</p><p>In the context of programming for visualization, data is stored in a digital file, typically in either text or binary form. Of course, potentially every piece of digital ephemera may be considered “data”—not just text, but bits and bytes representing images, audio, video, databases, streams, models, archives, and anything else.<a id="I_indexterm5_id296212" class="indexterm"/></p><p>Within the scope of D3 and browser-based visualization, however, we will limit ourselves to <span class="emphasis"><em>text-based data</em></span>. That is, anything that can be represented as numbers and strings of alpha characters. If you can get your data into a <span class="emphasis"><em>.txt</em></span> plain text file, a <span class="emphasis"><em>.csv</em></span> comma-separated value file, or a <span class="emphasis"><em>.json</em></span> JSON document, then you can use it with D3.<a id="I_indexterm5_id296244" class="indexterm"/><a id="I_indexterm5_id296252" class="indexterm"/><a id="I_indexterm5_id296258" class="indexterm"/><a id="I_indexterm5_id296265" class="indexterm"/><a id="I_indexterm5_id296271" class="indexterm"/></p><p>Whatever your data, it can’t be made useful and visual until it is <span class="emphasis"><em>attached</em></span> to something. In D3 lingo, the data must be <span class="emphasis"><em>bound</em></span> to elements within the page. Let’s address how to create new page elements first. Then attaching data to those elements will be a cinch.<a id="ix_pgelem" class="indexterm"/></p><div class="sect1" title="Generating Page Elements"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="_generating_page_elements">Generating Page Elements</h2></div></div></div><p>Typically, when using D3 to generate new DOM elements, the new elements will be circles, rectangles, or other visual forms that represent your data. But to avoid confusing matters, we’ll start with a simple example and create a lowly <code class="literal">p</code> paragraph element.<a id="ix_pgelemcrt" class="indexterm"/><a id="I_indexterm5_id296340" class="indexterm"/></p><p>Begin by creating a new document with our simple HTML template from the last chapter. You can find it in the sample code files as <span class="emphasis"><em>01_empty_page_template.html</em></span>, and it looks like the following code. (Eagle-eyed viewers will notice that I’ve modified the <code class="literal">src</code> path here due to work with the directory structure of the code samples. If that doesn’t mean anything to you, don’t worry about it.)</p><a id="I_programlisting5_id296361"/><pre class="programlisting"><code class="cp">&lt;!DOCTYPE html&gt;</code> <code class="nt">&lt;html</code> <code class="na">lang=</code><code class="s">"en"</code><code class="nt">&gt;</code> <code class="nt">&lt;head&gt;</code> <code class="nt">&lt;meta</code> <code class="na">charset=</code><code class="s">"utf-8"</code><code class="nt">&gt;</code> <code class="nt">&lt;title&gt;</code>D3 Page Template<code class="nt">&lt;/title&gt;</code> <code class="nt">&lt;script </code><code class="na">type=</code><code class="s">"text/javascript"</code> <code class="na">src=</code><code class="s">"../d3/d3.v3.js"</code><code class="nt">&gt;&lt;/script&gt;</code> <code class="nt">&lt;/head&gt;</code> <code class="nt">&lt;body&gt;</code> <code class="nt">&lt;script </code><code class="na">type=</code><code class="s">"text/javascript"</code><code class="nt">&gt;</code> <code class="c1">// Your beautiful D3 code will go here</code> <code class="nt">&lt;/script&gt;</code> <code class="nt">&lt;/body&gt;</code> <code class="nt">&lt;/html&gt;</code></pre><p>Open that page in your web browser. Make sure you’re accessing the page via your local web server, as we discussed in <a class="xref" href="ch04.html" title="Chapter 4. Setup">Chapter 4</a>. So the URL in your browser’s location bar should look something like this:</p><pre class="literallayout">http://localhost:8888/d3-book/chapter_05/01_empty_page_template.html</pre><p>If not viewed through a web server, the URL path will start with <span class="emphasis"><em>file:///</em></span> instead of <span class="emphasis"><em>http://</em></span>. Confirm that the URL does <span class="emphasis"><em>not</em></span> look like this:</p><pre class="literallayout">file:///…/d3-book/chapter_05/01_empty_page_template.html</pre><p>Once you’re viewing the page, pop open the web inspector. (As a reminder, see <a class="xref" href="ch03.html#developer_tools_3" title="Developer Tools">Developer Tools</a> on how to do that.) You should see an empty web page, with the DOM contents shown in <a class="xref" href="ch05.html#Web_inspector" title="Figure 5-1. Web inspector">Figure 5-1</a>.</p><div class="figure"><a id="Web_inspector"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id296428"/><img src="httpatomoreillycomsourceoreillyimages1614739.png" alt="Web inspector"/></div></div><div class="figure-title">Figure 5-1. Web inspector</div></div><p>Back in your text editor, replace the comment between the <code class="literal">script</code> tags with:</p><a id="I_programlisting5_id296457"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">).</code><code class="nx">append</code><code class="p">(</code><code class="s2">"p"</code><code class="p">).</code><code class="nx">text</code><code class="p">(</code><code class="s2">"New paragraph!"</code><code class="p">);</code></pre><p>Save and refresh, and voilà! There is text in the formerly empty browser window, and the web inspector will look like <a class="xref" href="ch05.html#Web_inspector_again" title="Figure 5-2. Web inspector, again">Figure 5-2</a>.</p><div class="figure"><a id="Web_inspector_again"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id296480"/><img src="httpatomoreillycomsourceoreillyimages1614740.png" alt="Web inspector, again"/></div></div><div class="figure-title">Figure 5-2. Web inspector, again</div></div><p>See the difference? Now in the DOM, there is a new paragraph element that was generated on the fly! This might not be exciting yet, but you will soon use a similar technique to dynamically generate tens or hundreds of elements, each one corresponding to a piece of your dataset.</p><p>Let’s walk through what just happened. (You can follow along with <span class="emphasis"><em>02_new_element.html</em></span>.) To understand that first line of D3 code, you must first meet your new best friend, <span class="emphasis"><em>chain syntax</em></span>.</p><div class="sect2" title="Chaining Methods"><div class="titlepage"><div><div><h3 class="title" id="_chaining_methods">Chaining Methods</h3></div></div></div><p>D3 smartly employs a technique called <span class="emphasis"><em>chain syntax</em></span>, which you might recognize from jQuery. By “chaining” methods together with periods, you can perform several actions in a single line of code. It can be fast and easy, but it’s important to understand how it works, to save yourself hours of debugging headaches later.<a id="I_indexterm5_id296535" class="indexterm"/><a id="I_indexterm5_id296541" class="indexterm"/></p><p>By the way, <span class="emphasis"><em>functions</em></span> and <span class="emphasis"><em>methods</em></span> are just two different words for the same concept: a chunk of code that accepts an argument as input, performs some action, and returns some other information as output.<a id="I_indexterm5_id296562" class="indexterm"/><a id="I_indexterm5_id296570" class="indexterm"/></p><p>The following code:</p><a id="I_programlisting5_id296581"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">).</code><code class="nx">append</code><code class="p">(</code><code class="s2">"p"</code><code class="p">).</code><code class="nx">text</code><code class="p">(</code><code class="s2">"New paragraph!"</code><code class="p">);</code></pre><p>might look like a big mess, especially if you’re new to programming. So the first thing to know is that JavaScript, like HTML, doesn’t care about whitespace and line breaks, so you can put each method on its own<a id="I_indexterm5_id296592" class="indexterm"/> line for legibility:</p><a id="I_programlisting5_id296602"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">)</code> <code class="p">.</code><code class="nx">append</code><code class="p">(</code><code class="s2">"p"</code><code class="p">)</code> <code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="s2">"New paragraph!"</code><code class="p">);</code></pre><p>Both I and your optometrist highly recommend putting each method on its own indented line. But programmers have their own coding style; use whatever indents, line breaks, and whitespace (tabs or spaces) are most legible for you.<a id="I_indexterm5_id296614" class="indexterm"/><a id="I_indexterm5_id296622" class="indexterm"/></p></div><div class="sect2" title="One Link at a Time"><div class="titlepage"><div><div><h3 class="title" id="_one_link_at_a_time">One Link at a Time</h3></div></div></div><p>Let’s deconstruct each line in this chain of code:</p><div class="variablelist"><dl><dt><span class="term"> <code class="literal">d3</code> </span></dt><dd> References the D3 object, so we can access its methods. Our D3 adventure begins here. </dd><dt><span class="term"> <code class="literal">.select("body")</code> </span></dt><dd> Give the <a class="ulink" href="http://bit.ly/12h4SF1" target="_top"><code class="literal">select()</code></a> method a CSS selector as input, and it will return a reference to the first element in the DOM that matches. (Use <a class="ulink" href="http://bit.ly/WwINKs" target="_top"><code class="literal">selectAll()</code></a> when you need more than one element.) In this case, we just want the <code class="literal">body</code> of the document, so a reference to <code class="literal">body</code> is handed off to the next method in our chain. </dd><dt><span class="term"> <code class="literal">.append("p")</code> </span></dt><dd> <a class="ulink" href="https://github.com/mbostock/d3/wiki/Selections#wiki-append" target="_top"><code class="literal">append()</code></a> creates whatever new DOM element you specify and appends it to the end (but <span class="emphasis"><em>just inside</em></span>) of whatever selection it’s acting on. In our case, we want to create a new <code class="literal">p</code> within the <code class="literal">body</code>. We specified <code class="literal">"p"</code> as the input argument, but this method also sees the reference to <code class="literal">body</code> that was passed down the chain from the <code class="literal">select()</code> method. So an empty <code class="literal">p</code> paragraph is <span class="emphasis"><em>appended</em></span> to the <code class="literal">body</code>. Finally, <code class="literal">append()</code> hands off a reference to the new element it just created. </dd><dt><span class="term"> <code class="literal">.text("New paragraph!")</code> </span></dt><dd> <a class="ulink" href="https://github.com/mbostock/d3/wiki/Selections#wiki-text" target="_top"><code class="literal">text()</code></a> takes a string and inserts it between the opening and closing tags of the current selection. Because the previous method passed down a reference to our new <code class="literal">p</code>, this code just inserts the new text between <code class="literal">&lt;p&gt;</code> and <code class="literal">&lt;/p&gt;</code>. (In cases where there is existing content, it will be overwritten.) </dd><dt><span class="term"> <code class="literal">;</code> </span></dt><dd> The all-important semicolon indicates the end of this line of code. Chain over. </dd></dl></div></div><div class="sect2" title="The Hand-off"><div class="titlepage"><div><div><h3 class="title" id="_the_hand_off">The Hand-off</h3></div></div></div><p>Many, but not all, D3 methods return a selection (actually, a reference to a selection), which enables this handy technique of method chaining. Typically, a method returns a reference to the element that it just acted on, but not always.<a id="I_indexterm5_id296850" class="indexterm"/></p><p>So remember this: when chaining methods, order matters. The output type of one method has to match the input type expected by the next method in the chain. If adjacent inputs and outputs are mismatched, the hand-off will function more like a dropped baton in a middle-school relay race.</p><p>When sussing out what each function expects and returns, <a class="ulink" href="https://github.com/mbostock/d3/wiki/API-Reference" target="_top">the API reference</a> is your friend. It contains detailed information on each method, including whether or not it returns a selection.<a id="I_indexterm5_id296876" class="indexterm"/><a id="I_indexterm5_id296885" class="indexterm"/></p></div><div class="sect2" title="Going Chainless"><div class="titlepage"><div><div><h3 class="title" id="_going_chainless">Going Chainless</h3></div></div></div><p>Our sample code could be rewritten without chain syntax:</p><a id="I_programlisting5_id296909"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">body</code> <code class="o">=</code> <code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">);</code> <code class="kd">var</code> <code class="nx">p</code> <code class="o">=</code> <code class="nx">body</code><code class="p">.</code><code class="nx">append</code><code class="p">(</code><code class="s2">"p"</code><code class="p">);</code> <code class="nx">p</code><code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="s2">"New paragraph!"</code><code class="p">);</code></pre><p>Ugh! What a mess. Yet there will be times you need to break the chain, such as when you are calling so many functions that it doesn’t make sense to string them all together. Or just because you want to organize your code in a way that makes more sense to you.</p><p>Now that you know how to generate new page elements with D3, it’s time to attach data to them.<a id="I_indexterm5_id296925" class="indexterm"/><a id="I_indexterm5_id296932" class="indexterm"/></p></div></div><div class="sect1" title="Binding Data"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="_binding_data">Binding Data</h2></div></div></div><p>What is binding, and why would I want to do it to my data?<a id="ix_databind" class="indexterm"/><a id="ix_pebind" class="indexterm"/></p><p>Data visualization is a process of <span class="emphasis"><em>mapping</em></span> data to visuals. Data in, visual properties out. Maybe bigger numbers make taller bars, or special categories trigger brighter colors. The mapping rules are up to you.<a id="I_indexterm5_id296987" class="indexterm"/></p><p>With D3, we <span class="emphasis"><em>bind</em></span> our data input values to elements in the DOM. Binding is like “attaching” or associating data to specific elements, so that later you can reference those values to apply mapping rules. Without the binding step, we have a bunch of data-less, unmappable DOM elements. No one wants that.</p><div class="sect2" title="In a Bind"><div class="titlepage"><div><div><h3 class="title" id="_in_a_bind">In a Bind</h3></div></div></div><p>We use D3’s <a class="ulink" href="https://github.com/mbostock/d3/wiki/Selections#wiki-data" target="_top"><code class="literal">selection.data()</code></a> method to bind data to DOM elements. But there are two things we need in place first, before we can bind data:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> The data </li><li class="listitem"> A selection of DOM elements </li></ul></div><p>Let’s tackle these one at a time.</p></div><div class="sect2" title="Data"><div class="titlepage"><div><div><h3 class="title" id="_data">Data</h3></div></div></div><p>D3 is smart about handling different kinds of data, so it will accept practically any array of numbers, strings, or objects (themselves containing other arrays or key/value pairs). It can handle JSON (and GeoJSON) gracefully, and even has a built-in method to help you load in CSV files.<a id="I_indexterm5_id297065" class="indexterm"/><a id="I_indexterm5_id297074" class="indexterm"/></p><p>But to keep things simple, for now we will start with a boring array of five numbers. Here is our sample dataset:</p><a id="I_programlisting5_id297086"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">dataset</code> <code class="o">=</code> <code class="p">[</code> <code class="mi">5</code><code class="p">,</code> <code class="mi">10</code><code class="p">,</code> <code class="mi">15</code><code class="p">,</code> <code class="mi">20</code><code class="p">,</code> <code class="mi">25</code> <code class="p">];</code></pre><p>If you’re feeling adventurous, or already have some data in CSV or JSON format that you want to play with, here’s how to do that. Otherwise, just skip ahead to <a class="xref" href="ch05.html#please_make_your_selection_5" title="Please Make Your Selection">Please Make Your Selection</a>. <a id="I_indexterm5_id297100" class="indexterm"/><a id="I_indexterm5_id297106" class="indexterm"/></p><div class="sect3" title="Loading CSV data"><div class="titlepage"><div><div><h4 class="title" id="_loading_csv_data">Loading CSV data</h4></div></div></div><p>CSV stands for comma-separated values. A CSV data file might look something like this:</p><pre class="screen">Food,Deliciousness Apples,9 Green Beans,5 Egg Salad Sandwich,4 Cookies,10 Vegemite,0.2 Burrito,7</pre><p>Each line in the file has the same number of values (two, in this case), and values are separated by a comma. The first line in the file often serves as a header, providing names for each of the “columns” of data.</p><p>If you have data in an Excel file, it probably follows a similar structure of rows and columns. To get that data into D3, open it in Excel, then choose Save as… and select CSV as the file type.</p><p>If we saved the preceding CSV data into a file called <span class="emphasis"><em>food.csv</em></span>, then we could load the file into D3 by using the <code class="literal">d3.csv()</code> method:</p><a id="I_programlisting5_id297154"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">csv</code><code class="p">(</code><code class="s2">"food.csv"</code><code class="p">,</code> <code class="kd">function</code><code class="p">(</code><code class="nx">data</code><code class="p">)</code> <code class="p">{</code> <code class="nx">console</code><code class="p">.</code><code class="nx">log</code><code class="p">(</code><code class="nx">data</code><code class="p">);</code> <code class="p">});</code></pre><p><code class="literal">csv()</code> takes two arguments: a string representing the path of the CSV file to load in, and an anonymous function, to be used as a <span class="emphasis"><em>callback function</em></span>. The callback function is “called” only <span class="emphasis"><em>after</em></span> the CSV file has been loaded into memory. So you can be sure that, by the time the callback is called, <code class="literal">d3.csv()</code> is done executing.<a id="I_indexterm5_id297179" class="indexterm"/><a id="I_indexterm5_id297185" class="indexterm"/></p><p>When called, the anonymous function is handed the result of the CSV loading and parsing process; that is, the data. Here I’m naming it <code class="literal">data</code>, but this could be called whatever you like. You should use this callback function to do all the things you can do only <span class="emphasis"><em>after</em></span> the data has been loaded. In the preceding example, we are just logging the value of the <code class="literal">data</code> array to the console, to verify it, as shown in <a class="xref" href="ch05.html#Array_logged_to_console" title="Figure 5-3. Array logged to console">Figure 5-3</a>. (See <span class="emphasis"><em>03_csv_loading_example.html</em></span> in the example code.)</p><div class="figure"><a id="Array_logged_to_console"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297228"/><img src="httpatomoreillycomsourceoreillyimages1614741.png.jpg" alt="Array logged to console"/></div></div><div class="figure-title">Figure 5-3. Array logged to console</div></div><p>You can see that <code class="literal">data</code> is an array (because of the hard brackets <code class="literal">[]</code> on either end) with six elements, each of which is an object. By toggling the disclosure triangles next to each object, we can see their<a id="I_indexterm5_id297258" class="indexterm"/> values (see <a class="xref" href="ch05.html#Array_elements_expanded" title="Figure 5-4. Array elements expanded">Figure 5-4</a>).</p><div class="figure"><a id="Array_elements_expanded"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297278"/><img src="httpatomoreillycomsourceoreillyimages1614742.png" alt="Array elements expanded"/></div></div><div class="figure-title">Figure 5-4. Array elements expanded</div></div><p>Aha! Each object has both a <code class="literal">Food</code> property and a <code class="literal">Deliciousness</code> property, the values of which correspond to the values in our CSV! (There is also a third property, <code class="literal">__proto__</code>, but that has to do with how JavaScript handles objects, and you can ignore it for now.) D3 has employed the first row of the CSV for property names, and subsequent rows for values. You might not realize it, but this just saved you a <span class="emphasis"><em>lot</em></span> of time.<a id="I_indexterm5_id297316" class="indexterm"/></p><p>One more thing to note is that each value from the CSV is stored as a string, even the numbers. (You can tell because 9 is surrounded by quotation marks, as in <code class="literal">"9"</code> and not simply <code class="literal">9</code>.) This could cause unexpected behavior later, if you try to reference your data as a numeric value but it is still typed as a string.</p><div class="sidebar"><a id="handling_data_loading_errors_5"/><div class="sidebar-title">Handling Data Loading Errors</div><p>Note that <code class="literal">d3.csv()</code> is an <span class="emphasis"><em>asynchronous</em></span> method, meaning that the rest of your code is executed even while JavaScript is simultaneously waiting for the file to finish downloading into the browser. (The same is true of D3’s other functions that load external resources, such as <code class="literal">d3.json()</code>.)<a id="I_indexterm5_id297363" class="indexterm"/><a id="I_indexterm5_id297369" class="indexterm"/></p><p>This can potentially be <span class="emphasis"><em>very</em></span> confusing, because you—as a reasonable human person—might assume that the CSV file’s data is available, when in fact it hasn’t finished loading yet. A common mistake is to include references to the external data <span class="emphasis"><em>outside of</em></span> the callback function. Save yourself some headaches and make sure to reference your data only from <span class="emphasis"><em>within</em></span> the callback function (or from within other functions that you call within the callback function).<a id="I_indexterm5_id297396" class="indexterm"/><a id="I_indexterm5_id297402" class="indexterm"/></p><p>Personally, I like to declare a global variable first, then call <code class="literal">d3.csv()</code> to load the data. Within the callback function, I copy the data into my global variable (so it’s available to all of my subsequent functions), and finally I call any functions that rely on that data being present. For example:</p><a id="I_programlisting5_id297421"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">dataset</code><code class="p">;</code> <code class="c1">//Global variable</code> <code class="nx">d3</code><code class="p">.</code><code class="nx">csv</code><code class="p">(</code><code class="s2">"food.csv"</code><code class="p">,</code> <code class="kd">function</code><code class="p">(</code><code class="nx">data</code><code class="p">)</code> <code class="p">{</code> <code class="nx">dataset</code> <code class="o">=</code> <code class="nx">data</code><code class="p">;</code> <code class="c1">//Once loaded, copy to dataset.</code> <code class="nx">generateVis</code><code class="p">();</code> <code class="c1">//Then call other functions that</code> <code class="nx">hideLoadingMsg</code><code class="p">();</code> <code class="c1">//depend on data being present.</code> <code class="p">});</code></pre><p>To further confuse matters, the callback function is executed <span class="emphasis"><em>whether or not the datafile was loaded successfully</em></span>. That’s right, if the network connection fails, or the filename is misspelled, or for some reason an error occurs on the web server end, the callback function will <span class="emphasis"><em>still</em></span> be executed. When the data fails to load, and you call functions that rely on that data being present, you will probably see an error in the console, and the visualization won’t be created. This scenario might happen only rarely, but it’s useful to know how to handle it.</p><p>Fortunately, you can include an optional <code class="literal">error</code> parameter in the callback function definition. If there is a problem loading the file, then <code class="literal">error</code> will be set to the error message returned by the web server, and <code class="literal">data</code> will be <code class="literal">undefined</code>. If the file loads successfully and there is no error, then <code class="literal">error</code> will be <code class="literal">null</code>, and the <code class="literal">data</code> array will be populated as expected. Note that <code class="literal">error</code> must be the first parameter, and <code class="literal">data</code> the second:</p><a id="I_programlisting5_id297483"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">dataset</code><code class="p">;</code> <code class="nx">d3</code><code class="p">.</code><code class="nx">csv</code><code class="p">(</code><code class="s2">"food.csv"</code><code class="p">,</code> <code class="kd">function</code><code class="p">(</code><code class="nx">error</code><code class="p">,</code> <code class="nx">data</code><code class="p">)</code> <code class="p">{</code> <code class="k">if</code> <code class="p">(</code><code class="nx">error</code><code class="p">)</code> <code class="p">{</code> <code class="c1">//If error is not null, something went wrong.</code> <code class="nx">console</code><code class="p">.</code><code class="nx">log</code><code class="p">(</code><code class="nx">error</code><code class="p">);</code> <code class="c1">//Log the error.</code> <code class="p">}</code> <code class="k">else</code> <code class="p">{</code> <code class="c1">//If no error, the file loaded correctly. Yay!</code> <code class="nx">console</code><code class="p">.</code><code class="nx">log</code><code class="p">(</code><code class="nx">data</code><code class="p">);</code> <code class="c1">//Log the data.</code> <code class="c1">//Include other code to execute after successful file load here</code> <code class="nx">dataset</code> <code class="o">=</code> <code class="nx">data</code><code class="p">;</code> <code class="nx">generateVis</code><code class="p">();</code> <code class="nx">hideLoadingMsg</code><code class="p">();</code> <code class="p">}</code> <code class="p">});</code></pre></div><p>Verifying your data is a great use of the <code class="literal">csv()</code> callback function, but typically this is where you’d call other functions that construct the visualization, now that the data is available, as in:</p><a id="I_programlisting5_id297502"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">dataset</code><code class="p">;</code> <code class="c1">//Declare global var</code> <code class="nx">d3</code><code class="p">.</code><code class="nx">csv</code><code class="p">(</code><code class="s2">"food.csv"</code><code class="p">,</code> <code class="kd">function</code><code class="p">(</code><code class="nx">data</code><code class="p">)</code> <code class="p">{</code> <code class="c1">//Hand CSV data off to global var,</code> <code class="c1">//so it's accessible later.</code> <code class="nx">dataset</code> <code class="o">=</code> <code class="nx">data</code><code class="p">;</code> <code class="c1">//Call some other functions that</code> <code class="c1">//generate your visualization, e.g.:</code> <code class="nx">generateVisualization</code><code class="p">();</code> <code class="nx">makeAwesomeCharts</code><code class="p">();</code> <code class="nx">makeEvenAwesomerCharts</code><code class="p">();</code> <code class="nx">thankAwardsCommittee</code><code class="p">();</code> <code class="p">});</code></pre><p>One more tip: if you have <span class="emphasis"><em>tab</em></span>-separated data in a TSV file, try the <code class="literal">d3.tsv()</code> method, which otherwise behaves exactly as the preceding method.<a id="I_indexterm5_id297520" class="indexterm"/></p></div><div class="sect3" title="Loading JSON data"><div class="titlepage"><div><div><h4 class="title" id="_loading_json_data">Loading JSON data</h4></div></div></div><p>We’ll spend more time talking about JSON later, but for now, all you need<a id="I_indexterm5_id297539" class="indexterm"/> to know is that the <code class="literal">d3.json()</code> method works the same way as <code class="literal">csv()</code>. Load your JSON data in this way:</p><a id="I_programlisting5_id297556"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">json</code><code class="p">(</code><code class="s2">"waterfallVelocities.json"</code><code class="p">,</code> <code class="kd">function</code><code class="p">(</code><code class="nx">json</code><code class="p">)</code> <code class="p">{</code> <code class="nx">console</code><code class="p">.</code><code class="nx">log</code><code class="p">(</code><code class="nx">json</code><code class="p">);</code> <code class="c1">//Log output to console</code> <code class="p">});</code></pre><p>Here, I’ve named the parsed output <code class="literal">json</code>, but it could be called <code class="literal">data</code> or whatever you like.</p></div></div><div class="sect2" title="Please Make Your Selection"><div class="titlepage"><div><div><h3 class="title" id="please_make_your_selection_5">Please Make Your Selection</h3></div></div></div><p>The data is ready to go. As a reminder, we are working with this simple array:</p><a id="I_programlisting5_id297590"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">dataset</code> <code class="o">=</code> <code class="p">[</code> <code class="mi">5</code><code class="p">,</code> <code class="mi">10</code><code class="p">,</code> <code class="mi">15</code><code class="p">,</code> <code class="mi">20</code><code class="p">,</code> <code class="mi">25</code> <code class="p">];</code></pre><p>Now you need to decide what to select. That is, what elements will your data be associated with? Again, let’s keep it super simple and say that we want to make a new paragraph for each value in the dataset. So you might imagine something like this would be helpful:</p><a id="I_programlisting5_id297602"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">).</code><code class="nx">selectAll</code><code class="p">(</code><code class="s2">"p"</code><code class="p">)</code></pre><p>and you’d be right, but there’s a catch: the paragraphs we want to select <span class="emphasis"><em>don’t exist yet</em></span>. And this gets at one of the most common points of confusion with D3: how can we select elements that don’t yet exist? Bear with me, as the answer might require bending your mind a bit.</p><p>The answer lies with <code class="literal">enter()</code>, a truly magical method. See this code,<a id="I_indexterm5_id297624" class="indexterm"/><a id="I_indexterm5_id297631" class="indexterm"/> which I’ll explain:</p><a id="I_programlisting5_id297639"/><pre class="programlisting"><code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">).</code><code class="nx">selectAll</code><code class="p">(</code><code class="s2">"p"</code><code class="p">)</code> <code class="p">.</code><code class="nx">data</code><code class="p">(</code><code class="nx">dataset</code><code class="p">)</code> <code class="p">.</code><code class="nx">enter</code><code class="p">()</code> <code class="p">.</code><code class="nx">append</code><code class="p">(</code><code class="s2">"p"</code><code class="p">)</code> <code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="s2">"New paragraph!"</code><code class="p">);</code></pre><p>View the example code <span class="emphasis"><em>04_creating_paragraphs.html</em></span> and you should see five new paragraphs, each with the same content, as shown in <a class="xref" href="ch05.html#Dynamic_paragraphs" title="Figure 5-5. Dynamic paragraphs">Figure 5-5</a>.</p><div class="figure"><a id="Dynamic_paragraphs"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297667"/><img src="httpatomoreillycomsourceoreillyimages1614743.png.jpg" alt="Dynamic paragraphs"/></div></div><div class="figure-title">Figure 5-5. Dynamic paragraphs</div></div><p>Here’s what’s happening:</p><div class="variablelist"><dl><dt><span class="term"> <code class="literal">d3.select("body")</code> </span></dt><dd> Finds the <code class="literal">body</code> in the DOM and hands off a reference to the next step in the chain. </dd><dt><span class="term"> <code class="literal">.selectAll("p")</code> </span></dt><dd> Selects all paragraphs in the DOM. Because none exist yet, this returns an empty selection. Think of this empty selection as representing the paragraphs that <span class="emphasis"><em>will soon exist</em></span>. </dd><dt><span class="term"> <code class="literal">.data(dataset)</code> </span></dt><dd> Counts and parses our data values. There are five values in our array called <code class="literal">dataset</code>, so everything past this point is executed five times, once for each value. </dd><dt><span class="term"> <code class="literal">.enter()</code> </span></dt><dd> To create new, data-bound elements, you must use <code class="literal">enter()</code>. This method looks at the current DOM selection, and then at the data being handed to it. If there are more data values than corresponding DOM elements, then <code class="literal">enter()</code> <span class="emphasis"><em>creates a new placeholder element</em></span> on which you can work your magic. It then hands off a reference to this new placeholder to the next step in the chain. </dd><dt><span class="term"> <code class="literal">.append("p")</code> </span></dt><dd> Takes the empty placeholder selection created by <code class="literal">enter()</code> and appends a <code class="literal">p</code> element into the DOM. Hooray! Then it hands off a reference to the element it just created to the next step in the chain. </dd><dt><span class="term"> <code class="literal">.text("New paragraph!")</code> </span></dt><dd> Takes the reference to the newly created <code class="literal">p</code> and inserts a text value. </dd></dl></div></div><div class="sect2" title="Bound and Determined"><div class="titlepage"><div><div><h3 class="title" id="_bound_and_determined">Bound and Determined</h3></div></div></div><p>All right! Our data has been read, parsed, and bound to new <code class="literal">p</code> elements that we created in the DOM. Don’t believe me? Take another look at <span class="emphasis"><em>04_creating_paragraphs.html</em></span> and whip out your web inspector, shown in <a class="xref" href="ch05.html#new_p_elements_in_the_inspector" title="Figure 5-6. New p elements in the web inspector">Figure 5-6</a>.</p><div class="figure"><a id="new_p_elements_in_the_inspector"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297884"/><img src="httpatomoreillycomsourceoreillyimages1614744.png" alt="New p elements in the web inspector"/></div></div><div class="figure-title">Figure 5-6. New <code class="literal">p</code> elements in the web inspector</div></div><p>Okay, I see five paragraphs, but where’s the data? Switch to the JavaScript console, type in the following code, and click Enter. The results are shown in <a class="xref" href="ch05.html#logging_to_from_console" title="Figure 5-7. Logging to the console, from the console">Figure 5-7</a>:</p><a id="I_programlisting5_id297912"/><pre class="programlisting"><code class="nx">console</code><code class="p">.</code><code class="nx">log</code><code class="p">(</code><code class="nx">d3</code><code class="p">.</code><code class="nx">selectAll</code><code class="p">(</code><code class="s2">"p"</code><code class="p">))</code></pre><div class="figure"><a id="logging_to_from_console"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297926"/><img src="httpatomoreillycomsourceoreillyimages1614745.png" alt="Logging to the console, from the console"/></div></div><div class="figure-title">Figure 5-7. Logging to the console, from the console</div></div><p>An array! Or, really, an array containing another array. Click the gray disclosure triangle to reveal its contents, shown in <a class="xref" href="ch05.html#array_of_arrays" title="Figure 5-8. Array of arrays, expanded">Figure 5-8</a>.</p><div class="figure"><a id="array_of_arrays"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297960"/><img src="httpatomoreillycomsourceoreillyimages1614746.png" alt="Array of arrays, expanded"/></div></div><div class="figure-title">Figure 5-8. Array of arrays, expanded</div></div><p>You’ll notice the five <code class="literal">p</code>s, numbered 0 through 4. Click the disclosure triangle next to the first one (number zero), which results in the view shown in <a class="xref" href="ch05.html#the_p_element_expanded" title="Figure 5-9. The p element, expanded">Figure 5-9</a>.</p><div class="figure"><a id="the_p_element_expanded"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id297998"/><img src="httpatomoreillycomsourceoreillyimages1614747.png" alt="The p element, expanded"/></div></div><div class="figure-title">Figure 5-9. The p element, expanded</div></div><p>See it? Do you see it? I can barely contain myself. There it is (<a class="xref" href="ch05.html#finally_bound_data" title="Figure 5-10. Finally, bound data">Figure 5-10</a>).</p><div class="figure"><a id="finally_bound_data"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id298032"/><img src="httpatomoreillycomsourceoreillyimages1614748.png.jpg" alt="Finally, bound data"/></div></div><div class="figure-title">Figure 5-10. Finally, bound data</div></div><p>Our first data value, the number <code class="literal">5</code>, is showing up under the first paragraph’s <code class="literal">__data__</code> attribute. Click into the other paragraph elements, and you’ll see they also contain <code class="literal">__data__</code> values: 10, 15, 20, and 25, just as we specified.</p><p>You see, when D3 binds data to an element, that data doesn’t exist in the DOM, but it does exist in memory as a <code class="literal">__data__</code> attribute of that element. And the console is where you can go to confirm whether or not your data was bound as expected.</p><p>The data is ready. Let’s do something with it.<a id="I_indexterm5_id298082" class="indexterm"/><a id="I_indexterm5_id298089" class="indexterm"/></p></div><div class="sect2" title="Using Your Data"><div class="titlepage"><div><div><h3 class="title" id="_using_your_data">Using Your Data</h3></div></div></div><p>We can see that the data has been loaded into the page and is bound to<a id="ix_bound" class="indexterm"/> our newly created elements in the DOM, but can we <span class="emphasis"><em>use</em></span> it? Here’s our code so far:</p><a id="I_programlisting5_id298128"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">dataset</code> <code class="o">=</code> <code class="p">[</code> <code class="mi">5</code><code class="p">,</code> <code class="mi">10</code><code class="p">,</code> <code class="mi">15</code><code class="p">,</code> <code class="mi">20</code><code class="p">,</code> <code class="mi">25</code> <code class="p">];</code> <code class="nx">d3</code><code class="p">.</code><code class="nx">select</code><code class="p">(</code><code class="s2">"body"</code><code class="p">).</code><code class="nx">selectAll</code><code class="p">(</code><code class="s2">"p"</code><code class="p">)</code> <code class="p">.</code><code class="nx">data</code><code class="p">(</code><code class="nx">dataset</code><code class="p">)</code> <code class="p">.</code><code class="nx">enter</code><code class="p">()</code> <code class="p">.</code><code class="nx">append</code><code class="p">(</code><code class="s2">"p"</code><code class="p">)</code> <code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="s2">"New paragraph!"</code><code class="p">);</code></pre><p>Let’s change the last line to:</p><a id="I_programlisting5_id298139"/><pre class="programlisting"> <code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="kd">function</code><code class="p">(</code><code class="nx">d</code><code class="p">)</code> <code class="p">{</code> <code class="k">return</code> <code class="nx">d</code><code class="p">;</code> <code class="p">});</code></pre><p>Now test out that new code in <span class="emphasis"><em>05_creating_paragraphs_text.html</em></span>. You should see the result shown in <a class="xref" href="ch05.html#more_dynamic_paragraphs" title="Figure 5-11. More dynamic paragraphs">Figure 5-11</a>.</p><div class="figure"><a id="more_dynamic_paragraphs"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id298167"/><img src="httpatomoreillycomsourceoreillyimages1614749.png.jpg" alt="More dynamic paragraphs"/></div></div><div class="figure-title">Figure 5-11. More dynamic paragraphs</div></div><p>Whoa! We used our data to populate the contents of each paragraph, all thanks to the magic of the <code class="literal">data()</code> method. You see, when chaining methods together, anytime after you call <code class="literal">data()</code>, you can create an anonymous function that accepts <code class="literal">d</code> as input. The magical <code class="literal">data()</code> method ensures that <code class="literal">d</code> is set to the corresponding value in your original dataset, given the current element at hand.<a id="I_indexterm5_id298209" class="indexterm"/></p><p>The value of “the current element” changes over time as D3 loops through each element. For example, when looping through the third time, our code creates the third <code class="literal">p</code> tag, and <code class="literal">d</code> will correspond to the third value in our dataset (or <code class="literal">dataset[2]</code>). So the third paragraph gets text content of “15”.</p></div><div class="sect2" title="High-Functioning"><div class="titlepage"><div><div><h3 class="title" id="_high_functioning">High-Functioning</h3></div></div></div><p>In case you’re new to writing your own functions (a.k.a. methods), the<a id="I_indexterm5_id298246" class="indexterm"/><a id="I_indexterm5_id298256" class="indexterm"/><a id="I_indexterm5_id298262" class="indexterm"/><a id="I_indexterm5_id298269" class="indexterm"/><a id="I_indexterm5_id298277" class="indexterm"/> basic structure of a function definition is:</p><a id="I_programlisting5_id298288"/><pre class="programlisting"><code class="kd">function</code><code class="p">(</code><code class="nx">input_value</code><code class="p">)</code> <code class="p">{</code> <code class="c1">//Calculate something here</code> <code class="k">return</code> <code class="nx">output_value</code><code class="p">;</code> <code class="p">}</code></pre><p>The function we used earlier is dead simple, nothing fancy:</p><a id="I_programlisting5_id298298"/><pre class="programlisting"><code class="kd">function</code><code class="p">(</code><code class="nx">d</code><code class="p">)</code> <code class="p">{</code> <code class="k">return</code> <code class="nx">d</code><code class="p">;</code> <code class="p">}</code></pre><p>This is called an <span class="emphasis"><em>anonymous function</em></span>, because it doesn’t have a name. Contrast that with a function that’s stored in a variable, which is a <span class="emphasis"><em>named function</em></span>:</p><a id="I_programlisting5_id298316"/><pre class="programlisting"><code class="kd">var</code> <code class="nx">doSomething</code> <code class="o">=</code> <code class="kd">function</code><code class="p">()</code> <code class="p">{</code> <code class="c1">//Code to do something here</code> <code class="p">};</code></pre><p>We’ll write lots of anonymous functions when using D3. They are the key to accessing individual data values and calculating dynamic properties.</p><p>This particular anonymous function is wrapped within D3’s <code class="literal">text()</code> function. So our anonymous function is executed first. Then its result is handed off to <code class="literal">text()</code>. Then <code class="literal">text()</code> finally works its magic (by inserting its input argument as text within the selected DOM element):</p><a id="I_programlisting5_id298344"/><pre class="programlisting"><code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="kd">function</code><code class="p">(</code><code class="nx">d</code><code class="p">)</code> <code class="p">{</code> <code class="k">return</code> <code class="nx">d</code><code class="p">;</code> <code class="p">});</code></pre><p>But we can (and will) get much fancier because you can customize these functions any way you like. Yes, this is both the pleasure and pain of writing your own JavaScript. Maybe you’d like to add some extra text, as in:</p><a id="I_programlisting5_id298355"/><pre class="programlisting"><code class="p">.</code><code class="nx">text</code><code class="p">(</code><code class="kd">function</code><code class="p">(</code><code class="nx">d</code><code class="p">)</code> <code class="p">{</code> <code class="k">return</code> <code class="s2">"I can count up to "</code> <code class="o">+</code> <code class="nx">d</code><code class="p">;</code> <code class="p">});</code></pre><p>which produces the result shown in <a class="xref" href="ch05.html#Still_more_dynamic_paragraphs" title="Figure 5-12. Still more dynamic paragraphs">Figure 5-12</a>, as seen in example file <span class="emphasis"><em>06_creating_paragraphs_counting.html</em></span>.</p><div class="figure"><a id="Still_more_dynamic_paragraphs"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject5_id298384"/><img src="httpatomoreillycomsourceoreillyimages1614750.png.jpg" alt="Still more dynamic paragraphs"/></div></div><div class="figure-title">Figure 5-12. Still more dynamic paragraphs</div></div></div><div class="sect2" title="Data Wants to Be Held"><div class="titlepage"><div><div><h3 class="title" id="_data_wants_to_be_held">Data Wants to Be Held</h3></div></div></div><p>You might be wondering w