angular - d3 - skapa uppslag med nest/group


Med hjälp av d3.js-biblioteket ville jag skapa en uppslagning som följer:

var lookup = d3.nest()
  .key((d: any) => d.day)
  .rollup((leaves: any) => {
    return d3.sum(leaves, (d: any) => { return parseInt(d.count); }) as any;
  })
  .object(dateData);

Så att jag kan använda det senare:

rect.filter(function (d) { return d in lookup; })
  .style("fill", function (d) { return d3.interpolatePuBu(scale(lookup[d])); })
  .select("title")
  .text((d) => this.titleFormat(new Date(d)) + ":  " + lookup[d]);

Tyvärr har detta orsakat en:

"export 'nest' (imported as 'd3') was not found in 'd3'

Efter mycket sökande upptäckte jag att i v4 av d3, som jag använder, ersattes nest med group. Nu kan jag inte hitta något i dokumentationen och jag försökte uppnå något liknande med:

var lookup = d3.group(data, (d: any) => d.day)
  .rollup((leaves: any) => {
    return d3.sum(leaves, (d: any) => { return parseInt(d.count); }) as any;
  })
  .object(dateData);

Men detta verkar inte ens kompileras. Hur skulle jag gå till väga för att uppnå det jag försöker göra?

Svar #1

Så din fråga är hur man får ett resultat liknande det nedan, men i d3 v4.

var dateData = [
  { day: 1, count: 2 },
  { day: 1, count: 3 },
  { day: 1, count: 4 },
  { day: 2, count: 2 },
  { day: 4, count: 1 },
  { day: 5, count: 0 },
];
var lookup = d3.nest()
  .key((d) => d.day)
  .rollup((leaves) => d3.sum(leaves, (d) => parseInt(d.count)))
  .entries(dateData);
console.log(lookup);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

Observera att det finns en helt okej lösning som endast använder ES6:

var dateData = [
  { day: 1, count: 2 },
  { day: 1, count: 3 },
  { day: 1, count: 4 },
  { day: 2, count: 2 },
  { day: 4, count: 1 },
  { day: 5, count: 0 },
];

// First, map it to a { [day]: [sum counts] } structure
// { "1": 9, "2": 2, "4": 1, "5": 0 }
var lookup = dateData.reduce((obj, { day, count }) => {
    // || 0 means that if the value is undefined, it will use 0 instead
    obj[day] = (obj[day] || 0) + parseInt(count);
    return obj;
  }, {});

// Secondly (if you want), map it to a the same structure as the v3 example
lookup = Object.entries(lookup)
  .map(([key, values]) => ({ key, values }));

console.log(lookup);

Relaterade artiklar