Generate JSON key-value pairs by nesting them in D3

Looking to convert a JSON into key-value pairs using d3.nest().

The initial JSON structure is as follows:

[
{
    "Country": "Mexico", 
    "Climate": 100,
    "Safety Index": 50,
    "Life Expectancy": 80,
    "Corruption": 30,
    "Per Capita Income": 20
},
{
    "Country": "UK",
    "Climate": 70,
    "Safety Index": 80,
    "Life Expectancy": 70,
    "Corruption": 70,
    "Per Capita Income": 80
},
{
    "Country": "US",
    "Climate": 80,
    "Safety Index": 70,
    "Life Expectancy": 90,
    "Corruption": 70,
    "Per Capita Income": 80
}
]

The desired output format should be:

[
{"key": "Mexico", "value":
    [ 
        { "key": "Climate", "value": 100 },
        { "key": "Safety Index", "value": 50 },
        { "key": "Life Expectancy", "value": 80 },
        { "key": "Corruption", "value": 30 },
        { "key": "Per Capita Income", "value": 20 }
    ]},
{"key": "UK", "value":
    [ 
        { "key": "Climate", "value": 70 },
        { "key": "Safety Index", "value": 80 },
        { "key": "Life Expectancy", "value": 70 },
        { "key": "Corruption", "value": 70 },
        { "key": "Per Capita Income", "value": 80 }
    ]},
{"key": "US", "value":
    [ 
        { "key": "Climate", "value": 80 },
        { "key": "Safety Index", "value": 70 },
        { "key": "Life Expectancy", "value": 90 },
        { "key": "Corruption", "value": 70 },
        { "key": "Per Capita Income", "value": 80 }
    ]}
    ]

Here's the code snippet I've tried:

var nest = d3.nest()
             .key(function(d) { return d.Country; })
             .entries(data);

I am new to D3 and seeking guidance on restructuring the JSON data.

UPDATE

The end goal is to create individual bar charts per country based on different categories, similar to this example: http://bl.ocks.org/mbostock/5872848. Any suggestions for a more efficient approach are welcome.

Answer №1

If you are looking for an exact replication of the provided output and prefer to use nesting, you can implement the following code snippet:

var nest = d3.nest()
         .key(function(data) { return data.Country; })
         .rollup(function(data) {
              var groupedObject = data[0];
              return d3.nest()
                       .key(function(innerKey) { return innerKey; })
                       .rollup(function(innerKey) { return groupedObject[innerKey]; })
                       .entries(Object.keys(groupedObject));
          })
         .entries(dataset);

One possible concern is that the assumption is made that each country will have a unique entry (e.g. no duplicate "Mexico" entries). Therefore, the inner nest only works on data[0] (which represents the first item for a specific country).

Edit: However, this solution doesn't precisely match your initial requirements as the country key-value pair is included in the nested grouping. To address this issue, you can exclude it by adding the following line before the inner nest: delete groupedObject.Country;

Edit 2: While the above code utilizes nested nest functions based on the question's specifications, in practical applications, utilizing pure JavaScript for the inner nest function seems more reasonable. Here is an alternative approach:

function getParameters(countryData){
    return Object.keys(countryData)
                   .filter(function(key){ return key !== "Country"; })
                   .map(function(key){ return { key: key, value: countryData[key] }; })
}

Answer №2

Check out this alternative solution that doesn't involve D3:

let originalArray = ...; // Array of JSON data
let newArray = [];
originalArray.forEach(function(item) {
    let newObj = {};
    newObj.key = item.Country;
    newObj.value = [];
    for (let key in item) {
        if (key === "Country") { continue; }
        newObj.value.push({"key": key, "value": item[key]});
    }
    newArray.push(newObj);
});

I'm curious about the use of only "key" and "value" as keys in your new object structure. It seems to diverge from the usual implicit keys and values concept of JSON. But I trust you have a specific reason behind this approach.

Answer №3

Your statement:

If there is a more efficient approach to consider, please share.

When modifying your data structure, why not transform it into the following format?

[
    ["Brazil", 90, 60, 70, 40, 30],
    ["Germany", 80, 90, 80, 80, 90],
    ["China", 85, 75, 95, 75, 85],
]

This version is compact and does not have any unnecessary repetitions.

If you aim to closely match the code example's data structure, I suggest maintaining your original data structure. This is because the JSON file resulting from the CSV conversion aligns closely with your existing JSON format.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transform an array into an object, organizing values according to their even or odd index positions

I need help converting an array into an object where the keys are based on whether the index of the array is odd or even. For example: Input: ["name", "Tom", "age", 20] Output: {"name": "Tom", "age": 20} I know this can be achieved using basic JavaSc ...

The concept of recursively exporting modules in Node.js modules

Looking for a way to recursively export all .hbs files in a NodeJS 14+ project main JS. I attempted the following: module.exports = () => ({ partial : __dirname + "/../partial/**.hbs", helper : __dirname + "/../helper/*.js" } ...

Display images that have been uploaded on the page either as a grid view or a list of

In my Reactjs application, I am uploading multiple images to Azure Blob Storage. On a page, there is a button to open the upload form. Once the upload completes, I want to display all these images on the same page. Since the images have different aspect ...

Ways to dynamically manipulate HTML elements in Angular 5

Recently, I've been attempting to programmatically transform an HTML element. Strangely, when I update the transform value in the console tab, it changes successfully, but for some reason it doesn't reflect in the element tab of the browser. onD ...

Developing a Navigation Bar Menu using JSON data and the power of Lodash

Seeking advice to enhance my code for creating a navbar menu from JSON data. Any suggestions on how to avoid calling getItems multiple times? Appreciate any feedback, thank you! var _ = require('lodash'); let menuConfig = [ { ID: 1 ...

An error occurs when attempting to upload an image in cropper js due to a violation of the Content Security Policy directive: "img-src * data:"

I'm currently using cropperjs to crop an image upon uploading click here to see the button Once the image is selected for upload, I encounter this problem The data in blob storage remains intact, but there seems to be an issue after the image is upl ...

Transforming the data retrieved from the API into a well-organized object in Vue.js

Currently, I am utilizing the vue-meta library to incorporate meta tags into my Vue project. What I'm attempting to do now is populate my meta tags using the API response data. Here's an example output from the API when I log 'response.data. ...

In the Android Chrome browser, the settings of the meta viewport attribute do not take effect when the device is in full screen mode

While using the fullscreen api in Android, I noticed that the values of meta viewport attributes like initial-scale and user-scalable are not reflected in the browser when in full screen mode. However, when not in full screen mode, these values work as exp ...

Loop through the CSS classes and add a number to the end of each class using JavaScript

I need to configure a form in SharePoint 2010 where certain fields are conditionally required. I have managed to set this up, but now I want a visual indicator on the form to show which fields are required. Not Required: field Required: field* My curren ...

Different ways to make jQuery attr() method include the attribute by using single quotation marks

I start by creating a div in memory: var video_div = document.createElement('div'); video_div.className = "vidinfo-inline"; Next, I define some variables: var key = "data-video-srcs"; var value = '{"video1":"http://www.youtube.com/watch?v ...

In Firefox, the Ajax Call is failing to initiate a response automatically

I am currently working on developing a dynamically generated accordion with nested subaccordions. A filter function has been successfully implemented to manipulate the content on the page using Ajax. In order to achieve this, the following function has bee ...

Updating Content Dynamically with AJAX, JavaScript, and PHP without requiring a page reload or user action

Currently, I'm delving into the world of JS/AJAX functions that operate without the need for a page refresh or button click. However, I've encountered an issue when trying to echo the value. Oddly enough, when I change this line $email = $_POST ...

Is there a way to incorporate the load page plugin specifically for JavaScript while ensuring that my PHP code is still functional?

Is there a way to implement the loading page plugin "PACE" for PHP code execution instead of just JavaScript? I am more comfortable with PHP, CSS, and HTML, but not very experienced in JavaScript/AJAX. The PACE plugin is designed to show a progress bar fo ...

Using PHP to send a JSON request via cURL

I am attempting to make a cURL request in PHP. The request I am trying to send is as follows: $ curl -H 'Content-Type: application/json' -d '{"username":"a", "password":"b","msisdn":"447000000001","webhook":"http://example.com/"}' http ...

The jqxgrid from jqwidget is displaying all content in a single, messy column

After successfully publishing my project from ASP.NET MVC, everything was functioning perfectly. However, upon publication, the JQXWidget JqxGrid displayed data in a mixed-up manner as shown in this image: https://i.sstatic.net/0o1XY.jpg The layout of my ...

Exploring search capabilities within D3 graph nodes

After creating a JSON file with four tiers and utilizing D3.js's collapsing box format to visualize it (source: https://bl.ocks.org/swayvil/b86f8d4941bdfcbfff8f69619cd2f460), I've run into an issue. The problem stems from the sheer size of the J ...

Utilize the return function to showcase the organized outcomes on the webpage

This is my Alignments.js react component that uses the new useState and useEffect React hooks. It's working great, displaying a list of alignments: import React, {useState, useEffect} from 'react'; import './App.css'; import {Link ...

"Making a POST request from Postman and include nested JSON data along with an image or file attachment in

I have a JSON object that I need to POST: { "user": { "name": "John Doe", "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="87f2f4e2f5c7e2ffe6eaf7ebe2a9e4e ...

Learn how to extract precise information from a JSON array by utilizing Angular 6

After making a GET request in Angular 6, I successfully retrieved data from a JSON array. Now, I have this JSON data as an example and my goal is to find the team(s) that employee "TEST4KRWN" is part of. Can anyone guide me on how to write a JSON query us ...

How do I connect a group of models in an Azure Function triggered by HTTP?

Azure Function v2 I have set up is triggered by a POST HTTP request and provided with a list of accounts. Below is the code for the Azure Function: public sealed class AccountFunction { private readonly ILogger m_logger; public AccountFunction(I ...