In Part 1 of this series on re-creating the Ruder-Finn Intent Index radial bar chart using D3.js, I created the background and the category gridlines for the chart, and in Part 2, I added the question gridlines and bars. In this last part of this three part series, I add the category and question labels to the chart.
Working with the category labels was fairly straightforward, especially after reading the fantastic tutorial, Placing Texts on Arcs with D3.js. This tutorial contained the solution for putting the labels on the arc and flipping the labels on the bottom half of the chart so that they weren't upside down. I added the requirement that the whole slice (not just the end angle) had to be between 90 and 270 degrees before flipping the label. This coincidentally resulted in all of the questions labels being flipped for a flipped category label, however a better solution would have been to only flip the question label if the category label was flipped.
The question labels were more complicated to deal with because they had to additionally be wrapped and centered both horizontally and vertically.
For wrapping the text, Mike Bostock's Wrapping Long Labels gave me a start to my solution. The function he provides ended up working well once I realized I had to determine the length of the arc and the length of the label in a less elegant manner. The result is the wrapTextOnArc function, which could use some refactoring, but gets the job done. The trick here was to create a temporary text element for use in getting an accurate measurement of the text length because using getComputedTextLength on the tspan's node just wasn't working (presumably because it was on an arc). This allowed me to determine when to wrap the text as well as assign an x value to the tspan in order to horizontally center each line.
After wrapping and horizontally centering the question label, I had to make one more pass against the question labels to vertically center them. This basically consisted of a trial and error adjustment to the dy attribute of the first line (i.e. tspan) of the label based on the number of lines.
While not resulting in an exact replica, its pretty close. I ended up making some adjustments to the code in Plunker in order to make the chart fit within my blog post. This meant shrinking the chart and shrinking the font so that the word "Community" would fit.
There's a lot of room for improvement here, including: choosing a better font; sizing a label's font if it contains a word that is too large for the allotted space (e.g.: community); flipping a question's text only if the category's label was flipped; only flipping the category label if the majority of the arc is on the bottom half; and adding more chart animation and interactivity.
However, in the end, I still feel like I accomplished my goal of establishing a jumping off point for creating a chart that will better fit my own data.
For a complete listing of the code and a working example, check out the Plunker: