14

I'm creating a line chart in d3.js like this:

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.temperature); });

I then want to put dots on the line data points like this:

var points = svg.selectAll(".point")
        .data(cities1[0].values)
      .enter().append("svg:circle")
         .attr("stroke", "black")
         .attr("fill", function(d, i) { return "black" })
         .attr("cx", function(d, i) { return x(d.date) })
         .attr("cy", function(d, i) { return y(d.temperature) })
         .attr("r", function(d, i) { return 3 });

The result is not what I expect:

enter image description here

I then change interpolate("basis") to interpolate("cardinal") and get what I want:

enter image description here

Why did I got the wrong result with basis? How can I draw the accurate points with basis too?

EDIT: A similar (unanswered) question. Check out this jsfiddle. It will only work if changing the interpolate from basis to cardinal (or other) mode. But Cardinal has a problem that it does not respect the max height of the graph. What I'm looking for is an explanation on why some interpolation modes prevent from putting the points in the right place (and why cardinal does not respect max height).

Community
  • 1
  • 1
Yaron Naveh
  • 23,560
  • 32
  • 103
  • 158
  • I see two axes; one on the left, one on the right. Perhaps the points were drawn against the wrong axis? Or not redrawn after the scaling was done. Hard to say without the full code. – cmonkey Dec 26 '12 at 14:48
  • I have the same problem. See my question here: http://stackoverflow.com/questions/16491180/formula-to-calculate-the-control-point-from-three-known-points-on-a-d3-basis-c It must be possible to calculate the control points for the "basis" interpolation so that the line goes through all your points. If you look here, http://stackoverflow.com/questions/9710616/explain-formula-to-curve-through-a-control-point , you will see how this is being done for curves generated by HTML 5 `quadraticCurveTo`. The formula for `D3` "basis" curves is different though so the solution given there won't work. – BruceHill May 11 '13 at 10:18
  • So if someone is able to help with the maths involved in doing the calculation of the control points for `D3` basis interpolate then it must be possible to solve this. – BruceHill May 11 '13 at 10:21
  • This [related question/answer](http://stackoverflow.com/a/18124827/2415524) may be useful. – mbomb007 Feb 25 '16 at 19:41

2 Answers2

12

This is unfortunately a property of the "basis" interpolation -- the line doesn't necessarily run through the points. There's no way of "fixing" this. Unless you absolutely need this particular interpolation, just stick with one that allows you to get the points right.

You could implement a custom interpolation that gives you access to the points the line runs through and add circles accordingly. This will require a somewhat in-depth knowledge of how d3 and line interpolators work though.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
0

It is my understanding that 'basis' interpolation creates a mean line between the data points. Cardinal create a smooth line that connects all points.