Data Visualization D3.js : Basic D3 Drawings - 2016
Throughout this tutorial, the d3 is defined in the header like this:
<!-- D3.js --> <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
Probably the simplest drawing:
Here is the code:
<div id="bogo1"> <script type="text/javascript"> var width = 200; var height = 200; var bogoSVG = d3.select("#bogo1").append("svg") .attr("width", width) .attr("height", height); var r = 80; bogoSVG.append("circle") .attr("cx", 100) .attr("cy", 100) .attr("r", r) .attr("stroke", "blue") .attr("fill", "none"); </script> </div>
Let's put a rectangle around the circle:
The code looks like this:
<div id="bogo2"> <script type="text/javascript"> var width = 200; var height = 200; var bogoSVG = d3.select("#bogo2").append("svg") .attr("width", width) .attr("height", height); var r = 80; bogoSVG.append("circle") .attr("cx", 100) .attr("cy", 100) .attr("r", r) .attr("stroke", "blue") .attr("stroke-width", 5) .attr("fill", "#800080") // purple .attr("fill-opacity", .2); bogoSVG.append("rect") .attr("x", 0) .attr("y", 0) .attr("width", 200) .attr("height", 200) .attr("stroke", "green") .attr("fill", "none"); </script> </div>
First, we want to draw a circle using arc and path from -45 to +90:
The code:
<div id="bogoSemiCircle"> <script type="text/javascript"> var bogoSVG = d3.select("#bogoSemiCircle").append("svg") .attr("width", 100) .attr("height", 100); var arc = d3.svg.arc() .innerRadius(48) .outerRadius(50) .startAngle(-Math.PI/4) .endAngle(Math.PI/2) bogoSVG.append("path") .attr("d", arc) .attr("transform", "translate(50,50)") </script> </div>
Now, we want to draw a semi-circle using line segments:
The .attr("d", line) is where the magic happens. This is where we send the data to the accessor function which returns the SVG Path Commands.
Here is the code:
<div id="bogoSemiCircle2"> <script type="text/javascript"> var bogoSVG = d3.select("#bogoSemiCircle2").append("svg") .attr("width", 300) .attr("height", 200); var points = 10, radius = 100; var angle = d3.scale.linear() .domain([0, points-1]) .range([-Math.PI/2, Math.PI/2]); var line = d3.svg.line.radial() .radius(radius) .angle(function(d, i) { return angle(i); }); bogoSVG.append("path") .datum(d3.range(points)) .attr("class", "line") .attr("d", line) .attr("fill", "none") .attr("stroke", "blue") .attr("stroke-width", 2) .attr("transform", "translate(100,125)"); </script> </div>
If we want to connect between points not using "linear", we can use "basis" interpolation:
var line = d3.svg.line.radial() .interpolate("basis") .radius(radius) .angle(function(d, i) { return angle(i); });
The result looks like this:
We can add the points along the circle:
The code for the picture above looks like the following:
<div id="bogoSemiCircleWithPoints"> <script type="text/javascript"> var svgContainer = d3.select("#bogoSemiCircleWithPoints").append("svg") .attr("width", 300) .attr("height", 200); var npoints = 10, radius = 100; var angle = d3.scale.linear() .domain([0, npoints-1]) .range([-Math.PI/2, Math.PI/2]); var line = d3.svg.line.radial() .radius(radius) .angle(function(d, i) { return angle(i); }); var circle = svgContainer.selectAll("circle") .data(d3.range(npoints)) .enter() .append("circle") .attr("cy", function(d, i) { return -Math.sin(i*Math.PI/(npoints-1))*radius; }) .attr("cx", function(d, i) { return Math.cos(i*Math.PI/(npoints-1))*radius; }) .attr("r", 5) .style("stroke-width", 2) .attr("transform", "translate(150,125)"); svgContainer.append("path") .datum(d3.range(npoints)) .attr("d", line) .attr("fill", "none") .attr("stroke", "blue") .attr("stroke-width", 2) .attr("transform", "translate(150,125)"); </script> </div>
Note that I dropped interpolate("basis") and used line segments to construct the circle because it does pool down the arc as shown the picture below:
At this point, I don't know how to deal with it.
The d3.selectAll method takes a selector string, such as "circle", and returns a selection representing all elements that match the selector:
var circle = d3.selectAll("circle");
With a selection, we can make various changes to selected elements. For example, we might change the stroke-width using selection.style and the radius using selection.attr:
circle.style("stroke-width", 5); circle.attr("r", 30);
The above code sets styles and attributes for all selected elements to the same values.
Here is is the code:
<div id="bogoSelect"> <script type="text/javascript"> var svgContainer = d3.select("#bogoSelect").append("svg") .attr("width", 500) .attr("height", 200); var circle = svgContainer.selectAll("circle") .data([49, 144, 225]) .enter() .append("circle") .attr("cy", 60) .attr("cx", function(d, i) { return i * 150; }) .attr("r", function(d) { return Math.sqrt(d); }) .style("stroke-width", 5) .attr("transform", "translate(100,0)"); </script> </div>
Let's append a SVG Group Element to the already defined SVG Container.
<div id="bogoGroup"> <script type="text/javascript"> var svgContainer = d3.select("#bogoGroup").append("svg") .attr("width", 300) .attr("height", 200); var cGroup = svgContainer.append("g"); </script> </div>
We see how it works from the picture below:
However, we have nothing in <g></g>.
Let's put circles in the group:
The code looks like this:
<div id="bogoGroup"> <script type="text/javascript"> var svgContainer = d3.select("#bogoGroup").append("svg") .attr("width", 300) .attr("height", 200); var cGroup = svgContainer.append("g"); var circleData = [ { "cx": 100, "cy": 20, "radius": 20, "color" : "green" }, { "cx": 100, "cy": 100, "radius": 50, "color" : "blue" } ]; var circles = cGroup.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; }); </script> </div>
Let's add a transformation to the group:
We simply added a transformation to the cGroup as in the following line:
var cGroup = svgContainer.append("g").attr("transform", "translate(100,0)");
The path data is specified in the same way as when using raw SVG:
The code looks like this:
<div id="svgPath"> <script type="text/javascript"> var svgContainer = d3.select("#svgPath").append("svg") .attr("width", 600) .attr("height", 600); svgContainer.append("path") .attr("d","M -200,0 A200,200 0 0,0 200,0 L -200,0") .attr("transform", "translate(250,250) scale(1,-1)") .style("stroke-width", 3) .style("stroke", "#0077bb") .style("fill", "#ffffdd"); </script> </div>
Note that we reflected the picture against x-axis via scale(1,-1).
The picture below is the same one except the path : we define the path by specifying path point rather than raw-svg path:
The code for the above picture is here:
<div id="d3Path"> <script type="text/javascript"> var svgContainer = d3.select("#d3Path").append("svg") .attr("width", 600) .attr("height", 300); var arc = d3.svg.arc() .innerRadius(200) .outerRadius(200) .startAngle(Math.PI/2) .endAngle(-Math.PI/2); // Specify the path points pathinfo = [{x:-200, y:0}, {x:200, y:0}]; // Specify the function for generating path data var d3line2 = d3.svg.line() .x(function(d){return d.x;}) .y(function(d){return d.y;}) .interpolate("linear"); svgContainer .append("path") .attr("d",arc) .attr("transform", "translate(250,250)") .style("stroke-width", 3) .style("stroke", "#0077bb") .style("fill", "#ffffdd"); svgContainer.append("path") .attr("d", d3line2(pathinfo)) .attr("transform", "translate(250,250)") .style("stroke-width", 3) .style("stroke", "#0077bb") .style("fill", "#ffffdd"); </script> </div>
svg:arc reference:
List of references:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization