0

I'm trying to get some array data into a particular format so I can use google linechart. But I can't quite get it right.

Right now I have the format

//format [date, id, count
var data = [

   ["2014-04-01", "1", "100"],
   ["2014-04-02", "1", "200"],
   ["2014-04-03", "1", "150"],
   ["2014-04-04", "1", "5"],

   ["2014-04-01", "2", "200"],
   ["2014-04-02", "2", "600"],
   ["2014-04-03", "2", "15"],
   ["2014-04-04", "2", "25"],

   ["2014-04-01", "3", "99"],
   ["2014-04-02", "3", "85"],
   ["2014-04-03", "3", "555"],
   ["2014-04-04", "3", "0"]

];

I need to get it into the format:

var reformatted = [

      ['Date', '1', '2', '3'],
      ['2014-04-01', 100, 200, 99],
      ['2014-04-02', 200, 600, 85],
      ['2014-04-03', 150, 15, 555],
      ['2014-04-04', 5, 25, 0]

    ]);



var graph = [["date"]];

//first element of array to be populated with array of ID's
//always second element of inner arrays
//these will be the lines of the graph
for (var i = 0; i < data.length; i++){

  if (graph[0].indexOf(data[i][1]) < 0){

    graph[0].push(data[i][1]);

  }

}

This puts me in a pretty good place. I get:

Array[1]]
    0: Array[4]
       0: "date"
       1: "1"
       2: "2"
       3: "3"

But I'm stumped on how to get the rest of the data in the appropriate format. Any ideas?

Tried this. No good result.

for (i = 0; i < data.length; i++){

  graph[i + 1] = graph[i + 1] || [];
  graph[i + 1].push(data[i][2]);

}
2
  • Would be great to see your solution! Commented Apr 21, 2014 at 21:00
  • @nazim Am working through your outline now. I'll post it once I've gotten there. Thanks much. Commented Apr 21, 2014 at 21:25

3 Answers 3

1

Logic:

First generate this by iterating through the initial array finding unique dates.

[
 ['Date'],
 ['2014-04-01'],
 ['2014-04-02'],
 ['2014-04-03'],
 ['2014-04-04']
]

Then convert the generated array as follows again iterating through the initial array finding unique numbers. Also generate list of unique numbers.

[
 ['Date','1','2','3'],
 ['2014-04-01'],
 ['2014-04-02'],
 ['2014-04-03'],
 ['2014-04-04']
]

Now iterate through above array, and for each item iterate through the number list and find matches from the initial array where date and number matches. place the matches in the above array. Place a null if not found. You should get the following. I have done this in php but not in javascript.

[
 ['Date','1','2','3'],
 ['2014-04-01', null, 100, 200],
 ['2014-04-02', 100, 400, 500],
 ['2014-04-03', 200, null, 100],
 ['2014-04-04', 100, 300, 100]
]

Good Luck!

addition

In php:

$originalData = array(
    array("2014-04-01", '1', '200'),
    array("2014-04-02", '1', '300'),
    array("2014-04-03", '1', '400'),
    array("2014-04-04", '1', '200'),
    array("2014-04-01", '2', '400'),
    array("2014-04-02", '2', '100'),
    array("2014-04-03", '2', '200'),
    array("2014-04-04", '2', '100'),
    array("2014-04-01", '3', '200'),
    array("2014-04-02", '3', '600'),
    array("2014-04-03", '3', '300'),
    array("2014-04-04", '3', '900'),
);

result from second step would be:

$graphData = array(
         array('Date','1','2','3'),
         array('2014-04-01'),
         array('2014-04-02'),
         array('2014-04-03'),
         array('2014-04-04'),
);

list of numbers would be:

$numbers = array('1','2','3');

I would then do the third step as follows:

$i = 0;
foreach($graphData as $graphDataItem) {

    if ($graphDataItem[0]!='Date') { // ignore the first index

        $j = 1; // 0 is date column
        foreach($numbers as $number) {
            foreach($originalData as $originalDataItem) {

                // set the value to null until found
                if (!isset($graphData[$i][$j]))
                  $graphData[$i][$j] = null;

                if ($originalDataItem[0] == $graphDataItem[0] && // check date match
                    $originalDataItem[1] == $number) { // check number match
                    $graphData[$i][$j] = $originalDataItem[2];
                    break;
                } 
            }
            $j++;
        }
    }
    $i++;
}

The resulting $graphData would be:

array
(
    0 => array
    (
        0 => 'Date'
        1 => '1'
        2 => '2'
        3 => '3'
    )
    1 => array
    (
        0 => '2014-04-01'
        1 => '200'
        2 => '400'
        3 => '200'
    )
    2 => array
    (
        0 => '2014-04-02'
        1 => '300'
        2 => '100'
        3 => '600'
    )
    3 => array
    (
        0 => '2014-04-03'
        1 => '400'
        2 => '200'
        3 => '300'
    )
    4 => array
    (
        0 => '2014-04-04'
        1 => '200'
        2 => '100'
        3 => '900'
    )
)

The above would get you the results in $graphData. However, this would be heavy on processor for larger sets.

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

4 Comments

"for each item iterate through the number list" What is the "number list"?
[1,2,3] see my second para
The last step is sort of confusing me. I have var dates = []; dates.unshift (["Dates"]); for (var d = 0; d < data.length; d++){ if (dates.indexOf(data[d][0]) < 0){ dates.push([data[d][0]]); } if (dates[0].indexOf(data[d][1]) < 0){ dates[0].push(data[d][1]); } } but am not sure how to proceed.
I could give you a php example?
0

Here's an option: First group all the data by dates, then convert it back into the representation you need. If you want to automate it a bit more, you could also keep track of the IDs and add the list for the legend automatically.

var data = [

   ["2014-04-01", "1", "100"],
   ["2014-04-02", "1", "200"],
   ["2014-04-03", "1", "150"],
   ["2014-04-04", "1", "5"],

   ["2014-04-01", "2", "200"],
   ["2014-04-02", "2", "600"],
   ["2014-04-03", "2", "15"],
   ["2014-04-04", "2", "25"],

   ["2014-04-01", "3", "99"],
   ["2014-04-02", "3", "85"],
   ["2014-04-03", "3", "555"],
   ["2014-04-04", "3", "0"]

];

var groupByDate = function (data) {
  var dataByDate = {};
  data.forEach(function (entry) {
    var date = entry[0];
    var count = entry[2];
    if (!(date in dataByDate)) {
       dataByDate[date] = []; 
    }
    dataByDate[date].push(count);
  });
  return dataByDate;
}

var toChartData = function (dataByDate) {
  var chartData = [];
  for (var date in dataByDate) {
        chartData.push([date].concat(dataByDate[date]));
  };
  return chartData;
};

var byDate = groupByDate(data);
var chartData = toChartData(byDate);
chartData.unshift(['Date', 1, 2, 3]);

console.log(chartData);

Comments

0

Arrays can be rough for things like this, to make it easier it can be best to first convert it to an object to make it easier to work with.

var obj = {};

for(var i=0;i<data.length;i++){
 if(!obj[data[i][0]]){ //check if index already exists
  obj[data[i][0]] = {}; //create sub object from the index
 }
 for(var ii=0;ii<data[i].length;ii++){
  if(ii!=0){ //since the 0 index is the parent here, ignore it
   obj[data[i][0]][ii] = data[i][ii];
  }
 }
}

This should translate to an object like so:

var data = {
 '2014-04-01':{
  1:100,
  2:200,
  3:99
 } //continue for the rest
}

So like that you can probably see that converting it into pretty much any other structure will be far easier.

var graph = [['date','1','2','3']];
for(var index in data){
 if(data.hasOwnProperty(index)){
  var arr = [index];
  for(var index2 in data[index]){
   if(data[index].hasOwnProperty(index2)){
    arr.push(data[index][index2]);
   }
  }
  graph.push(arr);
 }
}

Untested and written on the spot, but the concept is there.

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.