J'ai imbriqué des données JSON où le premier niveau de clés correspond aux types d'activité (balade, randonnée, etc.) et le deuxième niveau est l'année. Chaque année a une valeur (distance en kilomètres).
Ma structure de données ressemble à ceci:
Je souhaite dessiner un histogramme empilé comme celui-ci http://bl.ocks.org/mstanaland / 6100713 à partir de mes données. Comment puis-je amener mes données dans une structure qui convient à un histogramme empilé D3?
3 Réponses :
Cela pourrait être fait comme suit:
const data = []; myData.forEach(a => a.values.forEach(v => { const element = data.find(e => e.year === v.key); if (element) { element[a.key] = v.values; } else { data.push({ year: v.key, [a.key]: v.values }); } }));
a publié une réponse pour aligner toutes les propriétés une fois que les données sont poussées pour la première fois, je crois également que cela nécessiterait un tri pour que le graphique fonctionne ...
Cela fonctionne bien, mais lorsqu'il manque des combinaisons, aucune entrée n'est faite, donc ce ne sont pas de vraies données larges. Je l'ai réalisé avec ce code:
// make data long var flatdata = [] distance_per_year.forEach(function(type) { type.values.forEach(function(typeYears) { flatdata.push({ type: type.key, year: typeYears.key, distance: typeYears.values, }); }); }); // Unique activity types groups = Array.from(new Set(flatdata.map(({ type }) => type))); years = Array.from(new Set(flatdata.map(({ year }) => year))); // make wide data with 0 where value is missing var grouped = years.map(function(d) { var item = { year: d }; groups.forEach(function(e) { var itemForGroup = flatdata.filter(function(f) { return f.type === e && f.year === d; }); if (itemForGroup.length) { item[e] = Number(itemForGroup[0].distance); } else { item[e] = 0; } }) return item; })
Cela produit d'abord un ensemble de données long non imbriqué (3 colonnes), puis le remodèle en large et remplit des 0 là où la distance est manquante.
La source sont ces deux questions: Remodeler les données pour le graphique à barres empilées D3 a> et d3: aplatir les données imbriquées?
p >
Basé sur la réponse de @ unminder mais juste pour obtenir chaque propriété dans l'objet:
Exemple de Stakblitz: https://stackblitz.com/edit/js-d5sitf
const entryArr = [ { key: 'ride', values: [ { key: '2008', value: 3234 }, { key: '2009', value: 3234 }, { key: '2010', value: 5000 }, { key: '2011', value: 6000 }, { key: '2012', value: 1456 }, { key: '2013', value: 2453 } ] }, { key: 'hike', values: [ { key: '2006', value: 3234 }, { key: '2009', value: 2420 }, { key: '2010', value: 4530 }, { key: '2011', value: 2000 }, { key: '2012', value: 1900 }, { key: '2013', value: 3700 } ] }, { key: 'walk', values: [ { key: '2009', value: 3001 }, { key: '2010', value: 1090 }, { key: '2011', value: 2020 }, { key: '2012', value: 2000 }, { key: '2013', value: 6000 } ] } ]; const getKeys = entryArr.map(x => x.key); const result = []; entryArr.forEach(a => a.values.forEach(v => { const element = result.find(e => e.year === v.key); if (element) { element[a.key] = v.value; } else { const obj = getKeys.reduce((acc, x) => ({ ...acc, year: v.key, [x]: a.key === x ? v.value : '' }) , {}); result.push(obj); } })); console.log(result)
Remarque: il peut être amélioré en utilisant des réducteurs pour éviter les variables globales
p>
pouvez-vous s'il vous plaît ajouter le json afin qu'il puisse être copié pour des tests plus faciles ..