gka / d3-jetpack

🚀 Nifty convenience wrappers that speed up your daily work with d3.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

unify translate and line api

1wheel opened this issue · comments

It'd be nice if there was a consistent way of mapping data to a 2D space. Currently we switch between

  c.svg.appendMany(d, 'circle')
    .translate(d => [c.x(d.components), c.y(d.elements)])

and

  var line = d3.line()
    .x(d => c.x(d.components))
    .y(d => c.y(d.elements))

Ideally, line and selection would expose a translate or a pos method that did this. I'm not sure how to do that without forking d3-shape - I think you need access to variables captured in a closure.

Something like this would work:

  function setTranslate(line, fn){
    return line.x(d => fn(d)[0]).y(d => fn(d)[1])
  }

  setTranslate(d3.line().curve(d3.curveLinear), d => [c.x(d.components), c.y(d.elements)])

But that's not nearly as readable as

  d3.line()
    .curve(d3.curveLinear)
    .translate(d => [c.x(d.components), c.y(d.elements)])

Maybe a fork of d3.line would be best; that could also avoid calling the translate function once for x and once for y.

I don't think this is worth the effort.

  1. line is just one of many shape generators in d3-shape. Why worry about something with a limited use case like this? What about area, pie, arc, etc?
  2. I think d3.line().translate() is confusing because it's not imminent that you're not translating the entire line but the single points.
  3. translate() right now only works on a selection and it's setting a transform:translate() property (either css or svg attr). this would be an entirely different interpretation of translate, which I think should not use the same name.
  4. using this kind of "translate" you could easily scale or skew a line, which is not a translation in the geometrical sense. hence, the name would be misleading.

If you must have it I would suggest renaming it to d3.line().xy().

But again I would then expect the same in d3.area, but d3.area().xy0y1() is kind of ugly, also there are other possible combinations.

d3.area().xy(d => [x(d.year), [height, y(d.value)]) could work instead of d3.area().xy0y1()

But I don't think forking d3.line would be worth it. Maybe if there was a simpler way...