Skip to content

Commit 86e1fd8

Browse files
authored
Merge pull request #193 from studycloud/bugfix_tree_resource_duplication
Bugfix tree resource duplication
2 parents be30570 + 607ddcf commit 86e1fd8

File tree

3 files changed

+89
-16
lines changed

3 files changed

+89
-16
lines changed

app/Http/Controllers/GetTree.php

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,30 +80,45 @@ public function __invoke(Request $request)
8080
],
8181
'levels_up' => 'nullable|integer|min:0',
8282
'levels_down' => 'nullable|integer|min:0',
83+
'ancestor_resources' => 'nullable|boolean'
8384
]);
8485

8586
// now, retrieve the input
8687
$node_id = $request->input('id');
8788
$node_id = is_null($node_id) ? 0 : $node_id;
8889
$up = $request->input('levels_up');
8990
$down = $request->input('levels_down');
91+
$ancestor_resources = $request->input('ancestor_resources');
92+
$ancestor_resources = is_null($ancestor_resources) ? false : $ancestor_resources;
9093

91-
return $this->show($node_id, $up, $down);
94+
return $this->show($node_id, $up, $down, $ancestor_resources);
9295
}
9396

9497
/**
9598
* converts a portion of the tree to JSON for traversal by the JavaScript team
96-
* @param integer $node_id the id of the current node in the tree; defaults to the root of the tree, which has an id of 0
97-
* @param int|null $levels_up the number of ancestor levels of the tree to return; defaults to infinity
98-
* @param int|null $levels_down the number of descendant levels of the tree to return; defaults to infinity
99+
* @param integer $node_id the id of the current node in the tree; defaults to the root of the tree, which has an id of 0
100+
* @param int|null $levels_up the number of ancestor levels of the tree to return; defaults to infinity
101+
* @param int|null $levels_down the number of descendant levels of the tree to return; defaults to infinity
102+
* @param bool|null $ancestor_resources whether to return the resources of the ancestors; defaults to true
99103
* @return Collection the nodes and connections of the target portion of the tree
100104
*/
101-
public function show($node_id = 0, int $levels_up = null, int $levels_down = null)
105+
public function show($node_id = 0, int $levels_up = null, int $levels_down = null, bool $ancestor_resources = false)
102106
{
103-
// first, get the required data
104-
$this->getNodes($node_id, $levels_up, $levels_down);
107+
// first, get the required descendants (and the current node)
108+
$this->getDescendantNodes($node_id, $levels_down);
109+
// now, get the node_ids, since we'll need to get resources for them
110+
$node_ids = $this->tree->pluck('id');
111+
// next, get the ancestor nodes
112+
$this->getAncestorNodes($node_id, $levels_up);
105113
// then, convert the data to the nodes/connections format
106-
$node_ids = $this->convertFormat();
114+
if ($ancestor_resources)
115+
{
116+
$node_ids = $this->convertFormat();
117+
}
118+
else
119+
{
120+
$this->convertFormat();
121+
}
107122

108123
// get the converted resources of each node in the tree
109124
$resources = $this->getResourceNodes($node_ids);
@@ -122,18 +137,34 @@ public function show($node_id = 0, int $levels_up = null, int $levels_down = nul
122137
* @param int|null $levels_up the number of ancestor levels of the tree to return; defaults to infinity
123138
* @param int|null $levels_down the number of descendant levels of the tree to return; defaults to infinity
124139
*/
125-
private function getNodes($node_id, $levels_up, $levels_down)
140+
private function getAncestorNodes($node_id, $levels_up)
141+
{
142+
$root = $this->model_name::getRoot();
143+
$node = null;
144+
if ($node_id != 0)
145+
{
146+
$node = $this->model_name::find($node_id);
147+
}
148+
// get ancestors
149+
$this->tree = (new $this->repo)->ancestors($node, $levels_up, $root)->merge($this->tree);
150+
}
151+
152+
/**
153+
* get the raw nodes and connections data
154+
* @param integer $node_id the id of the current node in the tree; defaults to the root of the tree, which has an id of 0
155+
* @param int|null $levels_up the number of ancestor levels of the tree to return; defaults to infinity
156+
* @param int|null $levels_down the number of descendant levels of the tree to return; defaults to infinity
157+
*/
158+
private function getDescendantNodes($node_id, $levels_down)
126159
{
127160
$root = $this->model_name::getRoot();
128161
$node = null;
129162
if ($node_id != 0)
130163
{
131164
$node = $this->model_name::find($node_id);
132165
}
133-
// get the ancestors and descendants of this node in a flat collection
134-
$this->tree = (new $this->repo)->ancestors($node, $levels_up, $root)->merge(
135-
(new $this->repo)->descendants($node, $levels_down, $root)
136-
);
166+
// get the descendants
167+
$this->tree = (new $this->repo)->descendants($node, $levels_down, $root);
137168
// add the current node to the data
138169
// but use the root if the current node is null
139170
$this->tree->prepend(collect(is_null($node) ? $root : $node));

public/js/Tree.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ Tree.prototype.getNLevelIds = function(node_id, levels_num)
191191

192192
Tree.prototype.getIDLevelMaps = function(node_id, levels_up_num, levels_down_num)
193193
{
194+
//This functions returns maps from node_id to level for the tree. This essentially creates a labeled form of the tree.
195+
//It returns levels_up_num straight up the tree (can only be non-resources)
196+
//It return levels_down_num down the tree of nodes, and then one more level of resources.
197+
// If you ask for 3 levels down, you get 3 levels of nodes, and 1 more level of only resources.
198+
194199
var self = this;
195200

196201
var ID_Level_Map = d3.map();
@@ -251,10 +256,31 @@ Tree.prototype.getIDLevelMapTraverseDown = function(IDLevelMap, node_id, levels_
251256
IDLevelMap.set(node_id, levels_traversed);
252257

253258
if (levels_down_num === 0)
259+
{
260+
//now do one pass just for resources.
261+
262+
//We are searching for children, so check if our current node is a parent of any nodes, and traverse downwards
263+
self.links.data().forEach(function (link)
264+
{
265+
if (link.source.id === node_id && link.target.id[0] === 'r')
266+
{
267+
//We found a resource child!!
268+
//A child is any node that has a link that originates at our node
269+
self.getIDLevelMapTraverseDown(IDLevelMap, link.target.id, levels_down_num - 1, levels_traversed + 1);
270+
}
271+
}
272+
);
273+
274+
return;
275+
}
276+
277+
if (levels_down_num === -1)
254278
{
255279
//there are no more children to find
256280
return;
257281
}
282+
283+
258284

259285
//We are searching for children, so check if our current node is a parent of any nodes, and traverse downwards
260286
self.links.data().forEach(function (link)
@@ -379,6 +405,8 @@ Tree.prototype.updateDataNodes = function(selection, data)
379405
.on("click", function(){self.nodeClicked(this);})
380406
.on('contextmenu', function(d, i){self.menuContextNodeOpen(this, d, i);});
381407

408+
console.log("Added nodes: ", nodes_enter);
409+
382410
nodes_enter.append("rect");
383411
nodes_enter.append("text");
384412

@@ -402,8 +430,8 @@ Tree.prototype.updateDataNodes = function(selection, data)
402430

403431
var coordinates =
404432
{
405-
x: 0,
406-
y: 0,
433+
x: self.frame.boundary.width/2,
434+
y: self.frame.boundary.height/2,
407435
fx: null,
408436
fy: null,
409437
x_new: null,
@@ -521,6 +549,7 @@ Tree.prototype.updateDataNLevels = function(node_id, levels_up_num, levels_down_
521549

522550
console.log("Updating data for N Levels with:", node_id, levels_up_num, levels_down_num, data);
523551

552+
self.simulation.stop();
524553

525554
var nodes_updated_map;
526555

@@ -939,7 +968,7 @@ Tree.prototype.centerOnNode = function(node)
939968
self.nodes_simulated = self.nodes.filter(function(d)
940969
{
941970
var style = self.locals.style.get(this);
942-
return style.level !== undefined;
971+
return (style.level >= -1 && style.level <= 2);
943972
}
944973
);
945974
self.links_simulated = self.links.filter(function(d)

public/js/topics.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,19 @@ var data =
164164
]
165165
};
166166

167+
var data =
168+
{
169+
"nodes": [
170+
{
171+
"name": "Topic Root",
172+
"author_id": 1,
173+
"created_at": "2017-11-02 21:02:03",
174+
"updated_at": "2017-11-02 21:02:03",
175+
"id": "t0"
176+
}],
177+
"connections": []
178+
}
179+
167180
var connections = data.connections;
168181
var IDNodeMap = d3.map(data.nodes, function (d) { return d.id; });
169182

0 commit comments

Comments
 (0)