I'm using SVG and D3 to create bar graphs and have a question concerning how to color them. I've searched many questions on this site and others and haven't yet found anyone with the same issue.
I would like each bar to start at the bottom with one color, (yellow, e.g.) and, as the bar gets taller, progressively mix in more of the second color, (red, e.g.), so that the bars at their maximum potential height would be only the second color. In this example, the tops of the bars that are half their potential height would be orange.
I was able to write a function to produce, for a bar of any given height, a unique linear gradient that would color the bars as desired.
However, since this graph is dynamic and the heights of the bars may change many times per second as the data is refreshed, creating and applying a new gradient each time and for each bar is definitely not efficient and could result in serious lag in refreshing the bars. (I admit I haven't actually tried this with anything other than a static test case, so I could be wrong about that last assumption.)
Using a static gradient of course yields something like this, where the colors are mixed according to the height of the bar, not the height of the region:
In my desired scenario, however, the smaller bars should have very little red or dark blue respectively.
My question, finally, is this: is there a way to
Or, is there some other technique I'm overlooking?
Thanks
This is simple to implement but a bit hard to grasp, you need to specify that the gradient units are userSpaceOnUse
and then define the region where you want it to apply through x1
, x2
, y1
, y2
:
var gradient = svg
.append("linearGradient")
.attr("y1", minY)
.attr("y2", maxY)
.attr("x1", "0")
.attr("x2", "0")
.attr("id", "gradient")
.attr("gradientUnits", "userSpaceOnUse")
gradient
.append("stop")
.attr("offset", "0")
.attr("stop-color", "#ff0")
gradient
.append("stop")
.attr("offset", "0.5")
.attr("stop-color", "#f00")
You can see a demo here: http://jsfiddle.net/ZCwrx/