11import { Selection } from "./index.js" ;
22import { EnterNode } from "./enter.js" ;
3- import array from "../array.js" ;
43import constant from "../constant.js" ;
54
65function bindIndex ( parent , group , enter , update , exit , data ) {
@@ -90,7 +89,7 @@ export default function(value, key) {
9089 var parent = parents [ j ] ,
9190 group = groups [ j ] ,
9291 groupLength = group . length ,
93- data = array ( value . call ( parent , parent && parent . __data__ , j , parents ) ) ,
92+ data = arraylike ( value . call ( parent , parent && parent . __data__ , j , parents ) ) ,
9493 dataLength = data . length ,
9594 enterGroup = enter [ j ] = new Array ( dataLength ) ,
9695 updateGroup = update [ j ] = new Array ( dataLength ) ,
@@ -115,3 +114,15 @@ export default function(value, key) {
115114 update . _exit = exit ;
116115 return update ;
117116}
117+
118+ // Given some data, this returns an array-like view of it: an object that
119+ // exposes a length property and allows numeric indexing. Note that unlike
120+ // selectAll, this isn’t worried about “live” collections because the resulting
121+ // array will only be used briefly while data is being bound. (It is possible to
122+ // cause the data to change while iterating by using a key function, but please
123+ // don’t; we’d rather avoid a gratuitous copy.)
124+ function arraylike ( data ) {
125+ return typeof data === "object" && "length" in data
126+ ? data // Array, TypedArray, NodeList, array-like
127+ : Array . from ( data ) ; // Map, Set, iterable, string, or anything else
128+ }
0 commit comments