I am using a donut chart in order to present data from a static JSON query. I now want to make it responsive. I have made other D3 graphs responsive but it is different for this one.
The idea was first to calculate the distance between two corners of the screen (hypotenuse) in order to recalculate the radius of my shape. That could be useful for later. Snippet for this calculation is shown here:
console.log('width')
console.log(window.innerWidth);
console.log('height')
console.log(window.innerHeight);
console.log('final');
console.log(Math.sqrt(Math.pow(window.innerWidth,2) + Math.pow(window.innerHeight,2)));
$("#one").html(Math.sqrt(Math.pow(window.innerWidth,2) + Math.pow(window.innerHeight,2)));
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<div id="one"></div>
My main snippet is here and it is responsive but the box with the values (tooltip) is shown underneath the donut.
var margin = {top: 20, right: 20, bottom: 50, left: 100},
width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
height = parseInt(d3.select("#chart").style("width")) - margin.top - margin.bottom,
r = 180,
inner = 180/2,
color= d3.scale.ordinal()
.range(["#124", "#214183", "#3061c2", "#4876d1", "#87a5e1", "#c5d4f1"]);
data = [{"label":"ONE", "value":194},
{"label":"TWO", "value":567},
{"label":"THREE", "value":1314},
{"label":"FOUR", "value":793},
{"label":"FIVE", "value":1929},
{"label":"SIX", "value":1383}];
var total = d3.sum(data, function(d) {
return d3.sum(d3.values(d));
});
var vis = d3.select('#chart').append("svg:svg").data([data])
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox',(-width / 2 ) + ' ' + (-height/2) + ' '+width +' '+height)
.attr('preserveAspectRatio','xMinYMin')
var textTop = vis.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.attr("class", "textTop")
.text( "TOTAL" )
.attr("y", -10),
textBottom = vis.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.attr("class", "textBottom")
.text(total.toFixed(2) + "m")
.attr("y", 10);
var arc = d3.svg.arc()
.innerRadius(inner)
.outerRadius(r);
var arcOver = d3.svg.arc()
.innerRadius(inner + 5)
.outerRadius(r + 5);
var pie = d3.layout.pie()
.value(function(d) { return d.value; });
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("svg:g")
.attr("class", "slice")
.on("mouseover", function(d) {
d3.select(this).select("path").transition()
.duration(200)
.attr("d", arcOver)
textTop.text(d3.select(this).datum().data.label)
.attr("y", -10);
textBottom.text(d3.select(this).datum().data.value.toFixed(2))
.attr("y", 10);
})
.on("mouseout", function(d) {
d3.select(this).select("path").transition()
.duration(100)
.attr("d", arc);
textTop.text( "TOTAL" )
.attr("y", -10);
textBottom.text(total.toFixed(2) + "m");
});
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); } )
.attr("d", arc);
var legend = d3.select("#chart").append("svg")
.attr("class", "legend")
.attr("width", r)
.attr("height", r * 2)
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) { return color(i); });
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text(function(d) { return d.label; });
*{
font-family: 'Roboto', sans-serif;
text-transform:capitalize;
margin: 0 auto;
text-align:left;
}
body {
font-family: "Roboto"!important;
width: 100%;
height: 400px;
position: relative;
}
.slice path {
stroke: #fff;
stroke-width: 1px;
}
.textTop {
font-size: 12pt;
fill: #bbb;
}
.textBottom {
fill: #444;
font-weight: bold;
font-size: 18pt;
}
.top {
border: 1px solid #bbb;
color: #777;
padding: 5px;
text-decoration: none;
}
.top:hover {
border: 1px solid #555;
color: #333;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="chart"></div>
<svg id="chart2"></svg>
How can I include the tooltip (legend - not sure about the exact terminology) on the right side of the donut?