javascript - Using d3 to shade area between two lines -


so have chart plotting traffic vs. date , rate vs. date. i'm trying shade area between 2 lines. however, want shade different color depending on line higher. following works without last requirement:

var area = d3.svg.area()     .x0(function(d) { return x(d3.time.format("%m/%d/%y").parse(d.original.date)); })     .x1(function(d) { return x(d3.time.format("%m/%d/%y").parse(d.original.date)); })     .y0(function(d) { return y(parseint(d.original.traffic)); })     .y1(function(d) { return y(parseint(d.original.rate)); }) 

however, adding last requirement, tried use defined():

.defined(function(d){ return parseint(d.original.traffic) >= parseint(d.original.rate); }) 

now works, except when lines cross. how shade area under 1 line between points? it's shading based on points , want shade based on line. if don't have 2 consecutive points on 1 side of line, don't shading @ all.

since don't have datapoints @ intersections, simplest solution areas above , below each line , use clippaths crop difference.

i'll assume you're using d3.svg.line draw lines areas based on. way we'll able re-use .x() , .y() accessor functions on areas later:

var trafficline = d3.svg.line()   .x(function(d) { return x(d3.time.format("%m/%d/%y").parse(d.original.date)); })   .y(function(d) { return y(parseint(d.original.traffic)); });  var rateline = d3.svg.line()   .x(trafficline.x()) // reuse traffic line's x   .y(function(d) { return y(parseint(d.original.rate)); }) 

you can create separate area functions calculating areas both above , below 2 lines. area below each line used drawing actual path, , area above used clipping path. can re-use accessors lines:

var areaabovetrafficline = d3.svg.area()   .x(trafficline.x())   .y0(trafficline.y())   .y1(0); var areabelowtrafficline = d3.svg.area()   .x(trafficline.x())   .y0(trafficline.y())   .y1(height); var areaaboverateline = d3.svg.area()   .x(rateline.x())   .y0(rateline.y())   .y1(0); var areabelowrateline = d3.svg.area()   .x(rateline.x())   .y0(rateline.y())   .y1(height); 

...where height height of chart, , assuming 0 y-coordinate of top of chart, otherwise adjust values accordingly.

now can use area-above functions create clipping paths this:

var defs = svg.append('defs');  defs.append('clippath')   .attr('id', 'clip-traffic')   .append('path')   .datum(your_dataset)   .attr('d', areaabovetrafficline);  defs.append('clippath')   .attr('id', 'clip-rate')   .append('path')   .datum(your_dataset)   .attr('d', areaaboverateline); 

the id attributes necessary because need refer definitions when clipping paths.

finally, use area-below functions draw paths svg. important thing remember here each area-below, need clip opposite area-above, rate area clipped based on #clip-traffic , vice versa:

// traffic above rate svg.append('path')   .datum(your_dataset)   .attr('d', areabelowtrafficline)   .attr('clip-path', 'url(#clip-rate)')  // rate above traffic svg.append('path')   .datum(your_dataset)   .attr('d', areabelowrateline)   .attr('clip-path', 'url(#clip-traffic)') 

after you'll need give 2 regions different fill colors or whatever want distinguish them 1 another. hope helps!


Comments

Popular posts from this blog

magento2 - Magento 2 admin grid add filter to collection -

Android volley - avoid multiple requests of the same kind to the server? -

Combining PHP Registration and Login into one class with multiple functions in one PHP file -