On Github Yonet / NeoHack2015
Aysegul Yonet / @AysegulYonet
Slides : bit.ly/Neohack-d3
Not a prototyping tool.
Lot's of examples
<circle cx="250" cy="100" r="30" fill="#25B0B0"> </circle>
<rect x="200" y="50" width="100" height="100" rx="10" ry="0" fill="#25B0B0"> </rect>
Interesting fact: if a properly specified value is provided for rx but not for ry (or the opposite), then the browser will consider the missing value equal to the defined one.
<line x1="10" y1="10" x2="100" y2="100" stroke="blue" stroke-width="100"> </line>
<path d=" M50,100 L131,66 L259,115 L339,50 L400,98 M350,150 L100,150" fill="none" stroke="#25B0B0"> </path>
Unless you set the style of the SVG text, it inherits font-styles from CSS.
<svg> <text x="100" y="100" fill="red" font-family="arial" font-size="16"> Look at me, I am a text. </text> </svg>
Any transformations (positioning, scaling, rotating) that are applied to the group element will also be applied to each of the child elements.
<g transform="translate(100, 100)"> <circle cx="20" cy="10" r="30" fill="#25B0B0"> </circle> <circle cx="100" cy="10" r="30" fill="#25B0B0"> </circle> </g>
var paragraphs = $("div p");
var paragraphs = d3.select("div").selectAll("p");D3 difference: child nodes might not actually exist. Selectors in D3 are declared the same way as CSS rules. An important difference is that a D3 selector object only contains the elements that matched the selection rule when the selection was first created. The selection can be based on tag (as in the below example), class, identifier, attribute, or place in the hierarchy. Once elements are selected, one can apply operations to them. This includes getting and setting attributes, display texts, and styles. Elements may also be added and removed. This process of modifying, creating and removing HTML elements can be made dependent on data, which is the basic concept of D3.js.
Bind array of data to child nodes
d3.selectAll("p") .data([3, 7, 21, 31, 35, 42])
d3.select("body").selectAll("p") .data([3, 7, 21, 31, 35, 42]) .enter().append("p");When data is bound to a selection, each element in the data array is paired with the corresponding node in the selection. If there are fewer nodes than data, the extra data elements form the enter selection, which you can instantiate by appending to the enter selection
var bars = d3.select('svg').selectAll('rect').data(someData); //if we have more data, add new rectangles for those data items bars.enter().append('rect') //if we have less data points, remove the rectangles that no longer have a data pairing. bars.exit().remove();Using D3’s exit and remove, you can get rid of outgoing nodes that are no longer needed.
// Update… var p = d3.select("body").selectAll("p") .data([3, 7, 21, 31, 35, 42]); // Enter… p.enter().append("p") // Exit… p.exit().remove();if you forget about the enter and exit selections, you will automatically select only the elements for which there exists corresponding data. By handling these three cases separately, you specify precisely which operations run on which nodes.
Exercise: bit.ly/enter-exit-exercise
If you get stuck...Sotlution
You can operate over the nodes in a declarative way using selector methods.
You can use data values or index in a callback to define any property.
d3.select("div").selectAll("p").style("color", function(data, i) { return i % 2 ? "red" : "blue"; });
d3.selectAll("circle") .attr("r", "0"); .transition() .duration(750) .delay(function(d, i) { return i * 10; }) .attr("r", function(d) { return Math.sqrt(d); });
Exercise 0: Look at the example and create a transition to change the size of the circles:bit.ly/d3-transitions
Exercise 1: bit.ly/d3exercise1
In case you get stuck... Solution for Exercise 1
Scales and Domains
Axis
Loading external data
Scales transform a number in a certain interval (called the domain) into a number in another interval (called the range).
var x = d3.scale.linear() .domain([0, d3.max(data)]) .range([0, 420]); d3.select(".chart") .selectAll("div") .data([3, 7, 21, 31, 35, 42]) .enter().append("div") .style("width", function(d) { return x(d) + "px"; })JSFiddle
Ordinal Scale have a discrete domain, such as a set of names or categories.
var x = d3.scale.ordinal() .domain(["A", "B", "C", "D", "E", "F"]) .rangeRoundBands([0, width], .1);
d3.scale.category10() - Constructs a new ordinal scale with a range of ten categorical colors:
Solution: Bar Charts with Scale
d3.svg.axis creates a new axis generator.
var xAxis = d3.svg.axis() .scale(x) .orient('bottom') .tickValues(data);JSFiddle
d3.time.format - creates a new local time formatter for a given specifier.
d3.time.format("%Y-%m-%d");JSFiddle
d3.time.scale - constructs a linear time scale.
var xScale = d3.time.scale() .domain([2009-07-13T00:02, 2009-07-13T23:48]) .rangeRound([0, width]); //rangeRound does the same thing as range but rounds the values to integers or begining of dates.JSFiddle
d3.time.intervals - a time interval in local time.
Most commonly used functions
Slides : bit.ly/Neohack-d3