The basics
d3.select("body").append("svg")
.attr("width", 50)
.attr("height", 50)
.append("circle")
.attr("cx", 25)
.attr("cy", 25)
.attr("r", 25)
.style("fill", "purple")
var theData = [ 1, 2, 3 ]
var p = d3.select("body").selectAll("p")
.data(theData)
.enter()
.append("p")
.text("Hello");
//text(function () {
// return "hello world!";
//});
//.text(function (d) {
// return d * 2
//});
//.text(function (d, i) {
// return "Index: " + i + ", Val: " + d;
//});
console.log(p)
Binding shape properties to data
circleRadii = [40, 20, 10]
var svgContainer = d3.select("body").append("svg")
.attr("width", 600)
.attr("height", 100);
var circles = svgContainer.selectAll("circle")
.data(circleRadii)
.enter()
.append("circle")
var circleAttributes = circles
.attr("cx", 50)
.attr("cy", 50)
.attr("r", function (d) { return d; })
.style("fill", function(d) {
var returnColor;
if (d === 40) { returnColor = "green";
} else if (d === 20) { returnColor = "purple";
} else if (d === 10) { returnColor = "red"; }
return returnColor;
});
Binding styles and coordinates to data
var spaceCircles = [30, 70, 110];
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200);
var circles = svgContainer.selectAll("circle")
.data(spaceCircles)
.enter()
.append("circle");
var circleAttributes = circles
.attr("cx", function (d) { return d; })
.attr("cy", function (d) { return d; })
.attr("r", 20 )
.style("fill", function(d) {
var returnColor;
if (d === 30) { returnColor = "green";
} else if (d === 70) { returnColor = "purple";
} else if (d === 110) { returnColor = "red"; }
return returnColor;
});
Using json object as data
var jsonCircles = [
{
"x_axis": 30,
"y_axis": 30,
"radius": 20,
"color" : "green"
}, {
"x_axis": 70,
"y_axis": 70,
"radius": 20,
"color" : "purple"
}, {
"x_axis": 110,
"y_axis": 100,
"radius": 20,
"color" : "red"
}];
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200);
var circles = svgContainer.selectAll("circle")
.data(jsonCircles)
.enter()
.append("circle");
var circleAttributes = circles
.attr("cx", function (d) { return d.x_axis; })
.attr("cy", function (d) { return d.y_axis; })
.attr("r", function (d) { return d.radius; })
.style("fill", function(d) { return d.color; });
Polylines
//The data for our line
var lineData = [ { "x": 1, "y": 5}, { "x": 20, "y": 20},
{ "x": 40, "y": 10}, { "x": 60, "y": 40},
{ "x": 80, "y": 5}, { "x": 100, "y": 60}];
//This is the accessor function we talked about above
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
//The SVG Container
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200);
//The line SVG Path we draw
var lineGraph = svgContainer.append("path")
.attr("d", lineFunction(lineData))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
Dynamically determine size of svg
var jsonRectangles = [
{ "x_axis": 10, "y_axis": 10, "height": 20, "width":20, "color" : "green" },
{ "x_axis": 160, "y_axis": 40, "height": 20, "width":20, "color" : "purple" },
{ "x_axis": 70, "y_axis": 70, "height": 20, "width":20, "color" : "red" }];
var max_x = 0;
var max_y = 0;
for (var i = 0; i < jsonRectangles.length; i++) {
var temp_x, temp_y;
var temp_x = jsonRectangles[i].x_axis + jsonRectangles[i].width;
var temp_y = jsonRectangles[i].y_axis + jsonRectangles[i].height;
if ( temp_x >= max_x ) { max_x = temp_x; }
if ( temp_y >= max_y ) { max_y = temp_y; }
}
var svgContainer = d3.select("body").append("svg")
.attr("width", max_x)
.attr("height", max_y)
var rectangles = svgContainer.selectAll("rect")
.data(jsonRectangles)
.enter()
.append("rect");
var rectangleAttributes = rectangles
.attr("x", function (d) { return d.x_axis; })
.attr("y", function (d) { return d.y_axis; })
.attr("height", function (d) { return d.height; })
.attr("width", function (d) { return d.width; })
.style("fill", function(d) { return d.color; });
Linear scale
var initialScaleData = [0, 1000, 3000, 2000, 5000, 4000, 7000, 6000, 9000, 8000, 10000];
var newScaledData = [];
var minDataPoint = d3.min(initialScaleData);
var maxDataPoint = d3.max(initialScaleData);
var linearScale = d3.scale.linear()
.domain([minDataPoint,maxDataPoint])
.range([0,100]);
for (var i = 0; i < initialScaleData.length; i++) {
newScaledData[i] = linearScale(initialScaleData[i]);
}
newScaledData;
//[0, 10, 30, 20, 50, 40, 70, 60, 90, 80, 100]
Transformation
var circleData = [
{ "cx": 20, "cy": 20, "radius": 20, "color" : "green" },
{ "cx": 70, "cy": 70, "radius": 20, "color" : "purple" }];
var rectangleData = [
{ "rx": 110, "ry": 110, "height": 30, "width": 30, "color" : "blue" },
{ "rx": 160, "ry": 160, "height": 30, "width": 30, "color" : "red" }];
var svgContainer = d3.select("body").append("svg")
.attr("width",200)
.attr("height",200);
var circleGroup = svgContainer.append("g")
.attr("transform", "translate(80,0)")
var circles = circleGroup.selectAll("circle")
.data(circleData)
.enter()
.append("circle");
var circleAttributes = circles
.attr("cx", function (d) { return d.cx; })
.attr("cy", function (d) { return d.cy; })
.attr("r", function (d) { return d.radius; })
.style("fill", function (d) { return d.color; });
var rectangles = svgContainer.selectAll("rect")
.data(rectangleData)
.enter()
.append("rect");
var rectangleAttributes = rectangles
.attr("x", function (d) { return d.rx; })
.attr("y", function (d) { return d.ry; })
.attr("height", function (d) { return d.height; })
.attr("width", function (d) { return d.width; })
.style("fill", function(d) { return d.color; });
Adding text
//Circle Data Set
var circleData = [
{ "cx": 20, "cy": 20, "radius": 20, "color" : "green" },
{ "cx": 70, "cy": 70, "radius": 20, "color" : "purple" }];
//Create the SVG Viewport
var svgContainer = d3.select("#svgContainer")
.attr("width",200)
.attr("height",200);
//Add the SVG Text Element to the svgContainer
var text = svgContainer.selectAll("text")
.data(circleData)
.enter()
.append("text");
var circles = svgContainer.selectAll("circle")
.data(circleData)
.enter()
.append("circle")
.attr("cx", function(d) {return d.cx})
.attr("cy", function(d) {return d.cy})
.attr("r", function(d) {return d.radius})
.attr("fill", function(d) {return d.color})
//Add SVG Text Element Attributes
var textLabels = text
.attr("x", function(d) { return d.cx; })
.attr("y", function(d) { return d.cy; })
.text( function (d) { return "( " + d.cx + ", " + d.cy +" )"; })
.attr("font-family", "sans-serif")
.attr("font-size", "20px")
.attr("fill", "red");
Thinking in data joins: update, enter, exit
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(32," + (height / 2) + ")");
function update(data) {
// DATA JOIN
// Join new data with old elements, if any.
var text = svg.selectAll("text")
.data(data);
// UPDATE
// Update old elements as needed.
// Initially this part is empty
text.attr("class", "update").attr("fill", "blue");
// ENTER
// Create new elements as needed.
text.enter().append("text")
.attr("class", "enter")
.attr("fill", "green")
.attr("x", function(d, i) { return i * 32; })
.attr("dy", ".35em");
// ENTER + UPDATE
// Appending to the enter selection expands the update selection to include
// entering elements; so, operations on the update selection after appending to
// the enter selection will apply to both entering and updating nodes.
text.text(function(d) { return d; });
// EXIT
// Remove old elements as needed.
text.exit().remove();
}
In the javascript console:
update([1, 2])
update([1, 2, 3, 4])
update([1, 2, 3, 4, 5, 6])
Now with a touch of animation (transition in coordinates):
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(32," + (height / 2) + ")");
function update(data) {
var text = svg.selectAll("text")
.data(data);
text.attr("class", "update").attr("fill", "blue");
text.enter().append("text")
.attr("class", "enter")
.attr("fill", "green")
.attr("x", function(d, i) { return i * 32; })
.attr("y", -50)
.transition()
.attr("y", 0)
.attr("dy", ".35em");
text.text(function(d) { return d; });
text.exit()
.attr("y", 0)
.transition()
.attr("y", -50)
.remove();
}
Nested Selection
var tableBody = d3.select("body").append("table").append("tbody");
//var cells = tableBody.selectAll("tr").selectAll("td")
// .style("color", function(d, i, j) {return i === j ? "green" : "lightblue"})
var matrix = [
[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
];
var cells = tableBody.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
.selectAll("td")
.data(function(d, i) {return d})
.enter()
.append("td")
.html(function(d) {return "<b>" + d + "</b>";});