JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>

JavaScript

var Model = Backbone.Model.extend({
});

var Collection = Backbone.Collection.extend({
    model: Model,
    sortTimeAsc: function(model) {
        var val=model.get('timestamp');
        return +val;
    },
    sortTimeDesc: function(model) {
        var val=model.get('timestamp');
        return -val;
    }
});

// fill our collection with data
var col= new Collection();
col.add(new Model({id:1, name:"Item1", timestamp:10, parentId: null}));
col.add(new Model({id:2, name:"Item2", timestamp:20, parentId: null}));
col.add(new Model({id:3, name:"Item1.1", timestamp:30, parentId: 1}));
col.add(new Model({id:4, name:"Item3", timestamp:40, parentId: null}));
col.add(new Model({id:5, name:"Item4", timestamp:50, parentId: null}));
col.add(new Model({id:6, name:"Item3.1", timestamp:60, parentId: 4}));
col.add(new Model({id:7, name:"Item3.2", timestamp:70, parentId: 4}));

// sor our collection by Time
col.comparator = col.sortTimeAsc;
col.sort({silent:true});      // silent option won't trigger reset event

function Iterator(argument) {
    this.initialize(argument);           
}
Iterator.prototype = _.extend(Iterator, {
    _tree: null,      // here we will store our collection passed in constructor
    _stack: [],       // our stack for DFS
    options: {        
        // these are options you can pass if your collection uses key than 'parentId'
        id_name: 'id',
        parent_name: 'parentId'
    },
        
    initialize: function(tree, options) {
        this._tree = tree;
        this.reset();
    },
    
    reset: function() {
        var root = this;
        root._stack = [];
        // store lvl 0 backpoints into stack
        _.each(this._tree.models, function(model, index) {
            if (! _.isNumber( model.get(root.options.parent_name) ) ||
                  model.get(root.options.parent_name) == 0) {
                root._stack.push( root.getBackpoint(0, index) );
            }
        });
    },
    
    getBackpoint: function(level, index) {
...