0

I have seen an example of d3.svg.line() being as follows:

        var altitude = some_array()  // I read this from a .json file

        y = d3.scale.linear().domain([0, d3.max(altitude)]).range([0 + margin, h - margin]),
        x = d3.scale.linear().domain([0, altitude]).range([0 + margin, w - margin])

        var line = d3.svg.line()
            .x(function(d,i) { return x(i); })
            .y(function(d) { return -1 * y(d); })

        some_svg_group.append("svg:path").attr("d", line(altitude));

although I didn't quite understood what is actually happening, I get that this is a sort of generator function, where line().x and line().y are sort of generator functions, and the idiom shown is a way to have an equally spaced x array versus the actual values in the y array.

What I would like to do, though, is to pass TWO arrays to d3.svg.line(), say distance and altitude, more or less like this:

var line = d3.svg.line()
    .x(function_that_gives_distance)
    .y(function_that_fives_altitude)

some_svg_group.append("svg:path").attr("something", line(some_other_thing));

Any suggestion on what to replace those placeholders with? Or, if they are wrong, how to achieve that at all?

heltonbiker
  • 26,657
  • 28
  • 137
  • 252

1 Answers1

1

line.x and line.y are actually accessors. The array you pass into the line generator represents a set of data points and the accessor functions are used to map each data point onto appropriate x and y pixel coordinates.

So with that in mind, it probably doesn't make sense represent the same data points using 2 separate arrays. You should try to transform distance and altitude into a single array of data points ahead of time. Then, you can defined your x and y accessors to map the properties on your data point to the correct pixel locations. Using your placeholder terminology, I would think that function_that_gives_distance and function_that_gives_altitude would actually be invoked as part of the construction of the data points, not in the line generator's accessors.

To summarize, break apart the workflow into 2 steps:

  1. Transform the data into a set of data points you want to base the line on.
  2. Use the line generator accessor functions to do a projection of these data points onto the drawing system's coordinates (i.e. pixel positions).
Scott Cameron
  • 5,293
  • 2
  • 29
  • 32
  • It makes sense. I think I'm gonna read more thoroughly later, but this seems to complete the cycle: http://stackoverflow.com/a/10284006/401828 – heltonbiker Sep 12 '13 at 02:42