0

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?

1
  • 1
    d3.csv operates asynchronously, and d3pie is trying to create your chart before input_data has been populated. Quick and easy fix is to move the code that creates the pie chart inside the d3.csv callback. Commented Oct 11, 2018 at 20:02

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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
        }
    });
});

4 Comments

It works but it renders the chart twice. once with one slice and once with two slices.
@jax I hope that csv callback is the only place you're calling new d3pie(...).
yes it is. it seems like everything within the d3.csv is called as many as number of rows you have. Also, I noticed that the console.log() is shown twice as well once with one element and once with two elements. (my data has only two rows for testing purposes )
@jax It's hard to tell why that could be happening. Maybe you're calling d3.csv(...) multiple times?
0
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
        }
    });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.