Reputation: 898
At work someone who isn't available anymore made an application with a D3.js
graph in it, it wasn't finished yet and I have to finish it. However I wasn't and I still am not familiar with the D3.js library I could fix some things. But one thing I just can't fix, I have a graph with a colored area, that works and looks well, that has to show a red graph instead of yellow if a value is exceeded. In this case the value is -30, so above the red line (see pictures).
The image on the left shows what I have now and the right one what it needs to be:
I found out that multiple areas can be stacked with the d3.layout.stack()
function. But I only find examples with code using hard-coded JSON
or multiple graphs at top of each other.
The code below is what I have now: (I cut out that is irrelevant)
var area = d3.svg.area()
.interpolate("basis")
.x(function (d) {return x(d.date); })
.y0(function (d) {return y(0); })
.y1(function (d) {return y(d.energy); });
var svg = d3.select("#datacontainer2").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var context = svg.append("g").attr("transform","translate("+margin2.left+","+margin2.top + ")");
d3.csv("file:///data.txt", function (error, data) {
data.forEach(function (d) {
d.date = parseDate(d.date);
d.energy = d.energy;
});
x.domain(d3.extent(data.map(function (d) { return d.date; })));
y.domain([25, -50] /*d3.extent(data.map(function(d) { return d.energy; }))*/ );
x2.domain(x.domain());
y2.domain(y.domain());
focus.append("path")
.datum(data)
.attr("clip-path", "url(#clip)")
.attr("d", area);
// red line
focus.append("svg:line")
.attr("x1", 0)
.attr("x2", height * data.length)
.attr("y1", (function (d) { return y(-30); } ))
.attr("y2", (function (d) { return y(-30); }))
.attr("stroke", "#ff0000")
.attr("stroke-width", "3");
});
Also, all values below zero should be green colored, but this could be easily extended when having the code for above question.
Upvotes: 4
Views: 3581
Reputation: 619
This is an old question, but in case it helps anyone who stumbles upon this question, I was having a similar problem. I hate the way gradients visually look, so I searched for an alternative answer. A different, and in my opinion a cleaner approach can be taken using this example from Mike himself.
http://bl.ocks.org/mbostock/4062844
Upvotes: 1
Reputation: 2228
This is what you might be looking for: http://jsfiddle.net/h45CD/.
Create a area gradient and color according to that.
// Set the threshold
svg.append("linearGradient")
.attr("id", "area-gradient") // change from line to area
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", y(0))
.attr("x2", 0).attr("y2", y(1000))
.selectAll("stop")
.data([
{offset: "0%", color: "red"},
{offset: "30%", color: "red"},
{offset: "45%", color: "black"},
{offset: "55%", color: "black"},
{offset: "60%", color: "lawngreen"},
{offset: "100%", color: "lawngreen"}
])
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; });
More on this you can find at d3noob.
Upvotes: 3