1

What I'm working on is a menu that auto updates its entries based on an array length. It adds groups of 10 objects' properties (in this case "IDnumbers") to the menu if a new object is added to the array.

var arraysOfObject = [], obj = {"IDNumber": ""};
for(i = 0; i<42; i++){
arraysOfObject.push({"IDNumber": "Number " + i});}

Above is the array holding 42 objects with a specific property.

var array2 = [];
    var leftOver = arraysOfObject.length % 10;
    var groupsOfTen = (arraysOfObject.length - leftOver)/10;
    for (var i = 0; i < groupsOfTen; i++) {
        array2.push([]);
        for (var j = i*10; j < i*10 + 10; j++)
            array2[i].push(arraysOfObject[j]["IDNumber"]);
    } 

    //now the leftover
    if (leftOver > 0) {
        array2.push([]);
        for (var i = groupsOfTen*10; i < arraysOfObject.length; i++)
            array2[array2.length-1].push(arraysOfObject[i]["IDNumber"]);
    }

The array2 above is the array that stores all the possible arrays that can be grouped by 10 from arraysOfObject. In this case there are 5 inside of it, because 4 arrays holds 40 objects, and 1 array holds the 2 remainders.

That all works fine, but placing the array2 inside the menu displays all possible IDnumbers grouped together, but not grouped individually. I have to declare each possible array inside of it like so sets = [array2[0], array2[1], array2[2], array2[3], array2[4]]; If there's a 6th possible array because object #51 has been added to arraysOfObject, I have to input it with array2[5].

I don't want it to depend on my input, but that it knows the number of possible arrays and that it displays it automatically in sets. How do I do that?

var gui = new dat.GUI();
var guiData = function() {
  this.message = "Dat.Gui menu";
  this.system = 0;
  this.Sets = 0;
};

var data = new guiData();
sets = [array2[0], array2[1], array2[2], array2[3], array2[4],  array2[5]];

gui.add(data, 'message', 'Dat.Gui Menu!');
gui.add(data, 'system', {
  "1": 0,
  "2": 1,
  "3": 2,
  "4": 3,
  "5": 4,
  "6": 5,
}).name('system #').onChange(function(value) {
  updateSets(value);
});
gui.add(data, 'Sets', sets[0]).onChange();

function updateSets(id) {
    var controller = gui.__controllers[2];
    controller.remove();
    gui.add(data, 'Sets', sets[id]).onChange();
    
    data.Sets = 0;
    gui.__controllers[2].updateDisplay();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.1/dat.gui.min.js"></script>

<script>
var arraysOfObject = [], obj = {"IDNumber": ""};
for(i = 0; i<42; i++){
arraysOfObject.push({"IDNumber": "Number " + i});}

var array2 = [];
    var leftOver = arraysOfObject.length % 10;
    var groupsOfTen = (arraysOfObject.length - leftOver)/10;
    for (var i = 0; i < groupsOfTen; i++) {
        array2.push([]);
        for (var j = i*10; j < i*10 + 10; j++)
            array2[i].push(arraysOfObject[j]["IDNumber"]);
    } 

    //now take care of the leftover
    if (leftOver > 0) {
        array2.push([]);
        for (var i = groupsOfTen*10; i < arraysOfObject.length; i++)
            array2[array2.length-1].push(arraysOfObject[i]["IDNumber"]);
    }
</script>
TheNuttyStudent
  • 199
  • 1
  • 1
  • 8

2 Answers2

2

Not the issue at hand, but I was playing around with the dat.gui as you posted it and was wondering if the dropdown could be refilled without removing/adding/etc. It seems to work with .options. (NB The initialization code makes heavy use of ES6, but can work without. The system menu is created dynamically from the sets array)

let arraysOfObject =Array.from({length:42}, (o,i) => "Number " + i),
 ch =10, sets = Array.from({length:Math.ceil(arraysOfObject.length/ch)}, (a,i) => arraysOfObject.slice(i*=ch, i+ch));

var gui = new dat.GUI();
var guiData = function() {
  this.message = "Dat.Gui menu";
  this.system = 0;
  this.Sets = 0;
};

var data = new guiData();
gui.add(data, 'message', 'Dat.Gui Menu!');
gui.add(data, 'system',  sets.reduce((obj,s,i) => (obj[i+1] = i, obj), {})).name('system #').onChange(updateSets);
let controller =  gui.add(data, 'Sets');
updateSets(0);
function updateSets(id) {  
  controller = controller.options(sets[data.Sets = id]);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.1/dat.gui.min.js"></script>
Me.Name
  • 12,259
  • 3
  • 31
  • 48
  • I will definitely use your approach on how to update the dat.gui controllers. It was a hassle before and you made things a lot easier with that. So thanks. Since you've acquainted yourself with the code, maybe you know the answer to this? I've been failing with adding another array with objects (with its own properties) in the same "system#" `set`? So that it comes at the top of the `arraysOfObject` array? – TheNuttyStudent Dec 29 '16 at 17:41
  • Glad it was of help, but I'm afraid I don't fully understand your follow up question. Perhaps it's better to post a new question with the details. cheers – Me.Name Dec 30 '16 at 13:18
1

I think the easiest solution would be to use ES2015's spread operator which I don't know if you would want to use yet...

ES2015 method (demo)

sets = [...array2];

There are a few other changes in the demo to set the system variable

But after taking a closer look, you can optimize the code by using the method from this SO answer to chunk your array using slice(). Also, I'm not sure why an object was used to create array entries when it just ends up as a string... demo

var arraysOfObject = [],
  system = {},
  chunk = 10,
  size = 92;

for (var i = 0; i < size; i++) {
  arraysOfObject.push("Number " + i);
}

var sets = [];
var index = 0;
for (i = 0; i < size; i += chunk) {
  sets.push(arraysOfObject.slice(i, i + chunk));
  system[index + 1] = index++;
}

var gui = new dat.GUI();
var guiData = function() {
  this.message = "Dat.Gui menu";
  this.system = 0;
  this.Sets = 0;
};

var data = new guiData();

gui.add(data, 'message', 'Dat.Gui Menu!');
gui
  .add(data, 'system', system)
  .name('system #')
  .onChange(function(value) {
    updateSets(value);
  });
gui.add(data, 'Sets', sets[0]).onChange();

function updateSets(id) {
  var controller = gui.__controllers[2];
  controller.remove();
  gui.add(data, 'Sets', sets[id]).onChange();

  data.Sets = 0;
  gui.__controllers[2].updateDisplay();
}
Community
  • 1
  • 1
Mottie
  • 84,355
  • 30
  • 126
  • 241