Displaying hierarchical data in a pie chart using d3.js and a CSV file

As a newcomer to d3.js, I've been experimenting with creating pie charts. One of my projects involves a pie chart divided into 19 segments (see Picture 1) based on data from a CSV file (see Picture 2). Each segment represents a year, with the area indicating its score. If you'd like to view the images, you can check them out here.

My current goal is to establish a parent-child relationship within the CSV data, similar to the structure shown in Picture 3 (each year containing 5 continents). You can view the image here. The sum of the scores for the five continents should equal the total score for that specific year.

Additionally, I aim to transform the pie chart so that each segment is divided into 5 layers, going from the innermost to the outermost layer.

I've provided a snippet of my code below. Can someone guide me on how to create the hierarchy as outlined? If the structure shown in Picture 3 is incorrect, what would be the right approach to defining it?

Do I need to work with JSON data? If so, how should I adjust the data loading section from CSV files to accommodate JSON files?

    var width = 650, height = 650, radius = Math.min(width, height) / 2, innerRadius=0;

    var pie = d3.layout.pie()
                .sort(null)
                .value(function(d) { return d.width; });

    var arc = d3.svg.arc()
      .innerRadius(innerRadius)
      .outerRadius(function (d) {
        return (radius - innerRadius) * Math.sqrt(d.data.score / 2900.0) + innerRadius;
      });

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

//data loading
    d3.csv('./src/InCountry-v1.csv', function(error, data) {

      data.forEach(function(d) {
        d.id     =  d.year;
        d.order  = +d.order;
        d.color  =  d.color;
        d.weight = +d.weight;
        d.score  = +d.score;
        d.width  = +d.weight;
        d.label  =  d.label;
      });

    var path = svg.selectAll(".solidArc")
           .data(pie(data))
           .enter().append("path")
           .attr("fill", function(d) { return d.data.color})
           .attr("class", "solidArc")
           .attr("stroke", "gray")
           .attr("d", arc)
           .attr("opacity",0.5)
           .on("mouseenter", function() {d3.select(this)
                                           .style("fill", function(d) { return d.data.color})
                                           .attr("opacity",1); })
           .on("mouseleave", function() { d3.select(this).attr("opacity", 0.5); });

Answer №1

In order to achieve the desired structure for your data, it is essential to preprocess it appropriately.

To achieve this, you can create a function called dataPreparation:

function dataPreparation ( data ) {
  var byYear = {};
  var result = [];

  data.forEach(function (d) {
    if ( !byYear.hasOwnProperty(d.year) ) {
      byYear[d.year] = {
        year: d.year, 
        order: +d.order, 
        score: +d.score, 
        weight: +d.weight,
        width: +d.width,
        color: d.color,
        label: d.label,
        entries: [d]
      };
      result.push(byYear[d.year]);
    } else {
      byYear[d.year].score += +d.score;
      byYear[d.year].entries.push(d);
    }
  });
  return result;
}

Following this, within your csv load callback function, you can apply the dataPreparation function:

d3.csv('./src/InCountry-v1.csv', function(error, data) {
  var hierarchicalData = dataPreparation(data);

Finally, you can utilize the hierarchicalData with your pie generator function.

Best of luck!

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

Displaying an HTML button above JavaScript code

Hello, I am currently working on a project that involves displaying the Earth and I am in need of assistance with positioning some buttons on the screen. Currently, I am facing an issue where the buttons appear either above or below the JavaScript code. I ...

There seems to be an issue with the functionality of the Bootstrap Modal

I've been working on incorporating bootstrap login Modal functionality into my code, but for some reason, the screen is not displaying it. Here's what shows up on the screen: https://i.sstatic.net/UIU2w.png The red box in the image indicates whe ...

Creating Scroll Animations in Javascript - Mastering scrollIntoView Animation

When I click on a div, I was only able to bring it into view with the scrollIntoView function. It functions correctly and meets my expectations, but I am curious if there is a way to animate it and slow down the process. I attempted a suggestion found her ...

Trouble transferring JSON data into SQLite database using Python

My JSON data is structured like this, with additional information: { "realms": [ { "status": true, "battlegroup": "Shadowburn", "name": "Zuluhed", "locale": "en_US", "queue": false, ...

The input box is not properly filled with the complete string using protractor sendKeys

[HTTP] --> POST /wd/hub/session/ffcd7072-9f96-45cb-a61d-ec53fc696b56/element/0.9513211246393813-32/value {"value":["1","0","0","0","1"],"text":"10001"} My JavaScript code snippet: this.zipcode = element(by.model('personalInfo.zipcode')); t ...

What is the best way to disable the click function for <a> tags that have a specific class?

I am dealing with parent navigation items that have children, and I want to prevent the parent items from being clickable. Here is an example of how they currently look: <a href="parent">Parent Item</a> Is there a way to select the <a> ...

Unable to bring in the Firebase Firestore Colletion

When working on my next app, I encountered an error while trying to call a Firestore Collection. The specific error message that appeared when I ran the app was: FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicat ...

Accessing dataset schemas to parse JSON files

A JSON file has been included in a dataset within Foundry: [ { "name": "Tim", "born": "2000 01 01", "location": {"country": "UK", "city": "London"}, ...

Using React to access the properties of objects within an array that has been dynamically mapped

For my initial dive into developing a React application, I am currently in the process of fetching data from a database and updating the state to store this information as an array. My main challenge lies in accessing the properties of the objects within t ...

What drawbacks come with developing an Express.js application using TypeScript?

Curious about the potential drawbacks of using TypeScript to write Express.js applications or APIs instead of JavaScript. ...

My div is currently being concealed by a jQuery script that is hiding all of its

Below is the current code snippet: jQuery(document).ready(function($) { $("ul.accordion-section-content li[id*='layers-builder'] button.add-new-widget").click(function() { $("#available-widgets-list div:not([id*='layers-widget']) ...

Selecting the appropriate fields based on the value of another field

Is there a way to use Jolt to select only fields that contain the value of another field? Below is my input: { "type": "A", "field1": "value1", "field2": "value2", "example1-A1[zone= ...

Unsure how to proceed with resolving lint errors that are causing changes in the code

Updated. I made changes to the code but I am still encountering the following error: Error Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. It is recom ...

Using the Flow type checker with React library results in complications

I'm fairly new to JavaScript and React, so I appreciate your patience! I've recently started a project using create-react-app with React version 16.12.0. I installed a library that seems to be utilizing Flow. When attempting to use this library ...

React Router 4 - Optimizing Component Refresh by Remounting Instead of Re-Rendering

I am currently in the process of configuring a React project that utilizes React Router 4 ("react-router-dom": "^4.3.1"). Within this project, I have implemented a SideBar, a NavBar, and the main content section of the application which changes based on th ...

Guide to using get() and res.sendFile() function to redirect webpages

Why is the page not redirecting properly? In my index.html file, I have this script: $.get( "/loginPage", function( data ) {}); The purpose of this script is to check if a user is logged in. If they are, it should redirect them to the lobbyPage. This is ...

Exclude basic authentication for a specific route

Using node, express and connect for a simple app with basic HTTP auth implemented. The code snippet below shows part of the implementation: var express = require('express'), connect = require('connect'); app.configure = function(){ ...

What is the best way to filter through JSON data in Vue.js?

I'm encountering an issue with my JSON file that I am rendering to a table. I have 11 columns including id, name, and more. I want to search by every column, but the functionality only works for one column. If I try to filter the data multiple times, ...

Example JSON response for RabbitMQ API management module

Currently, I am in the process of gathering all the data offered by the RabbitMQ Management API. I have successfully set up my own RabbitMQ environment locally and have been able to retrieve the API responses. However, I am unsure if I have accessed all ...

I am encountering an issue with my Javascript file not running due to a bigint error

I'm attempting to utilize @metaplex/js for NFT minting. Usually, my .js files function correctly, but when I execute the file, this particular error arises. bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?) The meaning of ...