jax
jax

Reputation: 840

Issue formatting data in JavaScript for a pie chart

I am not a JavaScript expert and I am trying to put a simple pie chart together using the data from a csv file. The sample code for the pie chart with its input data looks like below and it works perfectly.

var pie = new d3pie("pie", {
        header: {
            title: {
                text: "A Very Simple Pie",
                fontSize: 30
            }
        },
        data: {
            content: [
                { label: "JavaScript", value: 264131 },
                { label: "Ruby", value: 218812 },
                { label: "Java", value: 157618}
            ]
        }
    });

but when I try to use the data from the csv file. It says no data is provided. I obviously try to pass the dynamic data to the data.content but it seems like I am not doing it correctly. Below is my code:

var input_data = []
d3.csv("data.csv", function (data) {

    input_data.push({
        label: data["First"],
        value: +data["Age"]
    });
});

console.log(input_data); // This shows [{label: "james", value:30},{"John",value:22}]
var pie = new d3pie("pie", {
    header: {
        title: {
            text: "Simple Pie",
            fontSize: 30
        }
    },
    data: {
        content: input_data
    }
});

Any idea what I am doing wrong here?

Upvotes: 0

Views: 75

Answers (3)

i alarmed alien
i alarmed alien

Reputation: 9520

As noted in my comment, your problem is because d3.csv acts asynchronously, and input_data isn't populated when d3pie tries to create your chart.

There is something highly suspicious going on with input_data in the other examples -- it should be called for every item in data, but seems only to be called once. Rather than using input_data to collate intermediate results, it's much easier to use javascript's map function to transform your csv data into the format you want:

d3.csv("data.csv", function (data) {
    var pie = new d3pie("pie", {
        header: {
         title: {
             text: "Simple Pie",
             fontSize: 30
            }
        },
        data: {
            content: data.map( function(d){
                return { label: d['First'], value: +d['Age'] }
            })
        }
    });
});

map iterates over an array and produces an array as output, so it's much cleaner and easier than creating extra arrays on to which you push data, etc.

Upvotes: 1

Sven Liivak
Sven Liivak

Reputation: 1413

const promise = d3.csv("data.csv", function (data) {
    input_data.push({
        'label': data["First"],
        'value': +data["Age"]
    });
});

promise.then(function(){
    var pie = new d3pie("pieChart", {
        header: {
            title: {
                text: "Simple Pie",
                fontSize: 30
            }
        },
        data: {
            content: input_data
        }
    });
});

Upvotes: 0

slider
slider

Reputation: 12990

You probably want to put your d3pie code inside your callback function because you want to call it after the data returns (see this example):

var input_data = []
d3.csv("data.csv", function (data) {
    input_data.push({
        label: data["First"],
        value: +data["Age"]
    });
    console.log(input_data); // This shows [{label: "james", value:30},{"John",value:22}]
    var pie = new d3pie("pie", {
        header: {
            title: {
                text: "Simple Pie",
                fontSize: 30
            }
        },
        data: {
            content: input_data
        }
    });
});

Upvotes: 1

Related Questions