1

I am trying to shade an area between two curves (time series). I adapted an example that I found at C3.js fill area between curves, but I need to use the D3.js version 5, due to my work, and from D3 version 4 some methods have been replaced by others.

Here is my code using D3.js v3:

function fillArea(){
var indexies = d3.range( items.length );
var yscale = linechart.internal.y;            
var xscale = linechart.internal.x; 

var area = d3.svg.area()
             .interpolate("linear")
             .x(function(d) {return xscale(new Date(items[d].Index)); })
             .y0(function(d) { return yscale(items[d].ymin_sd); })
             .y1(function(d) { return yscale(items[d].ymax_sd); });  

d3.select("#chart svg g").append('path')
  .datum(indexies)
  .attr('class', 'area')
  .attr('fill', 'red')
  .attr('d', area);
}

And the jsfiddle

Here is my code adapted to D3 v5, with version that I need, but the shading does not appear.

function fillArea(){
var indexies = d3.range( items.length );
var yscale = linechart.internal.y;            
var xscale = linechart.internal.x; 

var area = d3.area()
           .curveCardinal()
           .x(function(d) {return xscale(new Date(items[d].Index)); })
           .y0(function(d) { return yscale(items[d].ymin_sd); })
           .y1(function(d) { return yscale(items[d].ymax_sd); });  

d3.select("#chart svg g").append('path')
  .datum(indexies)
  .attr('class', 'area')
  .attr('fill', 'red')
  .attr('d', area);
}

Here is jsfiddle adapted to D3 v5.

Anyone can help me what I am doing wrong in my code?

ammaciel
  • 13
  • 3

1 Answers1

0

first and foremost, I think you might have imported the wrong versions of d3.js and c3.js on your second jsfiddle link. The js fiddle link seems to be importing older versions of c3 and d3, thus your examples weren't running there. You should use these 2 instead if you are importing them via CDNs.

https://d3js.org/d3.v5.min.js

and

https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.12/c3.min.js
https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.12/c3.min.css

Also, I dont think you can chain .area() and .curveCardinal() together.

You can only do this:

d3.area() 

or this.

d3.curveCardinal()

If you remove the .curveCardinal(), you will realise that your code actually works

var area = d3.area()
           .x(function(d) {return xscale(new Date(items[d].Index)); })
           .y0(function(d) { return yscale(items[d].ymin_sd); })
           .y1(function(d) { return yscale(items[d].ymax_sd); }); 

There is no need for .interpolate('linear') from d3.js v4 onwards, as linear interpolation is by default.

wentjun
  • 40,384
  • 10
  • 95
  • 107
  • `d3.curveCardinal()` is the argument of `area.curve()` – rioV8 Feb 12 '19 at 14:38
  • Are you using d3.curve? It wasnt stated on the example you provided.. Are you trying to do an `d3.area`? Or `d3.line().curve(d3.curveCardinal)`? Or `d3.area.curve`? – wentjun Feb 12 '19 at 17:09
  • 1
    "I dont think you can chain .area() and .curveCardinal() together.": You can't chain them together, but you can use both together - [example](https://jsfiddle.net/7s29a8yj/) - it just needs to be provided to area.curve() as noted by rioV8 (and in the [docs](https://github.com/d3/d3-shape#area_curve)) – Andrew Reid Feb 12 '19 at 17:23
  • Exactly, you are right! I was merely pointing out the mistake in his/her code. He wrote `d3.area().curveCardinal()`. Thats why I was kinda confused, because that itself will cause the compile to scream and return an error. As I mentioned on my previous comment, one way to use it is though `d3.line().curve(d3.curveCardinal)`, or as you mentioned, `d3.area().curve(d3.curveCardinal)`. Btw, does the OP has any updates regarding the issue? – wentjun Feb 12 '19 at 17:58