1

i'm trying to dynamically populate a javascript object with data i have fetched from an api (pivotal tracker).

i have a javascript object called 'results' which looks like this:

   [ {"state"=>"finished",
  "range"=>"6 months",
  "points"=>0,
  "numberStories"=>0,
  "points / story"=>"N/A"},
 {"state"=>"finished",
  "range"=>"9 months",
  "points"=>0,
  "numberStories"=>0,
  "points / story"=>"N/A"},
 {"state"=>"finished",
  "range"=>"12 months",
  "points"=>0,
  "numberStories"=>0,
  "points / story"=>"N/A"}]

and i'm trying to write the javascript which will dynamically populate the chartjs object so that i graph one line for each 'state' showing number of 'points' for each 'range.

the chartjs object (with dummy data) looks like this:

var data = {
    labels : ["January","February","March","April","May","June","July"],
    datasets : [
        {
            fillColor : "rgba(220,220,220,0.5)",
            strokeColor : "rgba(220,220,220,1)",
            pointColor : "rgba(220,220,220,1)",
            pointStrokeColor : "#fff",
            data : [65,59,90,81,56,55,40]
        },
        {
            fillColor : "rgba(151,187,205,0.5)",
            strokeColor : "rgba(151,187,205,1)",
            pointColor : "rgba(151,187,205,1)",
            pointStrokeColor : "#fff",
            data : [28,48,40,19,96,27,100]
        }
    ]
}

what i have tried so far is:

var data ={};   
var data["labels"] = [];

for (var i = 0 ; i < results.length ; i++) {
    data["labels"].push(results[i]["range"]);
}

its obvious that i haven't initialised the array inside data properly, but i can't quite figure out how this should be done. the same will apply to datasets, when i get there.... any pointers? thanks!

2 Answers 2

1

I'm not sure I followed your question. Here is some commented code:

var set = [
    {...},
    {...},
    {...}];

// Initialize data object
var data = { labels:[], datasets:[] };

// Get the distinct list of labels (range).
// * Done in a separate step to get a known count
// * of labels for initializing the datasets
data.labels = set.reduce(function(memo,el){
    if (memo.indexOf(el.range) === -1)
        memo.push(el.range);

    return memo;
},[]);

// Get a distinct list of datasets (states)
var _sets = set.reduce(function(memo,el){
    if (memo.indexOf(el.state) === -1){
        memo.push(el.state);

        // create a dataset record at the same index as 
        // the matching state. 
        // Initiatize the data collection for each label
        data.datasets.push({
            data:data.labels.map(function(){ return 0 }),
            name:el.state,
            fillColor : "rgba(151,187,205,0.5)",
            strokeColor : "rgba(151,187,205,1)",
            pointColor : "rgba(151,187,205,1)",
            pointStrokeColor : "#fff"
        });

    }
    return memo;
},[]);

// Go through the set and assign points to the 
// appropriate data bucket
set.map(function(el){
    var setIdx = _sets.indexOf(el.state);
    var labelIdx = data.labels.indexOf(el.range);

    data.datasets[setIdx].data[labelIdx] += el.points;
},[]);

console.log(data);

And a fiddle: http://jsfiddle.net/2xP56/

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

1 Comment

amazingly quick and accurate response that taught me a fair bit.... once i managed to get my head round it. many thanks.
1

results was not an array (missing []) perhaps that was the problem?

var results = [{
"state": "finished",
"range":"6 months",
"points":0,
"numberStories":0,
"points / story":"N/A"
},
{
"state":"finished",
"range":"9 months",
"points":0,
"numberStories":0,
"points / story":"N/A"
},
{
"state":"finished",
"range":"12 months",
"points":0,
"numberStories":0,
"points / story":"N/A"}
];

var data = {
        labels: []
    };   


for (var i = 0 ; i < results.length ; i++) {
    data.labels.push(results[i].range);
}

alert(data.labels.length);

Otherwise, this should work I think?

Also note that you first define data and then later on redefine it. (But that's probably on purpose for the example?)

Note that if you know its name, you can access a property directly with .range (instead of ["range"])

1 Comment

'results' was an array that i copied from terminal. have added the square brackets to clarify. the literal notation for instantiating labels[] was the hint i needed. and thanks for the tip on accessing proprties...still stuck in my ruby ways to a certain extent

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.