This simple bar chart evolved from my d3v4 fork of mbostock's Bar Chart.
Bar charts in d3 are usually presented as simpler to comprehend examples of using d3 to visualize data. Such bar charts suffer from two issues that are not straightforward to overcome.
-
The math is confusing. Given SVG's "reversed" y-coordinate system, the top of each bar is at the y-coordinate of the data point, but the height is something like the total height minus that data point's y-coordinate. Probably...possibly...I don't honestly know, I'd have to look it up. If it wasn't for bl.ocks examples of bar charts, I'd be stuck every time, trying to figure out the correct y and height attributes for each rectangle in a bar chart.
-
Clickability of the bars. From a usability perspective, bar charts generally have varying interaction characterstics. Tall bars are generally easier to click or hover the mouse. Shorter bars are trickier. A common method is to bind the data to a second set of
<rect>
objects. The second<rect>
s are full height and width and invisible/transparent. Most importantly, they capture the mouse hover and click events for the bar.
These issues are obviously surmountable, and most people don't think too much about them. However, over time I've come to use a slightly different method of rendering bar charts. The data is still joined to two different DOM elements, but the overall math is much easier.
What if we could think of our <rect>
s as containers for color? In other words, what if we had full-height <rect>
objects, that we could fill with paint up to a certain height?
Lucky for us, SVG lets us do exacly that with SVG linearGradients. We define a linearGradient in the SVG's <defs>
section. Each bar will use its own unique linearGradient. Therefore, we'll define one linearGradient for each letter represented in our example dataset.
- Each gradient need an "id" attribute. We use this attribute to refer to the gradient when we need to paint a rectangle.