forked from AntonOrlov's block: Radial Bar Chart built with D3
forked from eamonm95's block: Radial Bar Chart built with D3
forked from Heywhoyou22's block: Radial Bar Chart built with D3
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title>Oyster conservation data by decade</title>
<style>
body {
font: 12px sans-serif;
}
svg {
margin: 0px auto;
display: block;
}
path.arc {
opacity: .9;
transition: opacity 0.5s;
}
path.arc:hover {
opacity: 0.6;
}
.axis line, .axis circle {
stroke: #cccccc;
stroke-width: 1px
}
.axis circle {
fill: none;
}
.r.axis text {
text-anchor: end
}
.tooltip {
position: absolute;
display: none;
background: rgba(0, 0, 0, .7);
border-radius: 3px;
box-shadow: -3px 3px 15px #939393;
color: white;
padding: 6px;
}
#radial button {
background-color:#e0e0e0;
text-align:center;
border-radius: 20px;
border-color: #d1d1d1;
font-family:"Times New Roman", Times, serif;
font-size: 18px;
font-weight: 500;
position:fixed;
bottom:300px;
left:442px;
}
#radial button:hover {
background-color: #c0c0c0;
border-color: #e1e1e1;
}
#radial text{
font-family: "times new roman";
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
</head>
<body>
<div id="radial">
<p><br><div align="middle"> Dollars Adjusted to 2016 inflation </div></p>
<div id="radialSvg">
</div>
</div>
<script type="text/javascript" src="js/d3-tip.js"></script>
<script type="text/javascript">
//JS Object used to switch between data using a simple button
function dataSwitcherConstructor(datatype) {
this.currentData = datatype;
dataswitch(this.currentData);
}
//load data
var datatype = "revenue";
var dataSwitcher = new dataSwitcherConstructor(datatype);
//Arc colors
const color1 = d3.interpolate("#1d5d23","#197522");//d3.scaleOrdinal(d3.schemeGreens[7]);
const color2 = d3.interpolate("#2c538b","#3566aa");//d3.scaleOrdinal(d3.schemeBlues[7]);
let tooltip = d3.select('body').append('div')
.attr('class', 'tooltip');
//Chart spacing and tick settings
const PI = Math.PI,
arcMinRadius = 10,
arcPadding = 0,
labelPadding = -5,
numTicks = 15;
function dataswitch(datatype){
const width = 960,
height = 500,
chartRadius = height / 2 - 40;
d3.select("svg").remove();
let svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2.18 + ')');
svg.append ("rect")
.attr("width",100)
.attr("height",50)
.attr("x",-50)
.attr("y",230)
svg.append ("text")
.attr("width",100)
.attr("height",50)
.attr("x",-30)
.attr("y",257)
.text("hello")
.attr("font-size", 20)
.attr("font-family", "monospace")
.attr("fill","white")
d3.select("text").on("click", function(){
if (datatype=="revenue")
datatype = "landings";
else
datatype = "revenue";
dataSwitcher = new dataSwitcherConstructor(datatype);
});
//Datajoin
d3.csv('Oyster.csv', (data) => {console.log(data)
if(datatype == "revenue"){
let scale = d3.scaleLinear()
.domain([0, d3.max(data, d => +d.AdjustedRevenue) * 1.1])
.range([0, 2 * PI]);
//Building chart
let ticks = scale.ticks(numTicks).slice(0, -1);
let keys = data.map((d, i) => d.Decade);
//Arc Data
const numArcs = keys.length;
const arcWidth = (chartRadius - arcMinRadius - numArcs * arcPadding) / numArcs;
let arc = d3.arc()
.innerRadius((d, i) => getInnerRadius(i))
.outerRadius((d, i) => getOuterRadius(i))
.startAngle(0)
.endAngle((d, i) => scale(d))
let radialAxis = svg.append('g')
.attr('class', 'r axis')
.selectAll('g')
.data(data)
.enter().append('g');
radialAxis.append('circle')
.attr('r', (d, i) => getOuterRadius(i) + arcPadding);
radialAxis.append('text')
.attr('x', labelPadding)
.attr('y', (d, i) => -getOuterRadius(i) + arcPadding)
.text(d => d.Decade);
let axialAxis = svg.append('g')
.attr('class', 'a axis')
.selectAll('g')
.data(ticks)
.enter().append('g')
.attr('transform', d => 'rotate(' + (rad2deg(scale(d)) - 90) + ')');
axialAxis.append('line')
.attr('x2', chartRadius);
axialAxis.append('text')
.attr('x', chartRadius + 10)
.style('text-anchor', d => (scale(d) >= PI && scale(d) < 2 * PI ? 'end' : null))
.attr('transform', d => 'rotate(' + (90 - rad2deg(scale(d))) + ',' + (chartRadius + 10) + ',0)')
.text(d =>"$"+ d.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
let arcs = svg.append('g')
.attr('class', 'data')
.selectAll('path')
.data(data)
.enter().append('path')
.attr('class', 'arc')
.style('fill', (d, i) => color1(i))
arcs.transition()
.delay((d, i) => i * 200)
.duration(1000)
.attrTween('d', arcTween);
arcs.on('mousemove', showTooltip)
arcs.on('mouseout', hideTooltip)
//Text updates with data change
svg.append("text")
.text("Data Shown:")
.attr("y",-200)
.attr("x",-475)
.attr("font-size", 20)
.attr("font-family", "monospace")
svg.append("text")
.text("Revenue")
.attr("y",-200)
.attr("x",-350)
.attr("font-size", 20)
.attr("font-family", "monospace")
//Tooltip,archover data
function arcTween(d, i) {
let interpolate = d3.interpolate(0, +d.AdjustedRevenue);
return t => arc(interpolate(t), i);
}
function showTooltip(d) {
tooltip.style('left', (d3.event.pageX + 10) + 'px')
.style('top', (d3.event.pageY - 25) + 'px')
.style('display', 'inline-block')
.html("$"+d.AdjustedRevenue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + "<br>" + " Decline since 1950: "+ Math.round((100-((d.AdjustedRevenue/data[0].AdjustedRevenue)*100)))+"%")
}
function hideTooltip() {
tooltip.style('display', 'none');
}
function rad2deg(angle) {
return angle * 180 / PI;
}
function getInnerRadius(index) {
return arcMinRadius + (numArcs - (index + 1)) * (arcWidth + arcPadding);
}
function getOuterRadius(index) {
return getInnerRadius(index) + arcWidth;
}
}
//Landings data
else if(datatype == "landings"){
let scale = d3.scaleLinear()
.domain([0, d3.max(data, d => +d.MetricTonnage) * 1.1])
.range([0, 2 * PI]);
//Text updates with data change
svg.append("text")
.text("Data Shown:")
.attr("y",-200)
.attr("x",-475)
.attr("font-size", 20)
.attr("font-family", "monospace")
svg.append("text")
.text("Oyster Landings")
.attr("y",-200)
.attr("x",-350)
.attr("font-size", 20)
.attr("font-family", "monospace")
//Arc data
let ticks = scale.ticks(numTicks).slice(0, -1);
let keys = data.map((d, i) => d.Decade);
const numArcs = keys.length;
const arcWidth = (chartRadius - arcMinRadius - numArcs * arcPadding) / numArcs;
let arc = d3.arc()
.innerRadius((d, i) => getInnerRadius(i))
.outerRadius((d, i) => getOuterRadius(i))
.startAngle(0)
.endAngle((d, i) => scale(d))
let radialAxis = svg.append('g')
.attr('class', 'r axis')
.selectAll('g')
.data(data)
.enter().append('g');
radialAxis.append('circle')
.attr('r', (d, i) => getOuterRadius(i) + arcPadding);
radialAxis.append('text')
.attr('x', labelPadding)
.attr('y', (d, i) => -getOuterRadius(i) + arcPadding)
.text(d => d.Decade);
let axialAxis = svg.append('g')
.attr('class', 'a axis')
.selectAll('g')
.data(ticks)
.enter().append('g')
.attr('transform', d => 'rotate(' + (rad2deg(scale(d)) - 90) + ')');
axialAxis.append('line')
.attr('x2', chartRadius);
axialAxis.append('text')
.attr('x', chartRadius + 10)
.style('text-anchor', d => (scale(d) >= PI && scale(d) < 2 * PI ? 'end' : null))
.attr('transform', d => 'rotate(' + (90 - rad2deg(scale(d))) + ',' + (chartRadius + 10) + ',0)')
.text(d => d.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
let arcs = svg.append('g')
.attr('class', 'data')
.selectAll('path')
.data(data)
.enter().append('path')
.attr('class', 'arc')
.style('fill', (d, i) => color2(i))
arcs.transition()
.delay((d, i) => i * 200)
.duration(1000)
.attrTween('d', arcTween);
arcs.on('mousemove', showTooltip)
arcs.on('mouseout', hideTooltip)
//Tooltip,archover data
function arcTween(d, i) {
let interpolate = d3.interpolate(0, +d.MetricTonnage);
return t => arc(interpolate(t), i);
}
function showTooltip(d) {
tooltip.style('left', (d3.event.pageX + 10) + 'px')
.style('top', (d3.event.pageY - 25) + 'px')
.style('display', 'inline-block')
.html(d.MetricTonnage.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " Metric Tons"+ "<br>"+ " Decline since 1950: " + Math.round((100-((d.MetricTonnage/data[0].MetricTonnage)*100)))+"%")
}
function hideTooltip() {
tooltip.style('display', 'none');
}
function rad2deg(angle) {
return angle * 180 / PI;
}
function getInnerRadius(index) {
return arcMinRadius + (numArcs - (index + 1)) * (arcWidth + arcPadding);
}
function getOuterRadius(index) {
return getInnerRadius(index) + arcWidth;
}}})}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-color.v1.min.js
https://d3js.org/d3-interpolate.v1.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js