Skip to content

Instantly share code, notes, and snippets.

@alansmithy
Last active May 13, 2017 02:26
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 alansmithy/927c0614d1bf1ccd4a5a8cd2df8635ac to your computer and use it in GitHub Desktop.
Save alansmithy/927c0614d1bf1ccd4a5a8cd2df8635ac to your computer and use it in GitHub Desktop.
animated radar plot
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
#radar{fill:#154577;fill-opacity:0.5;stroke:#154577;stroke-width:3px;stroke-linecap:round;stroke-linejoin:round}
.axis text{fill:#dedede}
.axis line,path{stroke:#dedede}
text{font-family:Avenir;font-size:13.6px}
circle,.grid{fill:none;stroke-width:1px;stroke:#dedede}
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
// Feel free to change or delete any of the code you see in this editor!
var w=400;
var h=400;
var radius=150;
var radarData = [
{name:"North Korea",before:8,after:60},
{name:"Japan",before:85,after:40},
{name:"U.S.",before:90,after:65},
{name:"China",before:30,after:65}
];
var aniSpeed=1000;
var aniIndex=0;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
//create circle
svg.append("circle")
.attr("cx",w/2)
.attr("cy",w/2)
.attr("r",radius)
/*
//create central grid - temporary layout
//horizontal line
svg.append("line")
.attr("class","grid")
.attr("x1",(w/2)-radius)
.attr("x2",(w/2)+radius)
.attr("y1",(h/2))
.attr("y2",(h/2))
//vertical line
svg.append("line")
.attr("class","grid")
.attr("x1",(w/2))
.attr("x2",(w/2))
.attr("y1",(h/2)-radius)
.attr("y2",(h/2)+radius)
*/
//label the quadrants
svg.append("g").attr("id","labels")
.selectAll("text")
.data(radarData)
.enter()
.append("text")
.attr("x",function(d,i){
switch(i) {
case 0:
return w/2;
break;
case 1:
return (w/2)+radius+8;
break;
case 2:
return w/2;
break;
case 3:
return (w/2)-radius-8;
break;
}
})
.attr("y",function(d,i){
switch(i) {
case 0:
return (h/2)-radius-8;
break;
case 1:
return h/2+4;
break;
case 2:
return (h/2)+radius+18;
break;
case 3:
return (h/2)+4;
break;
}
})
.attr("text-anchor",function(d,i){
switch(i) {
case 0:
return "middle";
break;
case 1:
return "start";
break;
case 2:
return "middle";
break;
case 3:
return "end";
break;
}
})
.text(function(d){
return d.name;
})
//set up scales on each quadrant axis
var scaleN=d3.scaleLinear()
.domain([0,100])
.range([h/2,(h/2)-radius]);
var scaleS=d3.scaleLinear()
.domain([0,100])
.range([h/2,(h/2)+radius]);
var scaleE=d3.scaleLinear()
.domain([0,100])
.range([w/2,(w/2)+radius]);
var scaleW=d3.scaleLinear()
.domain([0,100])
.range([w/2,(w/2)-radius]);
//define some axes
var axisN = d3.axisRight()
.scale(scaleN)
//ticks(5)
.tickValues([50,100])
svg.append("g")
.attr("transform","translate("+w/2+",0)")
.attr("class","axis")
.call(axisN)
var axisS = d3.axisLeft()
.scale(scaleS)
.tickValues([50,100])
svg.append("g")
.attr("transform","translate("+w/2+",0)")
.attr("class","axis")
.call(axisS)
var axisE = d3.axisBottom()
.scale(scaleE)
.tickValues([50,100])
svg.append("g")
.attr("transform","translate(0,"+h/2+")")
.attr("class","axis")
.call(axisE)
var axisW = d3.axisTop()
.scale(scaleW)
.tickValues([50,100])
svg.append("g")
.attr("transform","translate(0,"+h/2+")")
.attr("class","axis")
.call(axisW)
//practice putting a circle anywhere on an axis
/*
svg.append("circle")
.attr("cx",w/2)
.attr("cy",scaleN(63))
.attr("r",5)
*/
//draw intial path
var plot = svg.append("path")
.attr("id","radar")
.attr("d",function(){
var x1=scaleE(0);
var y1=scaleN(radarData[0].before);
var x2=scaleE(radarData[1].before);
var y2=scaleN(0)
var x3=scaleE(0);
var y3=scaleS(radarData[2].before);
var x4=scaleW(radarData[3].before);
var y4=scaleN(0)
return "M"+x1+","+y1+" L"+x2+","+y2+" "+x3+","+y3+" "+x4+","+y4+"z"
})
setInterval(function(){
if (aniIndex==0){
aniIndex=1;
} else {
aniIndex=0;
}
plot.transition().duration(aniSpeed).ease(d3.easeElastic).attr("d",function(d){
var y1,x2,y3,x4;
if (aniIndex==1){
y1=scaleN(radarData[0].after);
x2=scaleE(radarData[1].after);
y3=scaleS(radarData[2].after);
x4=scaleW(radarData[3].after);
} else {
y1=scaleN(radarData[0].before);
x2=scaleE(radarData[1].before);
y3=scaleS(radarData[2].before);
x4=scaleW(radarData[3].before);
}
var x1=scaleE(0);
var y2=scaleN(0)
var x3=scaleE(0);
var y4=scaleN(0)
return "M"+x1+","+y1+" L"+x2+","+y2+" "+x3+","+y3+" "+x4+","+y4+"z"
})
}, aniSpeed);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment