Skip to content

Instantly share code, notes, and snippets.

@cmdoptesc
Last active March 4, 2018 01:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmdoptesc/6226150 to your computer and use it in GitHub Desktop.
Save cmdoptesc/6226150 to your computer and use it in GitHub Desktop.
JavaScript D3: Drawing Concentric Arcs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="Basic beginner's source code to drawing arcs in D3 using dynamically-generated data.">
<title>JavaScript D3: Drawing Concentric Arcs (Part I)</title>
<style type='text/css'>
.click-circle{
cursor: pointer;
}
</style>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.v3.min.js"></script>
</head>
<body>
<div class="chart"></div>
<script type="text/javascript">
var width = window.innerWidth,
height = window.innerHeight;
// append svg to the DIV
d3.select(".chart").append("svg:svg")
.attr("width", width)
.attr("height", height);
var render = function(dataset) {
vis = d3.select("svg"); // select the svg
// set constants
var PI = Math.PI;
var arcMin = 75; // inner radius of the first arc
var arcWidth = 15; // width
var arcPad = 1; // padding between arcs
// arc accessor
// d and i are automatically passed to accessor functions,
// with d being the data and i the index of the data
var drawArc = d3.svg.arc()
.innerRadius(function(d, i) {
return arcMin + i*(arcWidth) + arcPad;
})
.outerRadius(function(d, i) {
return arcMin + (i+1)*(arcWidth);
})
.startAngle(0 * (PI/180))
.endAngle(function(d, i) {
return d*6 * (PI/180);
});
// bind the data
var arcs = vis.selectAll("path.arc-path").data(dataset);
// *** update existing arcs -- redraw them ***
arcs.attr("d", drawArc)
.attr("fill", function(d){
// we need to redefine the fills as well since we have new data,
// otherwise the colors would no longer be relative to the data
// values (and arc length). if your fills weren't relative to
// the data, this would not be necessary
var grn = Math.floor((1 - d/60)*255);
return "rgb(0, "+ grn +", 0)";
});
// draw arcs for new data
arcs.enter().append("svg:path")
.attr("class", "arc-path") // assigns a class for easier selecting
.attr("transform", "translate(400,200)") // sets position--easier than setting x's and y's
.attr("fill", function(d){
// fill is an rgb value with the green value determined by the data
// smaller numbers result in a higher green value (1 - d/60)
// you should also look into using d3 scales to create gradients
var grn = Math.floor((1 - d/60)*255);
return "rgb(0, "+ grn +", 0)";
})
.attr("d", drawArc); // draw the arc
};
// you can safely ignore the code below.
// the code is used to create a click area for people to regenerate
// arcs by generating a new data set and calling render on that set
// for generating a random array of times
var generateTimes = function(quantity) {
var i, times = [];
for(i=0; i<quantity; i++) {
times.push(Math.round(Math.random()*60));
}
return times;
};
// drawing the click area
var initialize = function() {
var arcMin = 75; // this should match the arcMin in render()
var times = generateTimes(6);
render(times);
// making the click circle
if(!d3.selectAll("circle.click-circle")[0].length) { // if there is no click area..
d3.select("svg").append("circle")
.attr("class", 'click-circle')
.attr("transform", "translate(400,200)")
.attr("r", arcMin*0.85)
.attr("fill", "rgba(201, 201, 201, 0.5)")
.on("click", function(d) {
times = generateTimes(6);
render(times);
});
}
}
initialize();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment