Chapter 03Using D3-fetch
The d3-fetch module provides various convenience methods that are built on top of the Fetch data transfer standard.
<script src="https://d3js.org/d3-fetch.v1.min.js"></script>
The d3-fetch convenience methods are shown below.
-
d3.dsv(delimiter, input[, init][, row]) - returns an array of objects, one for each row
-
d3.csv(input[, init][, row]) - returns an array of objects, one for each row
-
d3.tsv(input[, init][, row]) - returns an array of objects, one for each row
-
d3.json(input[, init]) - returns a single object
-
d3.xml(input[, init]) - returns a XML document node
-
d3.html(input[, init]) - returns a HTML document node
-
d3.text(input[, init]) - returns a string
-
d3.svg(input[, init]) - returns a SVG node
-
d3.image(input[, init]) - returns an image element
-
d3.blob(input[, init]) - returns a Blob
-
d3.buffer(input[, init]) - returns an ArrayBuffer
Below are examples on how to use all but the last 2 methods.
When calling the dsv, csv, tsv, json, xml, html, and text download functions, you’ll find a call to then
chained to the download function call as shown below. The code in the function passed to then
is executed after the file is downloaded and the data within the file is ready to be used.
d3.dsv(delimiter, fileName) .then(function(data) { // download has completed - do something with data }); // may be executed before the code passed to then() is executed!
This pattern is necessary because the browser does not wait for the data to be downloaded. Instead, the browser will request the download and continue with the rest of the code in the JavaScript file. When the download has finished, the browser will jump to the code within the call to then
and execute it.
To be clear, any code that relies on the data in the downloaded file must be executed after the file has been downloaded and is usually included in the function passed to then
. Second, any code that is written after the then
call, may be executed before the file has been downloaded and before the function passed to then
is executed.
In the examples below we use the d3-fetch functions to retrieve the contents of various data files that we have on our server. All of the files store similar information, just in different formats. In each examples, we pass a function to then
that converts the data that is returned by the helper functions to an array of objects, each having the properties letter, number, and color (if it is not already in that format). We then pass the id of an svg element and the array of objects to drawText
(shown below) which writes the text contained in the objects of the array to the svg element.
function drawText(id, data) { d3.select(id) .selectAll("text") .data(data) .enter() .append("text") .attr("y", (d,i) => i * 20 + 20) .attr("x", 10) .text((d) => d.letter + " " + d.number + " " + d.color); }
d3.dsv
The code fragment below fetches a file named sample.dsv which contains the following text.
letter|number|color A|1|red B|2|blue
Here is the code to read the dsv file.
<script> d3.dsv("|", "samples/sample.dsv") .then(function(data) { drawText("#dsvDemo", data); }); </script> <svg id="dsvDemo" class="lightblue" width="80" height="50"></svg>
d3.csv
The code fragment below fetches a file named sample.csv which contains the following text.
letter,number,color A,1,red B,2,blue
Here is the code to read the csv file.
<script> d3.csv("samples/sample.csv") .then(function(data) { drawText("#csvDemo", data); }); </script> <svg id="csvDemo" class="lightblue" width="80" height="50"></svg>
d3.tsv
The code fragment below fetches a file named sample.tsv which contains the following text.
letter number color A 1 red B 2 blue
Here is the code to read the tsv file.
<script> d3.tsv("samples/sample.tsv") .then(function(data) { drawText("#tsvDemo", data); }); </script> <svg id="tsvDemo" class="lightblue" width="80" height="50"></svg>
d3.json
The code fragment below fetches a file named sample.json which contains the following text.
{ "0":{ "letter": "A", "number": 1, "color": "red" }, "1": { "letter": "B", "number": 2, "color": "blue" } }
Here is the code to read the json file.
<script> d3.json("samples/sample.json") .then(function(data) { // data is an object, convert to array. data = [data[0], data[1]]; drawText("#jsonDemo", data); }); </script> <svg id="jsonDemo" class="lightblue" width="80" height="50"></svg>
d3.xml
The code fragment below fetches a file named sample.xml which contains the following text.
<?xml version="1.0" encoding="UTF-8" ?> <data> <item> <letter>A</letter> <number>1</number> <color>red</color> </item> <item> <letter>B</letter> <number>2</number> <color>blue</color> </item> </data>
Here is the code to read the xml file.
<script> d3.xml("samples/sample.xml") .then(function(data) { // data is an XML document, parse document data = [].map.call(data.querySelectorAll("item"), function(item) { return { letter: item.querySelector("letter").textContent, number: item.querySelector("number").textContent, color: item.querySelector("color").textContent }; }); drawText("#xmlDemo", data); }); </script> <svg id="xmlDemo" class="lightblue" width="80" height="50"></svg>
d3.html
The code fragment below fetches a file named sample.html which contains the following text.
<html> <body> <p>A 1 red</p> <p>B 2 blue</p> </body> </html>
Here is the code to read the html file.
<script> d3.html("samples/sample.html") .then(function(data) { // data is an HTML document, parse document data = [].map.call(data.querySelectorAll("p"), function(node) { let tokens = node.textContent.split(" "); return { letter: tokens[0], number: tokens[1], color: tokens[2] }; }); drawText("#htmlDemo", data); }); </script> <svg id="htmlDemo" class="lightblue" width="80" height="50"></svg>
The code fragment below fetches a file named sample.txt which contains the following text.
A 1 red B 2 blue
Here is the code to read the text file.
<script> d3.text("samples/sample.txt") .then(function(data) { // data is a string data = data.split("\n"); data = data.map((str) => { let tokens = str.split(" "); return { letter: tokens[0], number: tokens[1], color: tokens[2] }; }); drawText("#textDemo", data); }); </script> <svg id="textDemo" class="lightblue" width="80" height="50"></svg>
d3.svg
The code fragment below fetches a file named sample.svg which contains the following text.
<svg id="svgDemo" xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" width="64" height="64" > <rect width="100%" height="100%" fill="green" /> <circle cx="40" cy="40" r="40" fill="blue" /> </svg>
Here is the code to read the svg file.
<script> d3.svg("samples/sample.svg") .then(function(data) { var oldChild = document.getElementById("svgDemo"); document.getElementById("svgDemo").parentNode.replaceChild(data.documentElement, oldChild); }); </script> <svg id="svgDemo" class="lightblue" width="80" height="50"></svg>
d3.image
The code fragment below fetches a file named sample.png which contains a png that was created by exporting the above svg to a file with the png format.
Here is the code to read the png file.
<script> d3.image("samples/sample.png") .then(function(data) { let canvas = document.getElementById("imageDemo"); let ctx = canvas.getContext('2d'); ctx.drawImage(data, 0,0); }); </script> <canvas id="imageDemo" width="64px" height="64px"></canvas>