@d3plus/data 3.0.12 → 3.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/src/addToQueue.js +3 -3
- package/es/src/isData.js +1 -1
- package/es/src/load.js +23 -28
- package/package.json +3 -3
- package/umd/d3plus-data.full.js +211 -422
- package/umd/d3plus-data.full.js.map +1 -1
- package/umd/d3plus-data.full.min.js +25 -44
- package/umd/d3plus-data.js +28 -34
- package/umd/d3plus-data.js.map +1 -1
- package/umd/d3plus-data.min.js +14 -12
package/umd/d3plus-data.full.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
@d3plus/data v3.0.
|
|
2
|
+
@d3plus/data v3.0.13
|
|
3
3
|
JavaScript data loading, manipulation, and analysis functions.
|
|
4
4
|
Copyright (c) 2025 D3plus - https://d3plus.org
|
|
5
5
|
@license MIT
|
|
@@ -117,380 +117,7 @@
|
|
|
117
117
|
@function isData
|
|
118
118
|
@desc Returns true/false whether the argument provided to the function should be loaded using an internal XHR request. Valid data can either be a string URL or an Object with "url" and "headers" keys.
|
|
119
119
|
@param {*} dataItem The value to be tested
|
|
120
|
-
*/ var isData = ((dataItem)=>typeof dataItem === "string" || typeof dataItem === "object" && dataItem.url
|
|
121
|
-
|
|
122
|
-
var prefix = "$";
|
|
123
|
-
function Map() {}
|
|
124
|
-
Map.prototype = map.prototype = {
|
|
125
|
-
constructor: Map,
|
|
126
|
-
has: function(key) {
|
|
127
|
-
return prefix + key in this;
|
|
128
|
-
},
|
|
129
|
-
get: function(key) {
|
|
130
|
-
return this[prefix + key];
|
|
131
|
-
},
|
|
132
|
-
set: function(key, value) {
|
|
133
|
-
this[prefix + key] = value;
|
|
134
|
-
return this;
|
|
135
|
-
},
|
|
136
|
-
remove: function(key) {
|
|
137
|
-
var property = prefix + key;
|
|
138
|
-
return property in this && delete this[property];
|
|
139
|
-
},
|
|
140
|
-
clear: function() {
|
|
141
|
-
for(var property in this)if (property[0] === prefix) delete this[property];
|
|
142
|
-
},
|
|
143
|
-
keys: function() {
|
|
144
|
-
var keys = [];
|
|
145
|
-
for(var property in this)if (property[0] === prefix) keys.push(property.slice(1));
|
|
146
|
-
return keys;
|
|
147
|
-
},
|
|
148
|
-
values: function() {
|
|
149
|
-
var values = [];
|
|
150
|
-
for(var property in this)if (property[0] === prefix) values.push(this[property]);
|
|
151
|
-
return values;
|
|
152
|
-
},
|
|
153
|
-
entries: function() {
|
|
154
|
-
var entries = [];
|
|
155
|
-
for(var property in this)if (property[0] === prefix) entries.push({
|
|
156
|
-
key: property.slice(1),
|
|
157
|
-
value: this[property]
|
|
158
|
-
});
|
|
159
|
-
return entries;
|
|
160
|
-
},
|
|
161
|
-
size: function() {
|
|
162
|
-
var size = 0;
|
|
163
|
-
for(var property in this)if (property[0] === prefix) ++size;
|
|
164
|
-
return size;
|
|
165
|
-
},
|
|
166
|
-
empty: function() {
|
|
167
|
-
for(var property in this)if (property[0] === prefix) return false;
|
|
168
|
-
return true;
|
|
169
|
-
},
|
|
170
|
-
each: function(f) {
|
|
171
|
-
for(var property in this)if (property[0] === prefix) f(this[property], property.slice(1), this);
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
function map(object, f) {
|
|
175
|
-
var map = new Map;
|
|
176
|
-
// Copy constructor.
|
|
177
|
-
if (object instanceof Map) object.each(function(value, key) {
|
|
178
|
-
map.set(key, value);
|
|
179
|
-
});
|
|
180
|
-
else if (Array.isArray(object)) {
|
|
181
|
-
var i = -1, n = object.length, o;
|
|
182
|
-
if (f == null) while(++i < n)map.set(i, object[i]);
|
|
183
|
-
else while(++i < n)map.set(f(o = object[i], i, object), o);
|
|
184
|
-
} else if (object) for(var key in object)map.set(key, object[key]);
|
|
185
|
-
return map;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function nest$1() {
|
|
189
|
-
var keys = [], sortKeys = [], sortValues, rollup, nest;
|
|
190
|
-
function apply(array, depth, createResult, setResult) {
|
|
191
|
-
if (depth >= keys.length) {
|
|
192
|
-
if (sortValues != null) array.sort(sortValues);
|
|
193
|
-
return rollup != null ? rollup(array) : array;
|
|
194
|
-
}
|
|
195
|
-
var i = -1, n = array.length, key = keys[depth++], keyValue, value, valuesByKey = map(), values, result = createResult();
|
|
196
|
-
while(++i < n){
|
|
197
|
-
if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
|
|
198
|
-
values.push(value);
|
|
199
|
-
} else {
|
|
200
|
-
valuesByKey.set(keyValue, [
|
|
201
|
-
value
|
|
202
|
-
]);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
valuesByKey.each(function(values, key) {
|
|
206
|
-
setResult(result, key, apply(values, depth, createResult, setResult));
|
|
207
|
-
});
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
|
-
function entries(map, depth) {
|
|
211
|
-
if (++depth > keys.length) return map;
|
|
212
|
-
var array, sortKey = sortKeys[depth - 1];
|
|
213
|
-
if (rollup != null && depth >= keys.length) array = map.entries();
|
|
214
|
-
else array = [], map.each(function(v, k) {
|
|
215
|
-
array.push({
|
|
216
|
-
key: k,
|
|
217
|
-
values: entries(v, depth)
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
return sortKey != null ? array.sort(function(a, b) {
|
|
221
|
-
return sortKey(a.key, b.key);
|
|
222
|
-
}) : array;
|
|
223
|
-
}
|
|
224
|
-
return nest = {
|
|
225
|
-
object: function(array) {
|
|
226
|
-
return apply(array, 0, createObject, setObject);
|
|
227
|
-
},
|
|
228
|
-
map: function(array) {
|
|
229
|
-
return apply(array, 0, createMap, setMap);
|
|
230
|
-
},
|
|
231
|
-
entries: function(array) {
|
|
232
|
-
return entries(apply(array, 0, createMap, setMap), 0);
|
|
233
|
-
},
|
|
234
|
-
key: function(d) {
|
|
235
|
-
keys.push(d);
|
|
236
|
-
return nest;
|
|
237
|
-
},
|
|
238
|
-
sortKeys: function(order) {
|
|
239
|
-
sortKeys[keys.length - 1] = order;
|
|
240
|
-
return nest;
|
|
241
|
-
},
|
|
242
|
-
sortValues: function(order) {
|
|
243
|
-
sortValues = order;
|
|
244
|
-
return nest;
|
|
245
|
-
},
|
|
246
|
-
rollup: function(f) {
|
|
247
|
-
rollup = f;
|
|
248
|
-
return nest;
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
function createObject() {
|
|
253
|
-
return {};
|
|
254
|
-
}
|
|
255
|
-
function setObject(object, key, value) {
|
|
256
|
-
object[key] = value;
|
|
257
|
-
}
|
|
258
|
-
function createMap() {
|
|
259
|
-
return map();
|
|
260
|
-
}
|
|
261
|
-
function setMap(map, key, value) {
|
|
262
|
-
map.set(key, value);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function Set() {}
|
|
266
|
-
var proto = map.prototype;
|
|
267
|
-
Set.prototype = {
|
|
268
|
-
constructor: Set,
|
|
269
|
-
has: proto.has,
|
|
270
|
-
add: function(value) {
|
|
271
|
-
value += "";
|
|
272
|
-
this[prefix + value] = value;
|
|
273
|
-
return this;
|
|
274
|
-
},
|
|
275
|
-
remove: proto.remove,
|
|
276
|
-
clear: proto.clear,
|
|
277
|
-
values: proto.keys,
|
|
278
|
-
size: proto.size,
|
|
279
|
-
empty: proto.empty,
|
|
280
|
-
each: proto.each
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
var noop = {
|
|
284
|
-
value: function() {}
|
|
285
|
-
};
|
|
286
|
-
function dispatch() {
|
|
287
|
-
for(var i = 0, n = arguments.length, _ = {}, t; i < n; ++i){
|
|
288
|
-
if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t)) throw new Error("illegal type: " + t);
|
|
289
|
-
_[t] = [];
|
|
290
|
-
}
|
|
291
|
-
return new Dispatch(_);
|
|
292
|
-
}
|
|
293
|
-
function Dispatch(_) {
|
|
294
|
-
this._ = _;
|
|
295
|
-
}
|
|
296
|
-
function parseTypenames(typenames, types) {
|
|
297
|
-
return typenames.trim().split(/^|\s+/).map(function(t) {
|
|
298
|
-
var name = "", i = t.indexOf(".");
|
|
299
|
-
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
|
|
300
|
-
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
|
|
301
|
-
return {
|
|
302
|
-
type: t,
|
|
303
|
-
name: name
|
|
304
|
-
};
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
Dispatch.prototype = dispatch.prototype = {
|
|
308
|
-
constructor: Dispatch,
|
|
309
|
-
on: function(typename, callback) {
|
|
310
|
-
var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length;
|
|
311
|
-
// If no callback was specified, return the callback of the given type and name.
|
|
312
|
-
if (arguments.length < 2) {
|
|
313
|
-
while(++i < n)if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
// If a type was specified, set the callback for the given type and name.
|
|
317
|
-
// Otherwise, if a null callback was specified, remove callbacks of the given name.
|
|
318
|
-
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
|
|
319
|
-
while(++i < n){
|
|
320
|
-
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
|
|
321
|
-
else if (callback == null) for(t in _)_[t] = set(_[t], typename.name, null);
|
|
322
|
-
}
|
|
323
|
-
return this;
|
|
324
|
-
},
|
|
325
|
-
copy: function() {
|
|
326
|
-
var copy = {}, _ = this._;
|
|
327
|
-
for(var t in _)copy[t] = _[t].slice();
|
|
328
|
-
return new Dispatch(copy);
|
|
329
|
-
},
|
|
330
|
-
call: function(type, that) {
|
|
331
|
-
if ((n = arguments.length - 2) > 0) for(var args = new Array(n), i = 0, n, t; i < n; ++i)args[i] = arguments[i + 2];
|
|
332
|
-
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
|
|
333
|
-
for(t = this._[type], i = 0, n = t.length; i < n; ++i)t[i].value.apply(that, args);
|
|
334
|
-
},
|
|
335
|
-
apply: function(type, that, args) {
|
|
336
|
-
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
|
|
337
|
-
for(var t = this._[type], i = 0, n = t.length; i < n; ++i)t[i].value.apply(that, args);
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
function get(type, name) {
|
|
341
|
-
for(var i = 0, n = type.length, c; i < n; ++i){
|
|
342
|
-
if ((c = type[i]).name === name) {
|
|
343
|
-
return c.value;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
function set(type, name, callback) {
|
|
348
|
-
for(var i = 0, n = type.length; i < n; ++i){
|
|
349
|
-
if (type[i].name === name) {
|
|
350
|
-
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
|
|
351
|
-
break;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
if (callback != null) type.push({
|
|
355
|
-
name: name,
|
|
356
|
-
value: callback
|
|
357
|
-
});
|
|
358
|
-
return type;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function request(url, callback) {
|
|
362
|
-
var request, event = dispatch("beforesend", "progress", "load", "error"), mimeType, headers = map(), xhr = new XMLHttpRequest, user = null, password = null, response, responseType, timeout = 0;
|
|
363
|
-
// If IE does not support CORS, use XDomainRequest.
|
|
364
|
-
if (typeof XDomainRequest !== "undefined" && !("withCredentials" in xhr) && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
|
|
365
|
-
"onload" in xhr ? xhr.onload = xhr.onerror = xhr.ontimeout = respond : xhr.onreadystatechange = function(o) {
|
|
366
|
-
xhr.readyState > 3 && respond(o);
|
|
367
|
-
};
|
|
368
|
-
function respond(o) {
|
|
369
|
-
var status = xhr.status, result;
|
|
370
|
-
if (!status && hasResponse(xhr) || status >= 200 && status < 300 || status === 304) {
|
|
371
|
-
if (response) {
|
|
372
|
-
try {
|
|
373
|
-
result = response.call(request, xhr);
|
|
374
|
-
} catch (e) {
|
|
375
|
-
event.call("error", request, e);
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
} else {
|
|
379
|
-
result = xhr;
|
|
380
|
-
}
|
|
381
|
-
event.call("load", request, result);
|
|
382
|
-
} else {
|
|
383
|
-
event.call("error", request, o);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
xhr.onprogress = function(e) {
|
|
387
|
-
event.call("progress", request, e);
|
|
388
|
-
};
|
|
389
|
-
request = {
|
|
390
|
-
header: function(name, value) {
|
|
391
|
-
name = (name + "").toLowerCase();
|
|
392
|
-
if (arguments.length < 2) return headers.get(name);
|
|
393
|
-
if (value == null) headers.remove(name);
|
|
394
|
-
else headers.set(name, value + "");
|
|
395
|
-
return request;
|
|
396
|
-
},
|
|
397
|
-
// If mimeType is non-null and no Accept header is set, a default is used.
|
|
398
|
-
mimeType: function(value) {
|
|
399
|
-
if (!arguments.length) return mimeType;
|
|
400
|
-
mimeType = value == null ? null : value + "";
|
|
401
|
-
return request;
|
|
402
|
-
},
|
|
403
|
-
// Specifies what type the response value should take;
|
|
404
|
-
// for instance, arraybuffer, blob, document, or text.
|
|
405
|
-
responseType: function(value) {
|
|
406
|
-
if (!arguments.length) return responseType;
|
|
407
|
-
responseType = value;
|
|
408
|
-
return request;
|
|
409
|
-
},
|
|
410
|
-
timeout: function(value) {
|
|
411
|
-
if (!arguments.length) return timeout;
|
|
412
|
-
timeout = +value;
|
|
413
|
-
return request;
|
|
414
|
-
},
|
|
415
|
-
user: function(value) {
|
|
416
|
-
return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
|
|
417
|
-
},
|
|
418
|
-
password: function(value) {
|
|
419
|
-
return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
|
|
420
|
-
},
|
|
421
|
-
// Specify how to convert the response content to a specific type;
|
|
422
|
-
// changes the callback value on "load" events.
|
|
423
|
-
response: function(value) {
|
|
424
|
-
response = value;
|
|
425
|
-
return request;
|
|
426
|
-
},
|
|
427
|
-
// Alias for send("GET", …).
|
|
428
|
-
get: function(data, callback) {
|
|
429
|
-
return request.send("GET", data, callback);
|
|
430
|
-
},
|
|
431
|
-
// Alias for send("POST", …).
|
|
432
|
-
post: function(data, callback) {
|
|
433
|
-
return request.send("POST", data, callback);
|
|
434
|
-
},
|
|
435
|
-
// If callback is non-null, it will be used for error and load events.
|
|
436
|
-
send: function(method, data, callback) {
|
|
437
|
-
xhr.open(method, url, true, user, password);
|
|
438
|
-
if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
|
|
439
|
-
if (xhr.setRequestHeader) headers.each(function(value, name) {
|
|
440
|
-
xhr.setRequestHeader(name, value);
|
|
441
|
-
});
|
|
442
|
-
if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
|
|
443
|
-
if (responseType != null) xhr.responseType = responseType;
|
|
444
|
-
if (timeout > 0) xhr.timeout = timeout;
|
|
445
|
-
if (callback == null && typeof data === "function") callback = data, data = null;
|
|
446
|
-
if (callback != null && callback.length === 1) callback = fixCallback(callback);
|
|
447
|
-
if (callback != null) request.on("error", callback).on("load", function(xhr) {
|
|
448
|
-
callback(null, xhr);
|
|
449
|
-
});
|
|
450
|
-
event.call("beforesend", request, xhr);
|
|
451
|
-
xhr.send(data == null ? null : data);
|
|
452
|
-
return request;
|
|
453
|
-
},
|
|
454
|
-
abort: function() {
|
|
455
|
-
xhr.abort();
|
|
456
|
-
return request;
|
|
457
|
-
},
|
|
458
|
-
on: function() {
|
|
459
|
-
var value = event.on.apply(event, arguments);
|
|
460
|
-
return value === event ? request : value;
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
return request;
|
|
464
|
-
}
|
|
465
|
-
function fixCallback(callback) {
|
|
466
|
-
return function(error, xhr) {
|
|
467
|
-
callback(error == null ? xhr : null);
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
function hasResponse(xhr) {
|
|
471
|
-
var type = xhr.responseType;
|
|
472
|
-
return type && type !== "text" ? xhr.response // null on error
|
|
473
|
-
: xhr.responseText; // "" on error
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
function type(defaultMimeType, response) {
|
|
477
|
-
return function(url, callback) {
|
|
478
|
-
var r = request(url).mimeType(defaultMimeType).response(response);
|
|
479
|
-
if (callback != null) {
|
|
480
|
-
if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
|
|
481
|
-
return r.get(callback);
|
|
482
|
-
}
|
|
483
|
-
return r;
|
|
484
|
-
};
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
var json = type("application/json", function(xhr) {
|
|
488
|
-
return JSON.parse(xhr.responseText);
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
var text = type("text/plain", function(xhr) {
|
|
492
|
-
return xhr.responseText;
|
|
493
|
-
});
|
|
120
|
+
*/ var isData = ((dataItem)=>typeof dataItem === "string" || typeof dataItem === "object" && dataItem.url);
|
|
494
121
|
|
|
495
122
|
var EOL = {}, EOF = {}, QUOTE = 34, NEWLINE = 10, RETURN = 13;
|
|
496
123
|
function objectConverter(columns) {
|
|
@@ -527,7 +154,7 @@
|
|
|
527
154
|
var hours = date.getUTCHours(), minutes = date.getUTCMinutes(), seconds = date.getUTCSeconds(), milliseconds = date.getUTCMilliseconds();
|
|
528
155
|
return isNaN(date) ? "Invalid Date" : formatYear(date.getUTCFullYear()) + "-" + pad(date.getUTCMonth() + 1, 2) + "-" + pad(date.getUTCDate(), 2) + (milliseconds ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2) + "." + pad(milliseconds, 3) + "Z" : seconds ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2) + "Z" : minutes || hours ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + "Z" : "");
|
|
529
156
|
}
|
|
530
|
-
function
|
|
157
|
+
function dsvFormat(delimiter) {
|
|
531
158
|
var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), DELIMITER = delimiter.charCodeAt(0);
|
|
532
159
|
function parse(text, f) {
|
|
533
160
|
var convert, columns, rows = parseRows(text, function(row, i) {
|
|
@@ -614,32 +241,39 @@
|
|
|
614
241
|
};
|
|
615
242
|
}
|
|
616
243
|
|
|
617
|
-
var csv$1 =
|
|
244
|
+
var csv$1 = dsvFormat(",");
|
|
618
245
|
var csvParse = csv$1.parse;
|
|
619
246
|
|
|
620
|
-
var tsv$1 =
|
|
247
|
+
var tsv$1 = dsvFormat("\t");
|
|
621
248
|
var tsvParse = tsv$1.parse;
|
|
622
249
|
|
|
623
|
-
function
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
var r = request(url).mimeType(defaultMimeType);
|
|
627
|
-
r.row = function(_) {
|
|
628
|
-
return arguments.length ? r.response(responseOf(parse, row = _)) : row;
|
|
629
|
-
};
|
|
630
|
-
r.row(row);
|
|
631
|
-
return callback ? r.get(callback) : r;
|
|
632
|
-
};
|
|
250
|
+
function responseText(response) {
|
|
251
|
+
if (!response.ok) throw new Error(response.status + " " + response.statusText);
|
|
252
|
+
return response.text();
|
|
633
253
|
}
|
|
634
|
-
function
|
|
635
|
-
return
|
|
636
|
-
return parse(request.responseText, row);
|
|
637
|
-
};
|
|
254
|
+
function text(input, init) {
|
|
255
|
+
return fetch(input, init).then(responseText);
|
|
638
256
|
}
|
|
639
257
|
|
|
640
|
-
|
|
258
|
+
function dsvParse(parse) {
|
|
259
|
+
return function(input, init, row) {
|
|
260
|
+
if (arguments.length === 2 && typeof init === "function") row = init, init = undefined;
|
|
261
|
+
return text(input, init).then(function(response) {
|
|
262
|
+
return parse(response, row);
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
var csv = dsvParse(csvParse);
|
|
267
|
+
var tsv = dsvParse(tsvParse);
|
|
641
268
|
|
|
642
|
-
|
|
269
|
+
function responseJson(response) {
|
|
270
|
+
if (!response.ok) throw new Error(response.status + " " + response.statusText);
|
|
271
|
+
if (response.status === 204 || response.status === 205) return;
|
|
272
|
+
return response.json();
|
|
273
|
+
}
|
|
274
|
+
function json(input, init) {
|
|
275
|
+
return fetch(input, init).then(responseJson);
|
|
276
|
+
}
|
|
643
277
|
|
|
644
278
|
/**
|
|
645
279
|
@function isObject
|
|
@@ -696,22 +330,21 @@
|
|
|
696
330
|
@param {String} [key] The key in the `this` context to save the resulting data to.
|
|
697
331
|
@param {Function} [callback] A function that is called when the final data is loaded. It is passed 2 variables, any error present and the data loaded.
|
|
698
332
|
*/ function load(path, formatter, key, callback) {
|
|
699
|
-
|
|
700
|
-
const getParser = (path)=>{
|
|
333
|
+
const fetchData = (path, init = {})=>{
|
|
701
334
|
const ext = path.slice(path.length - 4);
|
|
702
335
|
switch(ext){
|
|
703
336
|
case ".csv":
|
|
704
|
-
return csv;
|
|
337
|
+
return csv(path, init);
|
|
705
338
|
case ".tsv":
|
|
706
|
-
return tsv;
|
|
339
|
+
return tsv(path, init);
|
|
707
340
|
case ".txt":
|
|
708
|
-
return text;
|
|
341
|
+
return text(path, init);
|
|
709
342
|
default:
|
|
710
|
-
return json;
|
|
343
|
+
return json(path, init);
|
|
711
344
|
}
|
|
712
345
|
};
|
|
713
|
-
const validateData = (
|
|
714
|
-
if (
|
|
346
|
+
const validateData = (data)=>{
|
|
347
|
+
if (data && data instanceof Array) {
|
|
715
348
|
data.forEach((d)=>{
|
|
716
349
|
for(const k in d){
|
|
717
350
|
if (!isNaN(d[k])) d[k] = parseFloat(d[k]);
|
|
@@ -725,7 +358,6 @@
|
|
|
725
358
|
return data;
|
|
726
359
|
};
|
|
727
360
|
const loadedLength = (loadedArray)=>loadedArray.reduce((prev, current)=>current ? prev + 1 : prev, 0);
|
|
728
|
-
const getPathIndex = (url, array)=>array.indexOf(url);
|
|
729
361
|
// If path param is a not an Array then convert path to a 1 element Array to re-use logic
|
|
730
362
|
if (!(path instanceof Array)) path = [
|
|
731
363
|
path
|
|
@@ -745,23 +377,16 @@
|
|
|
745
377
|
// Load all urls an combine them with data arrays
|
|
746
378
|
const alreadyLoaded = loadedLength(loaded);
|
|
747
379
|
toLoad.forEach((dataItem)=>{
|
|
748
|
-
let
|
|
749
|
-
if (typeof dataItem === "object") {
|
|
380
|
+
let url = dataItem, init = {};
|
|
381
|
+
if (typeof dataItem === "object" && dataItem.url) {
|
|
750
382
|
url = dataItem.url;
|
|
751
|
-
|
|
752
|
-
}
|
|
753
|
-
parser = getParser(url);
|
|
754
|
-
const request = parser(url);
|
|
755
|
-
for(const key in headers){
|
|
756
|
-
if (({}).hasOwnProperty.call(headers, key)) {
|
|
757
|
-
request.header(key, headers[key]);
|
|
758
|
-
}
|
|
383
|
+
init = dataItem;
|
|
759
384
|
}
|
|
760
|
-
|
|
761
|
-
data
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
385
|
+
fetchData(url, init).then((data)=>{
|
|
386
|
+
if (!(data instanceof Array) && data.data && data.headers) data = fold(data);
|
|
387
|
+
data = validateData(data);
|
|
388
|
+
loaded[path.findIndex((d)=>JSON.stringify(d) == JSON.stringify(dataItem))] = data;
|
|
389
|
+
// All urls loaded
|
|
765
390
|
if (loadedLength(loaded) - alreadyLoaded === toLoad.length) {
|
|
766
391
|
// Format data
|
|
767
392
|
data = loadedLength(loaded) === 1 ? loaded[0] : loaded;
|
|
@@ -777,8 +402,11 @@
|
|
|
777
402
|
data = concat(loaded, "data");
|
|
778
403
|
}
|
|
779
404
|
if (key && `_${key}` in this) this[`_${key}`] = data;
|
|
780
|
-
if (callback) callback(
|
|
405
|
+
if (callback) callback(undefined, data);
|
|
781
406
|
}
|
|
407
|
+
}).catch((err)=>{
|
|
408
|
+
console.log(err);
|
|
409
|
+
if (callback) callback(err, undefined);
|
|
782
410
|
});
|
|
783
411
|
});
|
|
784
412
|
// If there is no data to Load response is immediately
|
|
@@ -811,15 +439,15 @@
|
|
|
811
439
|
@param {Function} [data] An optional data formatter/callback
|
|
812
440
|
@param {String} data The internal Viz method to be modified
|
|
813
441
|
*/ function addToQueue(_, f, key) {
|
|
814
|
-
|
|
442
|
+
const paths = _ instanceof Array ? _ : [
|
|
815
443
|
_
|
|
816
444
|
];
|
|
817
|
-
const needToLoad =
|
|
445
|
+
const needToLoad = paths.find(isData);
|
|
818
446
|
if (needToLoad) {
|
|
819
447
|
const prev = this._queue.find((q)=>q[3] === key);
|
|
820
448
|
const d = [
|
|
821
449
|
load.bind(this),
|
|
822
|
-
|
|
450
|
+
paths,
|
|
823
451
|
f,
|
|
824
452
|
key
|
|
825
453
|
];
|
|
@@ -913,6 +541,167 @@
|
|
|
913
541
|
return newObject;
|
|
914
542
|
}
|
|
915
543
|
|
|
544
|
+
var prefix = "$";
|
|
545
|
+
function Map() {}
|
|
546
|
+
Map.prototype = map.prototype = {
|
|
547
|
+
constructor: Map,
|
|
548
|
+
has: function(key) {
|
|
549
|
+
return prefix + key in this;
|
|
550
|
+
},
|
|
551
|
+
get: function(key) {
|
|
552
|
+
return this[prefix + key];
|
|
553
|
+
},
|
|
554
|
+
set: function(key, value) {
|
|
555
|
+
this[prefix + key] = value;
|
|
556
|
+
return this;
|
|
557
|
+
},
|
|
558
|
+
remove: function(key) {
|
|
559
|
+
var property = prefix + key;
|
|
560
|
+
return property in this && delete this[property];
|
|
561
|
+
},
|
|
562
|
+
clear: function() {
|
|
563
|
+
for(var property in this)if (property[0] === prefix) delete this[property];
|
|
564
|
+
},
|
|
565
|
+
keys: function() {
|
|
566
|
+
var keys = [];
|
|
567
|
+
for(var property in this)if (property[0] === prefix) keys.push(property.slice(1));
|
|
568
|
+
return keys;
|
|
569
|
+
},
|
|
570
|
+
values: function() {
|
|
571
|
+
var values = [];
|
|
572
|
+
for(var property in this)if (property[0] === prefix) values.push(this[property]);
|
|
573
|
+
return values;
|
|
574
|
+
},
|
|
575
|
+
entries: function() {
|
|
576
|
+
var entries = [];
|
|
577
|
+
for(var property in this)if (property[0] === prefix) entries.push({
|
|
578
|
+
key: property.slice(1),
|
|
579
|
+
value: this[property]
|
|
580
|
+
});
|
|
581
|
+
return entries;
|
|
582
|
+
},
|
|
583
|
+
size: function() {
|
|
584
|
+
var size = 0;
|
|
585
|
+
for(var property in this)if (property[0] === prefix) ++size;
|
|
586
|
+
return size;
|
|
587
|
+
},
|
|
588
|
+
empty: function() {
|
|
589
|
+
for(var property in this)if (property[0] === prefix) return false;
|
|
590
|
+
return true;
|
|
591
|
+
},
|
|
592
|
+
each: function(f) {
|
|
593
|
+
for(var property in this)if (property[0] === prefix) f(this[property], property.slice(1), this);
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
function map(object, f) {
|
|
597
|
+
var map = new Map;
|
|
598
|
+
// Copy constructor.
|
|
599
|
+
if (object instanceof Map) object.each(function(value, key) {
|
|
600
|
+
map.set(key, value);
|
|
601
|
+
});
|
|
602
|
+
else if (Array.isArray(object)) {
|
|
603
|
+
var i = -1, n = object.length, o;
|
|
604
|
+
if (f == null) while(++i < n)map.set(i, object[i]);
|
|
605
|
+
else while(++i < n)map.set(f(o = object[i], i, object), o);
|
|
606
|
+
} else if (object) for(var key in object)map.set(key, object[key]);
|
|
607
|
+
return map;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function nest$1() {
|
|
611
|
+
var keys = [], sortKeys = [], sortValues, rollup, nest;
|
|
612
|
+
function apply(array, depth, createResult, setResult) {
|
|
613
|
+
if (depth >= keys.length) {
|
|
614
|
+
if (sortValues != null) array.sort(sortValues);
|
|
615
|
+
return rollup != null ? rollup(array) : array;
|
|
616
|
+
}
|
|
617
|
+
var i = -1, n = array.length, key = keys[depth++], keyValue, value, valuesByKey = map(), values, result = createResult();
|
|
618
|
+
while(++i < n){
|
|
619
|
+
if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
|
|
620
|
+
values.push(value);
|
|
621
|
+
} else {
|
|
622
|
+
valuesByKey.set(keyValue, [
|
|
623
|
+
value
|
|
624
|
+
]);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
valuesByKey.each(function(values, key) {
|
|
628
|
+
setResult(result, key, apply(values, depth, createResult, setResult));
|
|
629
|
+
});
|
|
630
|
+
return result;
|
|
631
|
+
}
|
|
632
|
+
function entries(map, depth) {
|
|
633
|
+
if (++depth > keys.length) return map;
|
|
634
|
+
var array, sortKey = sortKeys[depth - 1];
|
|
635
|
+
if (rollup != null && depth >= keys.length) array = map.entries();
|
|
636
|
+
else array = [], map.each(function(v, k) {
|
|
637
|
+
array.push({
|
|
638
|
+
key: k,
|
|
639
|
+
values: entries(v, depth)
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
return sortKey != null ? array.sort(function(a, b) {
|
|
643
|
+
return sortKey(a.key, b.key);
|
|
644
|
+
}) : array;
|
|
645
|
+
}
|
|
646
|
+
return nest = {
|
|
647
|
+
object: function(array) {
|
|
648
|
+
return apply(array, 0, createObject, setObject);
|
|
649
|
+
},
|
|
650
|
+
map: function(array) {
|
|
651
|
+
return apply(array, 0, createMap, setMap);
|
|
652
|
+
},
|
|
653
|
+
entries: function(array) {
|
|
654
|
+
return entries(apply(array, 0, createMap, setMap), 0);
|
|
655
|
+
},
|
|
656
|
+
key: function(d) {
|
|
657
|
+
keys.push(d);
|
|
658
|
+
return nest;
|
|
659
|
+
},
|
|
660
|
+
sortKeys: function(order) {
|
|
661
|
+
sortKeys[keys.length - 1] = order;
|
|
662
|
+
return nest;
|
|
663
|
+
},
|
|
664
|
+
sortValues: function(order) {
|
|
665
|
+
sortValues = order;
|
|
666
|
+
return nest;
|
|
667
|
+
},
|
|
668
|
+
rollup: function(f) {
|
|
669
|
+
rollup = f;
|
|
670
|
+
return nest;
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function createObject() {
|
|
675
|
+
return {};
|
|
676
|
+
}
|
|
677
|
+
function setObject(object, key, value) {
|
|
678
|
+
object[key] = value;
|
|
679
|
+
}
|
|
680
|
+
function createMap() {
|
|
681
|
+
return map();
|
|
682
|
+
}
|
|
683
|
+
function setMap(map, key, value) {
|
|
684
|
+
map.set(key, value);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
function Set() {}
|
|
688
|
+
var proto = map.prototype;
|
|
689
|
+
Set.prototype = {
|
|
690
|
+
constructor: Set,
|
|
691
|
+
has: proto.has,
|
|
692
|
+
add: function(value) {
|
|
693
|
+
value += "";
|
|
694
|
+
this[prefix + value] = value;
|
|
695
|
+
return this;
|
|
696
|
+
},
|
|
697
|
+
remove: proto.remove,
|
|
698
|
+
clear: proto.clear,
|
|
699
|
+
values: proto.keys,
|
|
700
|
+
size: proto.size,
|
|
701
|
+
empty: proto.empty,
|
|
702
|
+
each: proto.each
|
|
703
|
+
};
|
|
704
|
+
|
|
916
705
|
/**
|
|
917
706
|
@function nest
|
|
918
707
|
@summary Extends the base behavior of d3.nest to allow for multiple depth levels.
|