In the example we're looking at historical weather data for San Francisco provided by intellicast.com.
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<link href='https://fonts.googleapis.com/css?family=Lato:300,900' rel='stylesheet' type='text/css'>
<style>
body{
background-color: whitesmoke;
}
svg {
background-color: white;
font-family: 'Lato';
}
.axis {
stroke: white;
opacity: .8;
}
text.title {
font-size: 26px;
}
circle.axis {
stroke: white;
stroke-width: 1px;
fill: none;
}
circle.axis.record {
stroke: #bae0d6;
stroke-width: 1.2px;
opacity: 1;
}
line.record {
stroke: #bae0d6;
stroke-width: 3px;
}
line.avg {
stroke: #71C5AF;
stroke-width: 3px;
}
.avg {
stroke: #71C5AF;
fill: #71C5AF;
}
.record {
stroke: #bae0d6;
fill: #bae0d6;
}
</style>
</head>
<body>
<svg width=960 height=500></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.3.0/d3-legend.min.js"></script>
<script>
var width = 960,
margin = 20,
height = 500,
svg = d3.select('svg'),
origin = svg.append('g')
.attr('transform', 'translate(' + width/2 + ',' + height/2 + ')'),
rScale = d3.scale.linear()
.domain([10, 110])
.range([0, height/2 - margin]),
yScale = (day, temp) => -Math.cos(angleScale(day)*Math.PI/180)*rScale(parseInt(temp)),
xScale = (day, temp) => Math.sin(angleScale(day)*Math.PI/180)*rScale(parseInt(temp)),
angleScale = d3.scale.linear()
.range([0, 360]);
d3.json('temp.json', function(err, json){
angleScale.domain([0, json.length - 1]);
var min = d3.min(json, d => parseInt(d.recLow)),
max = d3.max(json, d => parseInt(d.recHigh));
var months = [];
//find index for months based on data
json.forEach((d, i) => {
var month = d.date.split('-')[1],
prevDaysMonth = ( i === 0 ) ? undefined : json[i - 1].date.split('-')[1];
if (i === 0 || month != prevDaysMonth){
months.push({
month: month,
index: i
});
}
})
//circle axis
origin.selectAll('circle.axis-green')
.data([40, 60, 80, 100])
.enter().append('circle')
.attr('r', (d) => rScale(d))
.attr('class', 'axis record')
//record low and high
origin.selectAll('line.record')
.data(json)
.enter().append('line')
.attr('x1', (d, i) => xScale(i, d.recLow))
.attr('x2', (d, i) => xScale(i, d.recHigh))
.attr('y1', (d, i) => yScale(i, d.recLow))
.attr('y2', (d, i) => yScale(i, d.recHigh))
.attr('class', 'record');
//avg low and high
origin.selectAll('line.avg')
.data(json)
.enter().append('line')
.attr('x1', (d, i) => xScale(i, d.avgLow))
.attr('x2', (d, i) => xScale(i, d.avgHigh))
.attr('y1', (d, i) => yScale(i, d.avgLow))
.attr('y2', (d, i) => yScale(i, d.avgHigh))
.attr('class', 'avg');
origin.selectAll('circle.axis-white')
.data([40, 60, 80, 100])
.enter().append('circle')
.attr('r', (d) => rScale(d))
.attr('class', 'axis')
//axis lines
origin.selectAll('line.axis')
.data(months)
.enter().append('line')
.attr('x2', d => {
return xScale(d.index, 120)})
.attr('y2', d => -yScale(d.index, 120))
.attr('class', 'axis');
//center for reference
origin.append('circle')
.attr('r', 3)
.attr('class', 'avg')
//title
svg.append('text')
.attr('x', 30)
.attr('y', 60)
.text('San Francisco')
.attr('class', 'title')
//subtitle
svg.append('text')
.attr('x', 30)
.attr('y', 100)
.text('Historical Weather Data')
//create legend
var legendScale = d3.scale.ordinal()
.domain(['Record', 'Average'])
.range(['record', 'avg'])
//d3-legend
var legend = d3.legend.color()
.shapePadding(5)
.useClass(true)
.scale(legendScale);
svg.append('g')
.attr('transform', 'translate(30,120)')
.call(legend);
});
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.3.0/d3-legend.min.js