Skip to content

Commit 07fc995

Browse files
Folding less relevant nodes
1 parent fdc5be8 commit 07fc995

File tree

5 files changed

+127
-25
lines changed

5 files changed

+127
-25
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "iknow-entity-browser",
3-
"version": "0.1.1",
3+
"version": "0.2.0",
44
"description": "Visualizer for iKnow entities",
55
"main": "gulpfile.babel.js",
66
"scripts": {

src/static/js/graph/index.js

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { updateSelectedNodes } from "../tabular";
21
import { getGraphData } from "../model";
32
import { updateSelection, setLastSelectedNode } from "../selection";
43

@@ -131,35 +130,80 @@ export function init () {
131130
.on("keyup", keyUp);
132131
}
133132

133+
function flatten (root) {
134+
135+
let nodes = [];
136+
137+
function recurse (node) {
138+
if (node.children) node.children.forEach(recurse);
139+
// if (!node.id) node.id = ++i;
140+
nodes.push(node);
141+
}
142+
143+
recurse(root);
144+
145+
return nodes;
146+
147+
}
148+
149+
function flattenEdges (root) {
150+
151+
let edges = [];
152+
153+
function recurse (node) {
154+
if (!node.children)
155+
return;
156+
for (let c of node.children) {
157+
recurse(c);
158+
edges.push({ source: node, target: c, type: c.edgeType });
159+
}
160+
}
161+
162+
recurse(root);
163+
164+
return edges;
165+
166+
}
167+
134168
export function update (reset = false) {
135169

136-
let graph = getGraphData();
170+
let g = getGraphData().foldedTree,
171+
fl = flatten(g),
172+
graph = {
173+
nodes: fl,
174+
edges: flattenEdges(g)
175+
};
137176

138177
if (reset) {
139-
link = link.data([]);
140-
link.exit().remove();
141-
node = node.data([]);
142-
node.exit().remove();
178+
// link = link.data([]);
179+
// link.exit().remove();
180+
// node = node.data([]);
181+
// node.exit().remove();
143182
}
144183

145-
link = link
146-
.data(graph.edges, (d) => `${ d.source }-${ d.target }`);
184+
link = links.selectAll("line").data(graph.edges, (d) => d.target.id);
147185
link.exit().remove();
148-
link = link.enter().append("line")
186+
let linkEnter = link.enter().append("line")
149187
.attr("class", d => d.type === "similar"
150188
? "similar"
151189
: d.type === "related"
152190
? "related"
153191
: "other"
154192
);
193+
link = linkEnter.merge(link);
155194

156-
node = node
157-
.data(graph.nodes, (d) => d.id);
195+
node = nodes.selectAll(".node").data(graph.nodes, (d) => d.id);
158196
node.exit().remove();
159-
node = node.enter().append("g")
160-
.attr("class", "node")
197+
let nodeEnter = node.enter().append("g")
198+
.attr("class", d => `node ${ d.type || "unknown" }`)
161199
.call(dragger)
162-
.on("dblclick", () => d3.event.stopPropagation())
200+
.on("dblclick", (d) => {
201+
d3.event.stopPropagation();
202+
if (d.type === "folder" && d._children && d._children.length) {
203+
d.children = d._children;
204+
update();
205+
}
206+
})
163207
.on("click", function (d) {
164208
if (d3.event.defaultPrevented) return;
165209
if (!ctrlKey) {
@@ -170,16 +214,14 @@ export function update (reset = false) {
170214
updateSelection();
171215
});
172216

173-
node.append("circle")
217+
nodeEnter.append("circle")
174218
.attr("r", d => d.radius);
175219

176-
node.append("text")
220+
nodeEnter.append("text")
177221
.attr("dy", ".3em")
178222
.attr("style", d => `font-size:${ Math.round(d.radius / 2) }px`)
179223
.text(d => d.label);
180-
181-
node.exit().remove();
182-
link.exit().remove();
224+
node = nodeEnter.merge(node);
183225

184226
simulation
185227
.nodes(graph.nodes)
@@ -196,6 +238,8 @@ export function update (reset = false) {
196238

197239
brush.select('.overlay').style('cursor', 'auto');
198240

199-
for (let i = 100; i > 0; --i) simulation.tick();
241+
if (reset) {
242+
for (let i = 100; i > 0; --i) simulation.tick();
243+
}
200244

201245
}

src/static/js/model/index.js

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,53 @@ import { getData, getOption } from "../source";
33
import { toggleLoader } from "../utils";
44

55
let SIZE_CRITERIA = "frequency",
6-
FOLDING_CRITERIA = "frequency";
6+
FOLDING_CRITERIA = "frequency",
7+
MAX_CHILDREN = 20;
8+
9+
function fold (tree) {
10+
if (!tree.children || tree.children.length <= MAX_CHILDREN)
11+
return tree;
12+
for (let cld of tree.children) {
13+
fold(cld);
14+
}
15+
let rest = tree.children.splice(MAX_CHILDREN);
16+
tree.children.push({
17+
label: "...",
18+
type: "folder",
19+
_children: rest,
20+
radius: 10,
21+
entities: [],
22+
id: Math.random()
23+
});
24+
return tree;
25+
}
26+
27+
function toTree (graph, parent) {
28+
parent.children = [];
29+
for (let edge of graph.edges) {
30+
if (edge.source !== parent.id)
31+
continue;
32+
let t = null;
33+
for (let node of graph.nodes) {
34+
if (node.id === edge.target) {
35+
t = node;
36+
break;
37+
}
38+
}
39+
if (t) {
40+
t.edgeType = edge.type;
41+
parent.children.push(toTree(graph, t));
42+
}
43+
}
44+
parent.children.sort((a, b) => a[FOLDING_CRITERIA] > b[FOLDING_CRITERIA] ? 1 : -1);
45+
return parent;
46+
}
747

848
function preprocess (graph) {
949
let zeroID = null;
1050
graph.nodes.forEach(node => { if (!zeroID && node.id === 0) zeroID = node; });
1151
if (!zeroID) {
12-
graph.nodes.push({
52+
graph.nodes.unshift(zeroID = {
1353
id: 0,
1454
label: getOption("seed"),
1555
type: "entity",
@@ -22,7 +62,16 @@ function preprocess (graph) {
2262
graph.nodes.forEach(node =>
2363
node.radius = 5 + Math.sqrt(node.entities[0][SIZE_CRITERIA] / 4 || 25));
2464
console.log(graph);
25-
return graph;
65+
// fold(graph, zeroID);
66+
let tree = toTree(graph, zeroID),
67+
foldedTree = fold(tree);
68+
console.log(tree);
69+
70+
return {
71+
graph: graph,
72+
tree: tree,
73+
foldedTree: foldedTree
74+
};
2675
}
2776

2877
let graph = preprocess(sampleData.graph);

src/static/js/selection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ let selection = [],
66

77
export function updateSelection () {
88

9-
selection = model.getGraphData().nodes.filter(node => !!node.selected);
9+
selection = model.getGraphData().graph.nodes.filter(node => !!node.selected);
1010

1111
if (!selection.length) lastSelectedNode = null;
1212
if (lastSelectedNode && !lastSelectedNode.selected) {

src/static/scss/graph.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,25 @@
2727
circle {
2828
stroke: #fff;
2929
stroke-width: 1px;
30+
fill: red;
31+
}
32+
33+
&.entity circle {
3034
fill: #7ca1ff;
3135
}
3236

37+
&.folder circle {
38+
fill: #b58aff;
39+
}
40+
3341
&.selected circle {
3442
stroke: #000;
3543
}
3644

3745
text {
3846
text-anchor: middle;
3947
pointer-events: none;
48+
fill: black;
4049
}
4150

4251
}

0 commit comments

Comments
 (0)