Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract and display values from nested objects #262

Closed
FragginWagon opened this issue Jun 22, 2015 · 12 comments
Closed

Extract and display values from nested objects #262

FragginWagon opened this issue Jun 22, 2015 · 12 comments

Comments

@FragginWagon
Copy link

I have a data object that I want to use values nested within a field. This would mean that right now I am using x and my y variables are count and timer. I am trying to include a nested object called shifts and get data from there so the data object would look as follows.

$scope.data = {
count: 234,
timer:222,
shifts: {
count:323443,
timer: 234234
}}

I am wanting one of the y values to be shifts.count. is this possible, if so how?

Thanks,

Greg

@chaosmail
Copy link
Contributor

Hi @BinaryWasteland

you could simply map the nested array to a flat one, here is an example http://plnkr.co/edit/RXmxWSdrNE0G0diWslqh

Let me know if this works for you!

Best,
Christoph

@chaosmail
Copy link
Contributor

here is the essential part

  var orig_data = [{
    count: 234,
    timer:222,
    shifts: {
      count:323443,
      timer: 234234
    }
  },{
    count: 236,
    timer:228,
    shifts: {
      count:323464,
      timer: 234252
    }
  }];

  // Map the dataset to flat object
  $scope.data = orig_data.map(function(d){
    return {
      x: d.count,
      value1: d.timer,
      value2: d.shifts.count
    }
  });

@FragginWagon
Copy link
Author

Hey @chaosmail,

Thanks for the amazingly fast response, I appreciate it. I think this will work but I have only one other question. I am loading the shifts object up dynamically and am new to angular. What I want to do is if there are 3 different shifts then I need value1, value2, etc generated dynamically. Is this possible?

Thanks Christoph!

Greg

@FragginWagon
Copy link
Author

Hey again @chaosmail,

An example I have is below:

{
    "x": "2015-06-15T20:31:12.210Z",
    "count": 12256,
    "timer": 57.46,
    "trendTimer": 57,
    "trendCount": 12256,
    "xCountCounter": 1,
    "xTimerCounter": 1,
    "shifts": [{
        "count": 2902,
        "timer": 61633.33,
        "trendTimer": null,
        "trendCount": null,
        "shiftCounter": 1,
        "startDate": 1434366000,
        "endDate": 1434384000
    }, {
        "count": 2902,
        "timer": 61633.33,
        "trendTimer": null,
        "trendCount": null,
        "shiftCounter": 2,
        "startDate": 1434366000,
        "endDate": 1434384000
    }, {
        "count": 2902,
        "timer": 61633.33,
        "trendTimer": null,
        "trendCount": null,
        "shiftCounter": 3,
        "startDate": 1434366000,
        "endDate": 1434384000
    }],
    "countRegLine": 13103,
    "timerRegLine": 59.67333333333333
}, {
    "x": "2015-06-16T20:31:12.210Z",
    "count": 11866,
    "timer": 52.5,
    "trendTimer": 55,
    "trendCount": 12061,
    "xCountCounter": 2,
    "xTimerCounter": 2,
    "shifts": [{
        "count": 2764,
        "timer": 56738.89,
        "trendTimer": null,
        "trendCount": null,
        "shiftCounter": 4,
        "startDate": 1434452400,
        "endDate": 1434470400
    }, {
        "count": 2764,
        "timer": 56738.89,
        "trendTimer": null,
        "trendCount": null,
        "shiftCounter": 5,
        "startDate": 1434452400,
        "endDate": 1434470400
    }, {
        "count": 2764,
        "timer": 56738.89,
        "trendTimer": null,
        "trendCount": null,
        "shiftCounter": 6,
        "startDate": 1434452400,
        "endDate": 1434470400
    }],
    "countRegLine": 11346.464285714286,
    "timerRegLine": 51.58130952380952
}, etc, etc]

Hope this helps clarify it as I re-read my post and it confused me a little

@chaosmail
Copy link
Contributor

ok, so the goal is to map the original dataset (the one you posted above) to a flat dataset (that you can input to the visualization) once it is (re-)loaded.
You have 2 possibilies

  • loaded the dataset (with ngResource or $http and immediately flatten it
  • watch the original dataset for changes (with $watch) and update a flat dataset whenever the original one changes

The option to choose depends strongly on how you use the dataset in the rest of your application. Let me know which approach you use, then I can give you a specific example implementation!

@chaosmail
Copy link
Contributor

Also I saw that your shifts attribute contains mutliple objects - whereas the count value in these objects is always the same. Which values do you want to display exactly or do you want to sum them together or sth? There are pretty nice ways to aggregate datasets like yours with D3js; if you can tell me precisely what do you want to display, I could lead you to the right way or give you an example implementation.

@chaosmail chaosmail changed the title Wanting to load values not in main object Extract and display values from nested objects Jun 22, 2015
@FragginWagon
Copy link
Author

Hey @chaosmail,

Yes the shift values contain the same values but I was wanting to just test on multiple shifts pulling them into the same object then push onto the data object. I will need to show the following for shifts:

  • count
  • timer
  • trendCount
  • trendTimer

I would also need to show those for the base object as well assuming the user wants to switch back from viewing shifts to viewing completed totals. I am thinking on flattening the object i would want to make it look like the following

Data Object:

  • x (date values)
  • count
  • timer
  • trendCount
  • trendTimer
  • shiftCount1
  • shiftTimer1
  • shiftTrendCount1
  • shiftTrendTimer1

(anything with a number at the end I need these to increment by one for every shift defined, in this case 3 but could be any number, but not sure how to accomplish this).

I am wanting to display shifts (1 - whatever) side-by-side for x (the day) and then iterate to the next day and do the same. I have looked into D3js and it does look enticing but it seemed N3-Charts was the easiest route to showing something to customer. I am thinking I may need to switch or at least eventually let the customer choose but for now if I can get N3 working I would be ecstatic.

@chaosmail, I appreciate all the help you are giving I am learning so much, your AWESOME!

Thanks,

Greg

@chaosmail
Copy link
Contributor

Hi Greg,

first I want to make sure you are able to flatten the array properly; we use map to achieve this in JavaScript.

Here is a detailed example with comments where I walk through your data structure: http://plnkr.co/edit/Ali40NCUy5YW7vEO4p2L

After you have successfully flattened your array, we will look at displaying it and integrating it with AngularJS.

Best,
Christoph

@chaosmail
Copy link
Contributor

You can also first check the example output of the above plnkr in the embedded view http://embed.plnkr.co/Ali40NCUy5YW7vEO4p2L/preview

The output will appear in the console of the developer tools (press F12 and click on "console")

@FragginWagon
Copy link
Author

Hey @chaosmail,

Sorry for the long pause in response. My daughter is taking up most of my time today. I can definitely do that with the data I am just not sure how to recurse in the mapping function to dynamically add the following for however many objects need to be returned based on the number of shifts:

// here we access the values from the nested shifts values
// actually we return values from the first element of each shifts
// elements
shiftCount1: d.shifts[0].count,
shiftTimer1: d.shifts[0].timer,
shiftTrendCount1: d.shifts[0].trendCount,
shiftTrendTimer1: d.shifts[0].trendTimer,

// Actually we could also provide default values
// that we don't have to deal with Null values
shiftCount1Sane: d.shifts[0].count || 0,
shiftTimer1Sane: d.shifts[0].timer || 0,
shiftTrendCount1Sane: d.shifts[0].trendCount || 0,
shiftTrendTimer1Sane: d.shifts[0].trendTimer

Any idea on how I could accomplish this easily and effectively?

Thanks,

Greg

@FragginWagon
Copy link
Author

hey @chaosmail,

I ended up taking a different path to map the shifts to main object. I used the following to accomplish dynamic naming:

      for (i = 0; i < $scope.data.length - 1; ++i) {
          for (j = 0; j <= $scope.data[i].shifts.length - 1; ++j) {
            $scope.data[i]['shift' + j + 'count'] = $scope.data[i].shifts[j].count;
            $scope.data[i]['shift' + j + 'timer'] = $scope.data[i].shifts[j].timer;
            $scope.data[i]['shift' + j + 'trendCount'] = $scope.data[i].shifts[j].trendCount;
            $scope.data[i]['shift' + j + 'trendTimer'] = $scope.data[i].shifts[j].trendTimer;
            $scope.data[i]['shift' + j + 'countRegLine'] = $scope.data[i].shifts[j].countRegLine;
            $scope.data[i]['shift' + j + 'timerRegLine'] = $scope.data[i].shifts[j].timerRegLine;
          }
          //flat_data[0]['dynamic'] = 'Sweet Digs';
        }

        console.log($scope.data);
        var addItCount = 0;
        //for(i = 0; i <= $scope.shiftsObj.length - 1; ++i) {
        angular.forEach($scope.shiftsObj, function(value, key) {
          //console.log('shift' + addItCount + $scope.reporting.viewDataOption);
          $scope.options.series.push({
            y: 'shift' + addItCount + $scope.reporting.viewDataOption,
            color: '#' + hexColorRandomizer(),
            type: $scope.graphType,
            axis: 'y',
            striped: true,
            label: toTitleCase($scope.reportLabel + ' of ' + 'shift ' + (addItCount + 1)),
            id: value.id
          });
          addItCount++;
          //console.log();
        });

and then when I click a button to regen charting it will splice the series pushed out. Attached I have an image of the end result :)

screen shot 2015-06-23 at 11 35 52 pm

Made a random generator for Hex colors so kind of looks ravy but gives the result I am looking for. Few tweaks to make to make it look better but its a start :)

@chaosmail
Copy link
Contributor

great news, glad that you found a good solution for your problem!

Btw, if you want beautiful random colors, you could look into generating them in HSL space rather than in HEX. here is a library that does this under the hood. https://github.com/davidmerfield/randomColor

I will close this issue for now; please keep me updated on how is it going with the chart!

Best
Christoph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants