Dynamic cards and push to array question

Question for .js masters, dynamically I am building cards on the frontend and that’s not a problem. I got stuck when I want to push data to array. I am pulling a list of visible cards ‘risk1, zone1’ from visibleColumnCards and then I iterate ‘datatableData’ and pushing (‘risk1 and zone1’) data values to array.

Problem is that in dtFilteredCard ‘risk1 and zone1’ values are combined, what I would like to do is to access values e.g. dtFilteredCard[0] (risk1), dtFiltered[1] (zone1). And to conclude there is always a simple solution, but damn I can’t figure it out.

Thank you in advance!

  cardsConfig = [];
  let dtFilteredCard = [];
  let sortedValuesCard = [];

  visibleColumnCards.forEach(function (colValue, colKey) {
    cardData = colValue.data; //risk1, zone1

    datatableData.forEach(function (dtValue, dtKey) {
      let newValue = { name: dtValue.customerIdentifier, y: Number(dtValue[cardData]) };
      dtFilteredCard.push(newValue);
    });

    sortedValuesCard = dtFilteredCard.sort((a, b) => b["y"] - a["y"]).slice(0, 5);

    cardsConfig.push({
      id: colKey,
      countUpContainer: "cu-" + colKey,
      title: colValue.card_title,
      hcContainer: "hc-container-card-" + colKey,
      hcData: sortedValuesCard,
      hcHeight: "130px",
      hcUnit: "%",
      hcLegend: false,
    });

  });

not realy clear what are you trying to do

let visibleColumnCards = [
  { data: 'risk1', card_title: 'risk1Title' },
  { data: 'zone1', card_title: 'zone1Title' }
];

let datatableData = [
  { customerIdentifier: 'cusID1', risk1: '3', zone1: '4' },
  { customerIdentifier: 'cusID2', risk1: '2', zone1: '1' }
];
let cardsConfig = visibleColumnCards
  .map((i,x) => ({...i, ID: ++x }))
  .map(i => ({...i,
    title: i.card_title,
    hcUnit: '%',
    hcLegend: false,
    hcHeight: '130px',
    countUpContainer: 'cu-'+i.ID,
    hcContainer: 'hc-container-card-'+i.ID,
    hcData: datatableData
      .map(j => ({
        key: i.data,
        y: Number(j[i.data]),
        name: j.customerIdentifier
      }))
      .sort((a,b) => a.y - b.y)
      .filter((_,x) => x < 5)
  }));

console.log(JSON.stringify(cardsConfig,null,2));
  {
    "data": "risk1",
    "card_title": "risk1Title",
    "ID": 1,
    "title": "risk1Title",
    "hcUnit": "%",
    "hcLegend": false,
    "hcHeight": "130px",
    "countUpContainer": "cu-1",
    "hcContainer": "hc-container-card-1",
    "hcData": [
      {
        "key": "risk1",
        "y": 2,
        "name": "cusID2"
      },
      {
        "key": "risk1",
        "y": 3,
        "name": "cusID1"
      }
    ]
  },
  {
    "data": "zone1",
    "card_title": "zone1Title",
    "ID": 2,
    "title": "zone1Title",
    "hcUnit": "%",
    "hcLegend": false,
    "hcHeight": "130px",
    "countUpContainer": "cu-2",
    "hcContainer": "hc-container-card-2",
    "hcData": [
      {
        "key": "zone1",
        "y": 1,
        "name": "cusID2"
      },
      {
        "key": "zone1",
        "y": 4,
        "name": "cusID1"
      }
    ]
  }

Hi deejay, thank for your reply! I was maybe unclear with my explanation but here is in short what I want to achieve, I can get ‘riskScore’ and ‘zone’ from ‘visibleColumnCards’ also I can push ‘newValue’ to dtFilteredCard from datatableData, but the output isn’t what I am looking for,

visibleColumnCards.forEach(function (colValue, colKey) {
  cardData = colValue.data;
  cardData =  ['riskScore', 'zone'] //output

  datatableData.forEach(function (dtValue, dtKey) {
      if (dtValue[cardData]) {
        let newValue = { name: dtValue.customerIdentifier, y: Number(dtValue[cardData]) };
        dtFilteredCard.push(newValue);
      }
  });
})

then dtFilteredCard output looks like this:

0: {name: 'Pannier', y: 84} //riskScore
1: {name: 'Wrapsafe', y: 65} //riskScore
2: {name: 'Holdlamis', y: 46} //riskScore
3: {name: 'Pannier', y: 0.8} //zone
4: {name: 'Wrapsafe', y: 0.5} //zone
5: {name: 'Holdlamis', y: 0.6} //zone

what I am looking for is array like this:

0: "riskScore",
  0: {name: 'Pannier', y: 84} //riskScore
  1: {name: 'Wrapsafe', y: 65} //riskScore
  2: {name: 'Holdlamis', y: 46} //riskScore
1: "zone",
  0: {name: 'Pannier', y: 0.8} //zone
  1: {name: 'Wrapsafe', y: 0.5} //zone
  2: {name: 'Holdlamis', y: 0.6} //zone
let visibleColumnCards = [{ data: 'riskScore' },{ data: 'zone' }];
  
let datatableData = [
  { customerIdentifier: 'Pannier', riskScore: '84', zone: '0.8' },
  { customerIdentifier: 'Wrapsafe', riskScore: '65', zone: '0.5' },
  { customerIdentifier: 'Holdlamis', riskScore: '46', zone: '0.6' }
];
let array = visibleColumnCards.map(i => ({
  [i.data]: datatableData.map(j => ({
    name: j.customerIdentifier,
    y: j[i.data]
  })).sort((a,b) => a.y - b.y)
}));

console.log(JSON.stringify(array,null,2));
[
  {
    "riskScore": [
      { "name": "Holdlamis", "y": "46" },
      { "name": "Wrapsafe", "y": "65" },
      { "name": "Pannier", "y": "84" }
    ]
  },
  {
    "zone": [
      { "name": "Wrapsafe", "y": "0.5" },
      { "name": "Holdlamis", "y": "0.6" },
      { "name": "Pannier", "y": "0.8" }
    ]
  }
]
let object = visibleColumnCards.map(i => ({
  [i.data]: datatableData.map(j => ({
    name: j.customerIdentifier,
    y: j[i.data]
  })).sort((a,b) => a.y - b.y)
})).reduce((a,b) => Object.assign(a,b),{});

console.log(JSON.stringify(object,null,2));
{
  "riskScore": [
    { "name": "Holdlamis", "y": "46" },
    { "name": "Wrapsafe", "y": "65" },
    { "name": "Pannier", "y": "84" }
  ],
  "zone": [
    { "name": "Wrapsafe", "y": "0.5" },
    { "name": "Holdlamis", "y": "0.6" },
    { "name": "Pannier", "y": "0.8" }
  ]
}

WOW! That’s amazing!! I used ‘object’ one, I know you’re going to kill me. In ‘visibleColumnCards’ I added field ‘title’, what’s the easiest way to add ‘title’ value in ‘cardsConfig’? Btw. I owe you a beer!!! maybe two :wink:

let visibleColumnCards = [{ data: 'riskScore', title: 'Highest Risk' },{ data: 'zone', title: 'Highest Zone' }];          
    
let obj = visibleColumnCards
    .map((i) => ({
      [i.data]: datatableData
        .map((j) => ({
          name: j.customerIdentifier,
          y: Number(j[i.data]),
        }))
        .sort((a, b) => b.y - a.y)
        .slice(0, 5),
    }))
    .reduce((a, b) => Object.assign(a, b), {});

  cardsConfig = [];

  Object.entries(obj).forEach(([key, value]) => {
    cardsConfig.push({
      id: key,
      countUpContainer: "cu-" + key,
      countUpValue: value[0].y,
      title: "",
      hcContainer: "hc-container-card-" + key,
      hcData: value,
      hcHeight: "130px",
      hcUnit: "%",
      hcLegend: false,
    });
  });
let visibleColumnCards = [
  { title: 'Highest Risk', data: 'riskScore' },
  { title: 'Highest Zone', data: 'zone' }
];

let datatableData = [
  { customerIdentifier: 'Pannier', riskScore: '84', zone: '0.8' },
  { customerIdentifier: 'Wrapsafe', riskScore: '65', zone: '0.5' },
  { customerIdentifier: 'Holdlamis', riskScore: '46', zone: '0.6' }
];

let struct = {
  id: null,
  title: null,
  hcData: [],
  hcUnit: '%',
  hcLegend: false,
  hcHeight: '130px',
  hcContainer: 'hc-container-card-',
  countUpContainer: 'cu-',
  countUpValue: 0,
  maxData: 5
};
let cardsConfig = visibleColumnCards
  .map(i => ({ ...struct, ...i }))
  .map(i => ({ ...i, id: i.data,
    hcContainer: i.hcContainer.concat(i.data),
    countUpContainer: i.countUpContainer.concat(i.data),
    hcData: datatableData.map(j => ({
      name: j.customerIdentifier, y: j[i.data]
    })).sort((a,b) => b.y - a.y).filter((_,x) => x < i.maxData)
  })).map(i => ({ ...i,
    countUpValue: Math.max(...i.hcData.map(i => i.y),i.countUpValue)
  }));
   
console.log(JSON.stringify(cardsConfig,null,2))
[
  {
    "id": "riskScore",
    "title": "Highest Risk",
    "hcData": [
      { "y": "84", "name": "Pannier" },
      { "y": "65", "name": "Wrapsafe" },
      { "y": "46", "name": "Holdlamis" }
    ],
    "hcUnit": "%",
    "hcLegend": false,
    "hcHeight": "130px",
    "hcContainer": "hc-container-card-riskScore",
    "countUpContainer": "cu-riskScore",
    "countUpValue": 84,
    "maxData": 5,
    "data": "riskScore"
  },
  {
    "id": "zone",
    "title": "Highest Zone",
    "hcData": [
      { "y": "0.8", "name": "Pannier" },
      { "y": "0.6", "name": "Holdlamis" },
      { "y": "0.5", "name": "Wrapsafe" }
    ],
    "hcUnit": "%",
    "hcLegend": false,
    "hcHeight": "130px",
    "hcContainer": "hc-container-card-zone",
    "countUpContainer": "cu-zone",
    "countUpValue": 0.8,
    "maxData": 5,
    "data": "zone"
  }
]

if you want the result as obj:

let cardsConfig = visibleColumnCards
  .map(i => ({ ...struct, ...i }))
  .map(i => ({ ...i, id: i.data,
    hcContainer: i.hcContainer.concat(i.data),
    countUpContainer: i.countUpContainer.concat(i.data),
    hcData: datatableData.map(j => ({
      name: j.customerIdentifier, y: j[i.data]
    })).sort((a,b) => b.y - a.y).filter((_,x) => x < i.maxData)
  })).map(i => ({
    ...i, countUpValue: Math.max(...i.hcData.map(i => i.y),i.countUpValue)
  })).reduce((a,b) => ({ ...a, [b.data]: b }),{});


console.log(JSON.stringify(cardsConfig,null,2))
{
  "riskScore": {
    "id": "riskScore",
    "title": "Highest Risk",
    "hcData": [
      { "y": "84", "name": "Pannier" },
      { "y": "65", "name": "Wrapsafe" },
      { "y": "46", "name": "Holdlamis" }
    ],
    "hcUnit": "%",
    "hcLegend": false,
    "hcHeight": "130px",
    "hcContainer": "hc-container-card-riskScore",
    "countUpContainer": "cu-riskScore",
    "countUpValue": 84,
    "maxData": 5,
    "data": "riskScore"
  },
  "zone": {
    "id": "zone",
    "title": "Highest Zone",
    "hcData": [
      { "y": "0.8", "name": "Pannier" },
      { "y": "0.6", "name": "Holdlamis" },
      { "y": "0.5", "name": "Wrapsafe" }
    ],
    "hcUnit": "%",
    "hcLegend": false,
    "hcHeight": "130px",
    "hcContainer": "hc-container-card-zone",
    "countUpContainer": "cu-zone",
    "countUpValue": 0.8,
    "maxData": 5,
    "data": "zone"
  }
}
1 Like

Deejay, huuuge ‘thanks’ for your .js help/advice, now I know how little I know :slight_smile:

P.S. ‘Last night a DJ saved my life’, I’ll be playing all day long :wink:

alternative way to get the highest Value

let cardsConfig = visibleColumnCards
  .map(i => ({ ...struct, ...i }))
  .map(i => ({ ...i, id: i.data,
    hcContainer: i.hcContainer.concat(i.data),
    countUpContainer: i.countUpContainer.concat(i.data),
    // remove this line
  //hcData: datatableData.map(j => ({
    hcData: datatableData.map((j,_,a) => ({
      name: j.customerIdentifier,
      y: j[i.data],
      // add high: bool
      high: j[i.data] == Math.max(...a.map(v => v[i.data]),0)
    })).sort((a,b) => b.y - a.y).filter((_,x) => x < i.maxData)
  }))
  .map(i => ({
    ...i, // get highest obj
    highestValue: Object.assign({},i.hcData.find(i => i.high)),
    countUpValue: Math.max(...i.hcData.map(i => i.y),i.countUpValue)
  }))
  .reduce((a,b) => ({ ...a, [b.data]: b }),{});

console.log(cardsConfig.zone.highestValue.y); // => 0.8
console.log(cardsConfig.riskScore.highestValue.name); //=> Pannier