d3 / d3-collection Goto Github PK
View Code? Open in Web Editor NEWHandy data structures for elements keyed by string.
License: BSD 3-Clause "New" or "Revised" License
Handy data structures for elements keyed by string.
License: BSD 3-Clause "New" or "Revised" License
Maybe I get this wrong but why does the rollup function creates an object with the key "value". I expected "values". Is this wanted behaviour ?
And how can I get "values" as key ?
https://jsfiddle.net/niekes/u6h4summ/1/
Deleted request until I have a POC which actually works.
nest hardcodes key
and values
. If not too difficult, please support custom field names, as this would make this Vega's issue much easier to solve. Thanks!
BTW, I think this has benefit to other users because it simplifies result examination in case when original data also contains key
or values
fields, and the caller needs to find which objects were generated.
Hi there 👋
We're long time users of d3 and recently looked at upgrading from d3 v3.5.8.
C3 have bumped their dependency on this project so we're wanting to make use of the latest d3 if we're going to update.
One thing I noticed right away is that since quite a while ago you introduced a prefix to keys when using d3.map;
https://github.com/d3/d3-collection/blame/5aad1d67f264c0b3b6a9f3e9833021497f03beeb/src/map.js#L1
Some very common code from us might look like the following;
let nestedData = d3.nest()
.key((b) => b["Name"])
.rollup((b) => {
// return some aggregation on buckets of data by name
})
.map(data);
let names = Object.keys(nestedData);
So now in getting all of the unique "Name" elements we now get, for example ["$David", "$Jason"]
if that makes sense, instead of ["David", "Jason"]
.
Now I'm not saying there's anything wrong with this, I imagine this update was part of a breaking change version bump, I'm just curious as to the reasoning?
Also I noticed that you export the prefix, did you have a snippet of code as an example of setting the prefix to nothing, if that's possible?
Sometimes it's necessary to sort keys differently. Currently, only one sort is applied to all keys. I'm thinking the key
function could accept an optional sort function:
d3.nest()
.key(d => d.region, d3.ascending)
.key(d => d.country, d3.descending)
.entries(data)
Would be very useful for something like a pivot table.
See this interactive notebook to display problem
Suppose we have dataset like this
var arr = [
{name: "jim", amount: "34.0", date: "11/12/2015"},
{name: "carl", amount: "120.11", date: "11/12/2015"},
{name: "stacy", amount: "12.01", date: "01/04/2016"},
{name: "stacy", amount: "34.05", date: "01/04/2016"}
]
Would be good if we have possibility to nest by multiple key at one level
So, if we would try
expensesByNameAndDate = d3.nest()
.keys(["name","date"]) // keys , not key
.entries(expenses)
We would get
[
{
"key": { "name": "jim","date": "11/12/2015"},
"values": [{"name": "jim","amount": "34.0","date": "11/12/2015"}]
},
{ "key": {"name": "carl","date": "11/12/2015"},
"values": [{"name": "carl","amount": "120.11","date": "11/12/2015"}]
},
{ "key": {"name": "stacy","date": "01/04/2016"},
"values": [{"name": "stacy","amount": "12.01","date": "01/04/2016"},{"name": "stacy","amount": "34.05","date": "01/04/2016"}]
}
]
Possible overloads for keys func
.keys(["name","date"])
.keys([d=>d.name,d=>d.date])
The current definition obliterates the constructor
property.
I think that there's should be an example on the Readme for how to import the library using the es6 import syntax. E.g., neither of these syntaxes works:
import d3 from "d3-collection"; // Doesn't work
import { d3 } from "d3-collection"; // Doesn't work either
There's no error given but the d3
variable is always undefined.
After some hunting around, I finally found a syntax that does work :
import * as d3 from "d3-collection"; // does work
but this was far from obvious, for me at least!
I tried to call sortValues after rollup and it didn't work. Looking at the code it seems to me that is not possible in the way it was implemented, i think that it would be good, so we could group some objects and then summarize some values with rollup by group and order the groups by this value. I know it could be done with Array.sort, but anyway, i think that would be nice to do it with sortValues.
Its difficult to understand why rollup should strip leaf node properties, when there are all kinds of reasons those properties might be desired for viz/labelling. etc once the nest is fed to d3.hierarchy. I understand that I can have rollup deliver back an object rather than a single value but 1) that is laborous and idiosyncratic to the data set and 2) d3.hierarchy then finds 0/undefined in the "value" property for non leaf nodes.
Maybe stratify handles this better, but in my environment its not feasible to ask my non-viz counterparts to keep a bunch of dead/non-functional rows in their data so stratify can find them.
Can there be a way to for rollup to retain leaf properties in the nest?
Sometimes it’s convenient to group an array by a single key. You can do that using d3.nest like so:
var entries = d3.nest()
.key(d => d.foo)
.entries(data);
Is it worth making a convenience function for this?
d3.group = function(array, key) {
return d3.nest().key(key).entries(array);
};
I guess it would violate the parsimony principle.
Since plucking off a single property is likely a very common use case, it would be nice to support simply passing a string so that d3.set(stuff, 'name')
would be equivalent to d3.set(stuff, x => x.name)
.
I'd be happy to submit a PR if this is a feature you'd accept.
Using d3.nest to aggregate a dataset by date. My code:
vis.nestData = d3.nest()
.key(function(d){ return d.survey; })
.rollup(function(leaves){ return leaves.length; })
.entries(vis.data);
vis.nestData.forEach(function(d){
d.key = new Date(d.key);
})
vis.data
has field survey
as JS Date objects. Upon return, the keys become strings, NOT Date objects. The second call is needed to reformat them into dates. Somewhere in the nest call they are converted to strings.
What would d3-collection look like if we dropped the d3.map and d3.set implementations? You might still want a d3.map with a key accessor for constructing a Map from an array of data (the key would default to index if not specified, and perhaps #10 you’d also allow an optional value accessor), and a d3.set with an optional accessor.
As in d3.map(array, key, value):
var rateById = d3.map(data, d => d.id, d => d.rate);
rateById.get("01001"); // 0.053
Copied from d3/d3-array#10:
Related d3/d3#1091, it might be nice if there were an easy way to count the number of elements matched at each level of the hierarchy. Yes, things like the cluster layout do that for you already, but it’d be nice to do that with a simple nest operator, too.
This feels slightly related to the nest.rollup method, too. Like, instead of replacing the set of nested values with the return value of the rollup function, I just want to decorate the object (say by assigning a count value). But another big difference is that rollup only operates on arrays of siblings, and nest.count should be a recursive operation on the entire tree.
So… it’s almost like you want tree visit methods on the returned nest object. Which makes me wonder if there should be a nest.tree method instead of nest.map, and then have some useful methods on the returned tree instance.
This makes it easier to disambiguate leaf nodes from parent nodes.
Copied from d3/d3-array#31:
What if d3.nest returned an empty nest object, on which you can define some keys (which would nest existing values, if any), and then you added objects to the nest object and they were automatically slotted into the correct position? Perhaps you could remove objects, too. It’s not clear how nest.rollup would work in this context, though.
Currently nest.sortKeys(comparator)
only sorts keys as strings.
It seems like this often won't give the desired behaviour. For instance it will fail on dates and numbers with more than one digit.
Example code:
const nest = d3.nest()
.key(d=> d.date)
.sortKeys(d3.descending)
.entries(itemsWithDates)
Full running example:
http://bl.ocks.org/gunn/49919c316ebea97d56c31955a607f11f
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.