I have been successful in creating labels for both the X and Y axis. I have also been successful in adding a title to the graph. My problem is that if I modify the margins of the graph, the label positions get messed up.
Snippet of where I change the margins of the graph:
var margin = {top: 60, right: 60, bottom: 60, left:120}
Snippet of where I create the labels:
//Create Title
svg.append("text")
.attr("x", w / 2 )
.attr("y", 0)
.style("text-anchor", "middle")
.text("Title of Diagram");
//Create X axis label
svg.append("text")
.attr("x", w / 2 )
.attr("y", h + margin.bottom)
.style("text-anchor", "middle")
.text("State");
//Create Y axis label
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0-margin.left)
.attr("x",0 - (h / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Revenue");
JsFiddle:
http://jsfiddle.net/u63T9/
Here is another alternative, that I'm willing to live with:
I am basically leveraging the scales to find a base coordinate. I then add or take a little until I am happy with the location. This method actually keeps up with changes in the margins.
//Create title
svg.append("text")
.attr("x", w / 2 )
.attr("y", yScale(d3.max(input, function(d) { return d.CustomerCount; })) - 20 )
.style("text-anchor", "middle")
.text("Title of Graph");
//Create X axis label
svg.append("text")
.attr("x", w / 2 )
.attr("y", yScale(0) + 40 )
.style("text-anchor", "middle")
.text("State");
//Create Y axis label
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", xScale(0) - 80 )
.attr("x",0 - (h / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Revenue");
I use a simple function to measure text and then compute margins based on that.
// create a dummy element, apply the appropriate classes,
// and then measure the element
function measure(text, classname) {
if(!text || text.length === 0) return {height: 0, width: 0};
var container = d3.select('body').append('svg').attr('class', classname);
container.append('text').attr({x: -1000, y: -1000}).text(text);
var bbox = container.node().getBBox();
container.remove();
return {height: bbox.height, width: bbox.width};
}
Now you can use
var titleSize = measure('my title', 'chart title'),
margin.top = titleSize.height + 20; // add whatever padding you want
I updated your example at http://jsfiddle.net/uzddx/2/. You can see the top margin resizes when you modify the font size of the title. You could do something similar for the left margin so that your label isn't so far away from the y-axis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With