jQuery multidimensional object with multidimensional arrays
Asked Answered
D

4

9

Im trying to build a somewhat advanced "Flot" jQuery pluging graph. For that, I need a multidimensional object (or at least I think it is).

The structure should look like this:

var datasets = {
        "usa": {
            label: "USA",
            data: [[1988, 483994], [1989, 479060], [1990, 457648], [1991, 401949], [1992, 424705], [1993, 402375], [1994, 377867], [1995, 357382], [1996, 337946], [1997, 336185], [1998, 328611], [1999, 329421], [2000, 342172], [2001, 344932], [2002, 387303], [2003, 440813], [2004, 480451], [2005, 504638], [2006, 528692]]
        },        
        "russia": {
            label: "Russia",
            data: [[1988, 218000], [1989, 203000], [1990, 171000], [1992, 42500], [1993, 37600], [1994, 36600], [1995, 21700], [1996, 19200], [1997, 21300], [1998, 13600], [1999, 14000], [2000, 19100], [2001, 21300], [2002, 23600], [2003, 25100], [2004, 26100], [2005, 31100], [2006, 34700]]
        }
};

From my code-behind i've generated some lists looking like this (Not the same data, but dont mind that):

<ul id="MOBILISATION">
  <li data-key="2012/3/27">02:10</li>
  <li data-key="2012/3/28">05:25</li>
  <li data-key="2012/3/29">09:21</li>
  <li data-key="2012/3/30">00:00</li>
  <li data-key="2012/3/31">00:00</li>
</ul>
<ul id="OPERATIONS">
  <li data-key="2012/3/27">19:51</li>
  <li data-key="2012/3/28">18:35</li>
  <li data-key="2012/3/29">14:39</li>
  <li data-key="2012/3/30">07:46</li>
  <li data-key="2012/3/31">10:26</li>
</ul>

Where "USA/usa" is "MOBILISATION", "1988" is "2012/3/27" and "483994" is "02:10". You get picture!!??

I've tried writing some jQuery, but it obviously doesnt work:

    var objects = [];
    var array = [];
    var categoryName = "";
    $('div#Container ul').each(function () {
        catName = $(this).attr('id');
        $('li', this).each(function () {
            array.push([new Date($(this).data('key')).getTime(), $(this).text()]);
        });

        objects.push({ categoryName: { label: categoryName, data: array} });
    });
    var datasets = objects;

As you can see i've used push to objects array. Clearly that is not giving me the result I want. Im kindda loosing whats up and down in this, as its the first time I'm working with jQuery objects.

Whats the best solution for this?

Dollydolman answered 25/7, 2012 at 11:22 Comment(0)
N
6

Your datasets is an object, not an array - you can't push to it. Also, your variable categoryName does not work like that (read more on dot and bracket notation). Try this:

var datasets = {};
$('div#Container ul').each(function () {
    catName = this.id;
    var array = [];
    $('li', this).each(function () {
        array.push([
          new Date($(this).data('key')).getTime(),
          $(this).text()
        ]);
    });
    datasets[catName.toLowercase()] = {
        label: catName.toUppercase(),
        data: array
    };
});

Also, I'm not sure whether you really would need to create Date objects, but that depends on your in- and output format.

Nickname answered 25/7, 2012 at 11:33 Comment(4)
I need the date object because I have my x-axis property mode in "time" (have to for the Flot plugin to work). With your code right out the box the graph container and categories are drawn nicely. My next problem the Date object. Theres no data/bars/lines in the graph, because the plugin cant recognize the string "hh:mm" on the y-axis as time. Gimme a sec to figure it out and ill mark your answer as correct (Even though all the other answers probly are correct as well just by reading them). ThanksDollydolman
Hmm yeah cant get It to work. Do you have any idea what to do? Ive tried converting it to a Date object and set the date format property for the plugins y-axis. No luckDollydolman
No, not me. But I think that would give a good, there are already some on time issues - yet they handle datetimes, not times of day :-)Nickname
Yeah. Guess what I need is a time span. Thanks for your help mate!Dollydolman
A
12

Change var objects = []; to var objects = {}; and change

objects.push({ categoryName: { label: categoryName, data: array} });

to

objects[categoryName] = { label: categoryName, data: array};

The problem you have with JSON objects is in setting properties with a variable index. You can use array notation to do that, as above.

Accalia answered 25/7, 2012 at 11:29 Comment(0)
N
6

Your datasets is an object, not an array - you can't push to it. Also, your variable categoryName does not work like that (read more on dot and bracket notation). Try this:

var datasets = {};
$('div#Container ul').each(function () {
    catName = this.id;
    var array = [];
    $('li', this).each(function () {
        array.push([
          new Date($(this).data('key')).getTime(),
          $(this).text()
        ]);
    });
    datasets[catName.toLowercase()] = {
        label: catName.toUppercase(),
        data: array
    };
});

Also, I'm not sure whether you really would need to create Date objects, but that depends on your in- and output format.

Nickname answered 25/7, 2012 at 11:33 Comment(4)
I need the date object because I have my x-axis property mode in "time" (have to for the Flot plugin to work). With your code right out the box the graph container and categories are drawn nicely. My next problem the Date object. Theres no data/bars/lines in the graph, because the plugin cant recognize the string "hh:mm" on the y-axis as time. Gimme a sec to figure it out and ill mark your answer as correct (Even though all the other answers probly are correct as well just by reading them). ThanksDollydolman
Hmm yeah cant get It to work. Do you have any idea what to do? Ive tried converting it to a Date object and set the date format property for the plugins y-axis. No luckDollydolman
No, not me. But I think that would give a good, there are already some on time issues - yet they handle datetimes, not times of day :-)Nickname
Yeah. Guess what I need is a time span. Thanks for your help mate!Dollydolman
W
1

Try

    var data = {};
    $('div#Container ul').each(function() {
        var sub_obj = data[$(this).attr('id').toLowerCase()] = {
            label: $(this).attr('id').toUpperCase(),
            data: []
        };
        $(this).children('li').each(function() {
            sub_obj.data.push([$(this).data('key'), $(this).text()]);
        });
    });
    console.log(data);
Whirlybird answered 25/7, 2012 at 11:33 Comment(1)
This post is missing its explanation.Ringent
J
1
function convertObject(obj, key) {
    let returnObje = {};
    if (!key) key = "";
    else key = key + "_";
    Object.keys(obj).forEach(function (k1) {
        if (obj[k1] != null && typeof obj[k1] == "object") {
            returnObje = Object.assign({}, returnObje, convertObject(obj[k1], key + k1))
        } else
            returnObje[key + k1] = obj[k1];
    });
    return returnObje;
}

var hotels = { 
                     "hilton": {"name": "hilton hotel" },
                     "newton": {"name": "newton hotel"}
                 };

convertObject(hotels);
Johanna answered 2/8, 2018 at 11:0 Comment(1)
This post is missing its explanation.Ringent

© 2022 - 2024 — McMap. All rights reserved.