🏠 back to Observable

Javascript Map objects


#1

Are there any examples of creating a visualization using javascript’s Map objects?

I like some of Mike’s data analysis notebooks which use them, but I’m not sure how or if I can input Map objects into a viz. Do I need to convert back to a traditional array of objects first? I’m working with nested objects. Any pointers or examples would be appreciated! Cheers


#2

If you’re talking about making visualizations in d3, note that you can’t directly bind data to a Map object with .data() since that function really expects an Array object there. You can convert a Map m to an array using Array.from(m) or by doing something like this:

const a = [];
m.forEach([val, key] => {
  a.push(val);
});

If you’re making graphics “by hand” (e.g. by drawing in a canvas with context2d), then you can iterate over the key-value pairs in a Map using for ... of.

Maps are basically just “key-value stores” and they’re primarily used when there’s a need to associate data or functions to specific keys for later retrieval. For instance, they’re frequently used to cache results of a computation / fetch operation for later use.

Could you say a bit more about what kinds of examples you’re looking for? Most of the time that I’ve used Map objects it’s for general programming needs (e.g. a the data generation or preprocessing step), rather than something I turn to when it comes time to make visualizations.


#3

I see. Well I was going through some of Mike’s data analysis examples, particularly the ‘group’ examples which involve using map objects. For what I need I can use d3.nest. I was just curious why for these grouping examples seemed to be promoting map objects. I’ve moved over from R recently and would like to do all my wrangling and analysis in javascript :). thanks for your response!


#4

I’ll add support for iterables (including Map) in the next major version of d3-selection. Until then I recommend Array.from.


#5

Cool! I hadn’t seen these notebooks before. Map objects are well-suited for use there because the “grouping” operation is exactly the operation of associating data to keys; the MDN page you linked explains some of the advantages of using them over ordinary JS objects.

Browsing a little bit, it seems like those notebooks were in fact written to explore a possible future addition to d3 that uses the Map objects, see this tweet which links an earlier version. That’s probably the most direct answer to the question of why the notebooks are “promoting map objects”.


#6

Here are some more examples of the new d3-array (which will be part of d3 v6):


#7

I’m trying using the array.from method selected, basically iterating through the levels of the nested map, after using d3.rollup, but that seems tedious (requiring several levels of iteration) compared to using d3.nest… so I don’t see why this is the route I should go :slight_smile:.

Here’s a notebook where I’m experimenting with these techniques.

Surely there must be a better way to convert the nested map object. Any pointers would be greatly appreciated.


#8

It’s possible to convert the nested map to a nested plain object with a recursive function (code at the end of this post), but as you say, there’s no point in doing this if you just want the output of d3.nest.

Here’s a question: is it possible that the code that requires a nested object would somehow benefit from using nested maps instead?

function mapToObj(map) {
  if (map instanceof Map) {
    return Array.from(map).map(([key, val]) => ({name:key, children:mapToObj(val)}));
  }
  return map;
}

Edit: that doesn’t wrap the outermost layer, so use it like this, I guess:

dat = ({name:"moluscs", children:mapToObj(mapped)})

#9

Here are some ways to make your code less verbose and possibly allow you to spot/extract reusable parts (edit: removed some leftovers in longData, be sure to reload):


#10

Oops, had “class” twice in hierarchy - fixed. Let me know if you have any questions!


#11

Wow, that’s very helpful! There’s obviously a few things I need to learn here. I’ll comb through this carefully. thanks!


#12

Thanks so much for this! Likewise, I need to go through this carefully and learn from it. I will let you know if I have any questions :wink: Thanks again.