Skip to content

Instantly share code, notes, and snippets.

@timchu90
Last active January 14, 2019 22:36
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 timchu90/0bd2cef2a91f60b4f32c2f7e537407f7 to your computer and use it in GitHub Desktop.
Save timchu90/0bd2cef2a91f60b4f32c2f7e537407f7 to your computer and use it in GitHub Desktop.
Raindrop Radial Chart

Raindrop Radial Chart

Hover to show only one year Click anywhere to reset chart

Experimental chart made as a DataVizRequest from this Reddit thread: https://www.reddit.com/r/DataVizRequests/comments/ac3x0q/request_can_someone_volunteer_their_time_to/

Dataset was from the user's grandfather who manually charted the rain levels in Earlville, Cairns, Australia from 1993 to today. Went with the theme and thought I would experiment by making a 3d radial line chart, hoping for it to look like a raindrop splash. The end result sort of has the effect I wanted, but gives no extra insight that a series of layered line charts wouldn't give. In the end, happy with my prototype and curious to see if it would work better with other sets of data in the future.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
#chart {
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
z-index: -2;
height: 100%;
}
body {
font-family: sans-serif;
}
.line {
stroke-width: 1px;
opacity: 0.5;
}
</style>
</head>
<body>
<div id="chart">
</div>
<script>
var chartDiv = document.getElementById("chart");
var width = chartDiv.clientWidth -10;
var height = chartDiv.clientHeight -20;
var index;
var xScale = d3.scaleLinear().range([0,width]).domain([0,1000])
var yScale = d3.scaleLinear().range([0,height]).domain([0,1000])
var x = d3.scaleLinear().range([0,width]).domain([-20,20])
var y = d3.scaleLinear().range([height,0]).domain([-20,20])
var scale = d3.scaleLinear().range([0,height]).domain([0,1000])
var relativeScale = d3.scaleLinear().range([0,50]).domain([0,1500])
var colorScale = d3.scaleLinear()
.range(['#c6dbef','#08306b'])
.domain([0,25])
var radius = 3
var line = d3.area()
.curve(d3.curveBasisClosed)
.x(function(d,i){
i = i+1
var correctedX;
if(i < 3) {
correctedX = i * radius/3
}
else if (i < 9){
correctedX = (6-i) * radius/3
}
else {
correctedX = (i-12) * radius/3
}
return x(correctedX)
})
.y1(function(d,i){
i = i+1
var multiplier, x
if(i > 3 && i < 10){
multiplier = -1
x = (6-i) * radius/3
}
else if (i > 9){
multiplier = 1
x = (i-12) * radius/3
}
else{
multiplier = 1
x = i * radius/3
}
return y(multiplier * (Math.sqrt(Math.pow(radius,2) - Math.pow(x,2)))-radius) - relativeScale(d);
})
.y0(function(d,i){
i = i+1
var multiplier, x
if(i > 3 && i < 10){
multiplier = -1
x = (6-i) * radius/3
}
else if (i > 9){
multiplier = 1
x = (i-12) * radius/3
}
else{
multiplier = 1
x = i * radius/3
}
return y(multiplier * (Math.sqrt(Math.pow(radius,2) - Math.pow(x,2)))-radius);
})
var zeroline = d3.area()
.curve(d3.curveBasisClosed)
.x(function(d,i){
i = i+1
var correctedX;
if(i < 3) {
correctedX = i * radius/3
}
else if (i < 9){
correctedX = (6-i) * radius/3
}
else {
correctedX = (i-12) * radius/3
}
return x(correctedX)
})
.y1(function(d,i){
i = i+1
if(i > 3 && i < 10){
var multiplier = -1
var x = (6-i) * radius/3
}
else if (i > 9){
var multiplier = 1
var x = (i-12) * radius/3
}
else{
var multiplier = 1
var x = i * radius/3
}
return y(multiplier * (Math.sqrt(Math.pow(radius,2) - Math.pow(x,2)))-radius);
})
.y0(function(d,i){
i = i+1
var multiplier, x
if(i > 3 && i < 10){
multiplier = -1
x = (6-i) * radius/3
}
else if (i > 9){
multiplier = 1
x = (i-12) * radius/3
}
else{
multiplier = 1
x = i * radius/3
}
return y(multiplier * (Math.sqrt(Math.pow(radius,2) - Math.pow(x,2)))-radius);
})
var svg = d3.select('body').append('svg')
.attr("width", width)
.attr("height", height)
var months = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']
for(month in months){
svg.append('text')
.text(months[month])
.attr('text-anchor','middle')
.attr('x',xScale(500))
.attr('y',yScale(470))
.attr('dx',xScale(Math.sin(((-30*month)+165) * (Math.PI / 180)) * 350))
.attr('dy',yScale(Math.cos(((-30*month)+165) * (Math.PI / 180)) * 400))
}
d3.tsv('rainData.txt', function(error,data){
if (error) throw error;
for (var i = 0; i < data.length; i++){
data[i].y = Object.values(data[i]).slice(1)
}
var rings = svg.selectAll('.rings')
.data(data)
.enter()
.append('g')
.attr('class','rings')
.attr('transform','translate(' + xScale(0) + ',' + yScale(-70)+ ')')
rings.append('path')
.attr('class','line')
.attr('d',function(d,i){radius = (i+1)*2/4; return zeroline(d.y)})
.attr('transform',function(d,i){ return'translate(' + xScale(0) + ',' + yScale(-12 * i)+ ')'})
.attr('stroke',function(d,i){return colorScale(i)})
.attr('fill',function(d,i){return colorScale(i)})
.on('mouseover',function(d,i){
d3.selectAll('.line')
.transition()
.duration(200)
.attr('d',function(d,i){radius = (i+1)*2/4; return zeroline(d.y)})
d3.select(this)
.transition()
.duration(200)
.attr('opacity',1)
.attr('d',function(d){radius = (i+1)*2/4; return line(d.y)})
})
.transition()
.duration(500)
.delay(function(d,i){return i*100})
.attr('d',function(d,i){radius = (i+1)*2/4; return line(d.y)})
svg.on('click',function(d,i){
d3.selectAll('.line')
.transition()
.duration(200)
.attr('d',function(d,i){radius = (i+1)*2/4; return line(d.y)})
})
})
</script>
</body>
</html>
Year January February March April May June July August September October November December
1994 620.3 722.5 97.3 252.4 57.3 64.0 49.2 64.6 26.2 42.7 24.6 67.9
1995 140.6 760.4 598.0 35.2 158.8 86.3 8.4 159.1 7.5 74.1 113.2 62.8
1996 454.3 434.1 640.9 328.2 96.2 95.6 56.7 7.4 4.5 244.7 13.9 252.8
1997 488.0 474.4 387.6 142.3 49.3 61.9 22.9 75.8 43.9 56.1 154.1 359.2
1998 536.8 518.5 150.2 156.9 151.8 38.8 24.4 126.9 117.1 76.3 173.5 199.5
1999 369.3 859.6 961.8 328.2 33.5 48.4 57.2 67.5 118.2 53.3 262.7 141.5
2000 126.0 1476.5 555.3 551.0 59.5 33.8 9.2 72.7 9.7 46.7 179.0 596.7
2001 349.3 939.0 215.8 174.1 3.5 90.4 5.2 15.5 37.5 72.7 71.1 67.5
2002 180.7 278.7 71.9 255.8 103.1 3.5 70.0 56.0 12.4 0.0 47.5 74.2
2003 285.7 171.0 225.9 247.9 113.6 60.2 45.6 31.1 1.5 17.1 28.8 265.6
2004 349.7 735.5 1333.5 326.5 57.0 49.5 50.2 3.0 27.5 33.0 94.5 346.9
2005 588.0 172.0 670.5 249.0 21.5 47.0 87.0 111.0 7.0 11.0 24.5 45.5
2006 502.0 399.0 867.0 765.0 85.0 179.5 84.5 15.5 87.0 106.0 23.0 94.0
2007 254.5 894.5 297.0 116.0 196.5 76.0 22.5 26.5 4.0 67.5 93.5 245.0
2008 520.0 599.0 773.0 14.0 78.0 27.0 79.0 3.5 68.0 91.5 199.0 209.5
2009 1093.0 631.0 130.0 265.5 106.0 11.5 10.5 6.0 10.5 48.0 332.0 950.0
2010 738.5 307.0 481.0 376.0 51.0 18.0 56.5 87.5 100.5 293.0 291.0 478.5
2011 522.0 1086.0 418.5 80.0 26.0 50.5 6.5 19.0 22.5 519.5 123.5 283.0
2012 379.5 333.0 920.0 179.0 200.5 17.5 65.0 25.5 26.5 58.0 49.5 52.0
2013 529.0 200.0 240.0 107.5 318.0 34.5 89.0 12.0 38.0 53.5 185.5 94.0
2014 440.5 472.5 452.5 437.0 179.0 159.0 19.0 36.5 4.0 20.5 23.5 18.5
2015 209.5 816.0 298.0 110.0 43.0 264.0 33.0 11.5 41.0 74.5 124.0 415.5
2016 152.0 149.0 232.0 196.0 198.0 101.5 110.5 46.0 84.5 18.5 32.5 88.5
2017 357.5 641.0 128.5 245.5 76.5 37.5 83.0 3.5 74.0 228.0 108.0 52.5
2018 596.5 534.5 1207.5 101.0 12.0 57.0 56.0 4.0 12.0 21.5 18.0 1015.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment