micsucmed
micsucmed

Reputation: 31

Grouping nested arrays by inner index in D3.js

I am new to D3.js and have read that nesting works when you have an array of objects and group this by one of the keys of these objects.

Is there a way to group my data by the position of the data within the arrays if I have an array of arrays instead of an array of objects ?

My data looks something like this:

[
    [
        50.14352861269181,
        48.590287468781376,
        51.36544052859994,
        51.265280602232096,
        51.660889890343306,
        51.89253163777577,
        53.79770880045476,
        49.214056731713264,
        51.316879464205044,
        47.09919284254052
    ],
    [
        49.20113040284179,
        48.11080607326288,
        53.786172519260134,
        49.50555805166513,
        54.16462155958811,
        51.148344084151155,
        51.83257260255879,
        51.35018450153239,
        51.47051074626946,
        47.65706482740083
    ],
    [
        48.899862343706644,
        47.80971057062669,
        55.108443599961014,
        48.989036802519614,
        55.66890774696284,
        50.386958533218376,
        52.87843386747259,
        52.39402151471223,
        51.6092359734941,
        47.4915639070558
    ],
    [
        49.891282044187506,
        45.29346511364243,
        52.40835440563241,
        50.67290357791945,
        55.365562224487824,
        50.602979524103354,
        54.881624124344626,
        52.02405059118448,
        53.168454779439244,
        44.77453617715855
    ],
    [
        50.39553333333042,
        43.87826289058943,
        51.819149082482674,
        50.9574668994543,
        54.60626411775401,
        48.892139331397935,
        53.524944013637615,
        52.73385561233758,
        53.62074865541904,
        45.981452257915265
    ],
    [
        51.19335695015922,
        43.781771044372086,
        52.11853488405912,
        48.428654893528034,
        52.99695052855934,
        50.0516057469041,
        49.93053707008544,
        55.11683685260799,
        52.901021144887935,
        45.92555879487636
    ],
    [
        51.082656955085575,
        42.97229677200713,
        55.44860184180001,
        51.94085128684821,
        54.046238606912205,
        51.84543204433595,
        48.005579375671175,
        55.993455582290416,
        52.662417746724884,
        44.94783351992743
    ],
]

So all numbers in position 0 of the arrays will be grouped, all numbers in position 1 will be grouped, and so on. Inner arrays will always have the same length.

Upvotes: 3

Views: 323

Answers (2)

Robin Mackenzie
Robin Mackenzie

Reputation: 19289

If you are looking to keep the array-of-arrays structure and flip from a 7x9 to a 9x7 array then you can use d3.transpose:

const data = [[50.14352861269181,48.590287468781376,51.36544052859994,51.265280602232096,51.660889890343306,51.89253163777577,53.79770880045476,49.214056731713264,51.316879464205044,47.09919284254052],[49.20113040284179,48.11080607326288,53.786172519260134,49.50555805166513,54.16462155958811,51.148344084151155,51.83257260255879,51.35018450153239,51.47051074626946,47.65706482740083],[48.899862343706644,47.80971057062669,55.108443599961014,48.989036802519614,55.66890774696284,50.386958533218376,52.87843386747259,52.39402151471223,51.6092359734941,47.4915639070558],[49.891282044187506,45.29346511364243,52.40835440563241,50.67290357791945,55.365562224487824,50.602979524103354,54.881624124344626,52.02405059118448,53.168454779439244,44.77453617715855],[50.39553333333042,43.87826289058943,51.819149082482674,50.9574668994543,54.60626411775401,48.892139331397935,53.524944013637615,52.73385561233758,53.62074865541904,45.981452257915265],[51.19335695015922,43.781771044372086,52.11853488405912,48.428654893528034,52.99695052855934,50.0516057469041,49.93053707008544,55.11683685260799,52.901021144887935,45.92555879487636],[51.082656955085575,42.97229677200713,55.44860184180001,51.94085128684821,54.046238606912205,51.84543204433595,48.005579375671175,55.993455582290416,52.662417746724884,44.94783351992743],];

const transposed = d3.transpose(data);

console.log(transposed);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>

If you then want to group those transposed arrays by the index e.g. all the 0th values are grouped under a key of 0; all the 1st values are grouped under a key of 1 etc then you can just pass the transposed array to d3.group (for a Map) or d3.groups (for a nested array) and use a key function of (d, i) => i to nest:

const data = [[50.14352861269181,48.590287468781376,51.36544052859994,51.265280602232096,51.660889890343306,51.89253163777577,53.79770880045476,49.214056731713264,51.316879464205044,47.09919284254052],[49.20113040284179,48.11080607326288,53.786172519260134,49.50555805166513,54.16462155958811,51.148344084151155,51.83257260255879,51.35018450153239,51.47051074626946,47.65706482740083],[48.899862343706644,47.80971057062669,55.108443599961014,48.989036802519614,55.66890774696284,50.386958533218376,52.87843386747259,52.39402151471223,51.6092359734941,47.4915639070558],[49.891282044187506,45.29346511364243,52.40835440563241,50.67290357791945,55.365562224487824,50.602979524103354,54.881624124344626,52.02405059118448,53.168454779439244,44.77453617715855],[50.39553333333042,43.87826289058943,51.819149082482674,50.9574668994543,54.60626411775401,48.892139331397935,53.524944013637615,52.73385561233758,53.62074865541904,45.981452257915265],[51.19335695015922,43.781771044372086,52.11853488405912,48.428654893528034,52.99695052855934,50.0516057469041,49.93053707008544,55.11683685260799,52.901021144887935,45.92555879487636],[51.082656955085575,42.97229677200713,55.44860184180001,51.94085128684821,54.046238606912205,51.84543204433595,48.005579375671175,55.993455582290416,52.662417746724884,44.94783351992743],];

const grouped = d3.groups(
  d3.transpose(data), 
  (d, i) => i
);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>

Upvotes: 2

Arun AK
Arun AK

Reputation: 4370

Since I am not much familiar with d3.js, I did the solution without using it.

var arr = [
  [
    50.14352861269181,
    48.590287468781376,
    51.36544052859994,
    51.265280602232096,
    51.660889890343306,
    51.89253163777577,
    53.79770880045476,
    49.214056731713264,
    51.316879464205044,
    47.09919284254052
  ],
  [
    49.20113040284179,
    48.11080607326288,
    53.786172519260134,
    49.50555805166513,
    54.16462155958811,
    51.148344084151155,
    51.83257260255879,
    51.35018450153239,
    51.47051074626946,
    47.65706482740083
  ],
  [
    48.899862343706644,
    47.80971057062669,
    55.108443599961014,
    48.989036802519614,
    55.66890774696284,
    50.386958533218376,
    52.87843386747259,
    52.39402151471223,
    51.6092359734941,
    47.4915639070558
  ],
  [
    49.891282044187506,
    45.29346511364243,
    52.40835440563241,
    50.67290357791945,
    55.365562224487824,
    50.602979524103354,
    54.881624124344626,
    52.02405059118448,
    53.168454779439244,
    44.77453617715855
  ],
  [
    50.39553333333042,
    43.87826289058943,
    51.819149082482674,
    50.9574668994543,
    54.60626411775401,
    48.892139331397935,
    53.524944013637615,
    52.73385561233758,
    53.62074865541904,
    45.981452257915265
  ],
  [
    51.19335695015922,
    43.781771044372086,
    52.11853488405912,
    48.428654893528034,
    52.99695052855934,
    50.0516057469041,
    49.93053707008544,
    55.11683685260799,
    52.901021144887935,
    45.92555879487636
  ],
  [
    51.082656955085575,
    42.97229677200713,
    55.44860184180001,
    51.94085128684821,
    54.046238606912205,
    51.84543204433595,
    48.005579375671175,
    55.993455582290416,
    52.662417746724884,
    44.94783351992743
  ],
]

// If the inner array is always equal like u said, you can simply do arr[0].length
const maxLength = arr.map(a => a.length).indexOf(Math.max(...arr.map(a => a.length)));

const newGroup = Array.apply(null, new Array(5)).map(_ => [])

newGroup.map((item, index) => arr.forEach(list => item.push(list[index])))
console.log(newGroup)

Happy Coding !!!

Upvotes: 0

Related Questions