d3 / d3-shape

Graphical primitives for visualization, such as lines and areas.
https://d3js.org/d3-shape
ISC License
2.47k stars 305 forks source link

Accept iterables. #153

Closed mbostock closed 3 years ago

mbostock commented 4 years ago

Fixes #148.

Fil commented 4 years ago

I just tested https://github.com/d3/d3-shape/pull/153/commits/5a4e7929c4ea8865e4d7591274a16cdd2416008d on a notebook I was working on today 👍

mbostock commented 4 years ago

Here’s a good example of how iterables support will help:

https://observablehq.com/@mbostock/revenue-by-music-format-1973-2018

Before:

series = d3.stack()
    .keys(Array.from(colors.keys()))
    .value(([, group], name) => group.get(name).value)
    .order(d3.stackOrderReverse)
  (Array.from(d3.rollup(data, ([d]) => d, d => +d.date, d => d.name)))

After:

series = d3.stack()
    .keys(colors.keys())
    .value(([, group], name) => group.get(name).value)
    .order(d3.stackOrderReverse)
  (d3.rollup(data, ([d]) => d, d => +d.date, d => d.name))

Similarly with d3-scale support, before:

color = d3.scaleOrdinal()
    .domain(Array.from(colors.keys()))
    .range(Array.from(colors.values()))

After:

color = d3.scaleOrdinal()
    .domain(colors.keys())
    .range(colors.values())
Fil commented 4 years ago

In the README "input data array" can become "input data array (or iterable)", but I'm not sure about the most legible formulation.

And there will be a small difficulty for the sentence:

When a pie is generated, the value accessor will be invoked for each element in the input data array, being passed the element d, the index i, and the array data as three arguments.

because in this case it's not the original iterator that is passed to the value accessor, but its array form.

Maybe the simplest way of solving this is to add somewhere "all methods that accept arrays also accept iterables and convert them to arrays internally"?

(fixed in https://github.com/d3/d3-shape/pull/153/commits/4364ddc62f1f4ed08a7f154bdaef8e2935d47d63)