Javascript -- the super-fast version.

http://eloquentjavascript.net/

  • Visualisation
  • Data
  • Animation
  • Interaction
  • Reusable Charts, Graphs

Create the SVG element

var svgslide = d3.select("#svg #chart").append("svg:svg")
            .attr("width", slideWidth-100)
            .attr("height", slideHeight-100)
            .attr("class", "chart")
            .attr("class", "borders");

Add a Text Element

          svgslide.append("text")
            .attr("y", 325)
            .attr("x", 175)
            .attr("class", "logoText")
            .text("SVG");
        

Drawing things is simple

shapeslide.append("circle")
  .attr("cx", "50%")
  .attr("cy", "50%")
  .attr("r", "100")
  .attr("fill", "#fff");

Selectors

Select a document element and assign it to a variable

var slide =
d3.select("#svg #chart").append("svg:svg")

Select things that don't yet exist (!)

var circles = slide.selectAll("circle")

https://github.com/mbostock/d3/wiki/Selections

Data-driven Documents

var exampleData = [
    {"name":"Ireland","value":852}, {"name":"United Kingdom", "value":406},
    {"name":"France","value":182}, {"name":"Greece", "value":174},
    {"name":"Zimbabwe","value":103}];
Source
var countryscale = d3.scale.linear()
  .domain([0, d3.max(exampleData, function(d){return d.value;})])
  .range([0, 1]);

countryslide.selectAll("circle")
  .data(exampleData)
  .enter()
  .append("circle")
  .attr("cx", function(d,i){return (i * 20 + 15) + "%";})
  .attr("cy", "50%")
  .attr("fill", "white")
  .attr("r", function(d,i){return countryscale(d.value) * 100;})
animslidePos.select("rect")
  .transition()
  .duration(1000)
  .attr("x", "80%")
  .attr("y", "75%")
  .transition()
  .delay(1000)
  .attr("fill", "red");
animslideAdd.selectAll("text")
  .data(animslideAddData)
  .enter()
  .append("text")
  .attr("fill", "#00ff00")
  .attr("stroke", "#ddffdd")
  .attr("transform", "rotate(90)")
  .attr("font-size", "22px")
  .attr("x", "-20%")
  .attr("y", function(d,i){ return (-70 * i); })
  .text(function(d,i){console.log(d); return d;})
  .transition().duration(2000)
  .attr("x", "100%");

Interaction

  1. Mouse
  2. Touch
  3. Drag
  4. Zoom

API Reference

JSON & other animals

{
  "@context": {
    "ical": "http://www.w3.org/2002/12/cal/ical#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "ical:dtstart": {
      "@type": "xsd:dateTime"
    }
  },
  "ical:summary": "Lady Gaga Concert",
  "ical:location": "New Orleans Arena, New Orleans, Louisiana, USA",
  "ical:dtstart": "2011-04-09T20:00Z"
}

d3.json('../gaga.json', function(error, json){
    if (error) return console.warn(error);
    var now = new Date(Date.now());
    var then = new Date(json["ical:dtstart"]);
    var days = Math.floor((now-then) / (1000 * 60 * 60 * 24));
    d3.select('#dateOutput')
                    .append('p').text(days+' days elapsed');
});
        

D3.csv, D3.xml and others also exist.

Layouts and Physics

A huge amount of code for free, if you read the documentation
(beware Stackoverflow)

//Force-Directed Graph Setup
var forcecolor = d3.scale.category20();

var forceOne = d3.layout.force()
    .charge(-200)
    .linkDistance(100)
    .size([400, 400]);

var svgOne = d3.select("#forcechart").append("svg")
    .attr("class", "chart")
    .attr("width", "450px")
    .attr("height", "500px");

forceOne
    .nodes(graphOne.nodes)
    .links(graphOne.links)
    .start();

var linkOne = svgOne.selectAll(".link")
    .data(graphOne.links)
  .enter().append("line")
    .attr("class", "link")
    .style("stroke-width", function(d) { return Math.sqrt(d.value); });

var nodeOne = svgOne.selectAll(".node")
    .data(graphOne.nodes)
  .enter().append("circle")
    .attr("class", "node")
    .attr("r", 5)
    .style("fill", function(d) { return forcecolor(d.group); })
    .call(forceOne.drag);

nodeOne.append("title")
    .text(function(d) { return d.name; });


forceOne.on("tick", function() {
  linkOne.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  nodeOne.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
});

    
graphOne = {
   "nodes": [
       {"name":"A",  "group": 1},
       {"name":"B",  "group": 1},
       {"name":"C",  "group": 2},
       {"name":"D",  "group": 3},
       {"name":"E",  "group": 3}
   ],
   "links": [
       {"source":0, "target":1, "value":1},
       {"source":0, "target":2, "value":5},
       {"source":1, "target":2, "value":5},
       {"source":3, "target":4, "value":1},
       {"source":3, "target":2, "value":5},
       {"source":4, "target":2, "value":5},
   ]

};
    

Higher-level Libraries based on D3

Official list of tutorials

Example App: SPARQL Result Viewer

  1. Requesting the Data
  2. Displaying the text triples
  3. Drawing a graph
  4. Animating it
  5. Future Work
SELECT ?game, ?title
WHERE {
    ?game <http://purl.org/dc/terms/subject> 
<http://dbpedia.org/resource/Category:First-person_shooters> .
    ?game foaf:name ?title .
}
ORDER by ?title
LIMIT 5
d3.json(dbpediagame, function(error, json){
    console.log(json);      
});
        
 var rows = d3.select('#bindresults')
.selectAll("tr")
.data(json['results']['bindings'])
.enter()
.append("tr");

var cells = rows.selectAll('td')
.data(function(d){return d3.values(d)})
.enter().append("td")
.text(function(d) {return d['value']});
#graphresults circle:hover{
  stroke: #000;
  stroke-width: 3px;

}

Part of the attraction of SVG & D3 is that it's not a black box like flash or canvas.

Summary

  • D3 Provides lots of stuff for free
  • ... and Just enough Rope to hang yourself
  • The best option is to try and keep to the style which it imposes:
    • Use Selects
    • Evaluate lazily
    • Use the libraries for things like interpolation, colours

Use a spacebar or arrow keys to navigate