Skip to content

Commit 2c2a873

Browse files
Rest client binding, diagram refresh, settings, loader add, etc
1 parent e32a35d commit 2c2a873

File tree

13 files changed

+3951
-132
lines changed

13 files changed

+3951
-132
lines changed

README.md

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Preview
66
-------
77

88
![Screenshot](https://cloud.githubusercontent.com/assets/4989256/20325678/5efeecde-ab8e-11e6-8d8d-f4955a1afa4d.png)
9+
![Screenshot](https://cloud.githubusercontent.com/assets/4989256/20610106/becaeac6-b29d-11e6-987b-670998ac048e.png)
910

1011
Usage
1112
-----
@@ -39,3 +40,13 @@ gulp
3940
```
4041

4142
Then, open `build/static/index.html` file.
43+
44+
To install test REST client, run the following:
45+
46+
```bash
47+
import
48+
```
49+
50+
This will put `src/cls/EntityBrowser/Router.cls` class into your Caché (change the `import.*`
51+
script), and after you set up a web application, go to configure app settings by clicking setting
52+
button in the top right corner.

package.json

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

src/cls/EntityBrowser/Router.cls

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ ClassMethod AppendChildObjects(ByRef pObjects, ByRef pGraph, ByRef pEntityTokens
312312
}
313313
set tNodeObj = {"id": (tNodeID), "label": (pEntityTokens(tEntIDx)), "type": "entity", "entities": [ (tEntObj) ]}
314314
do pObjects.nodes.%Push(tNodeObj)
315-
set tEdgeObj = {"origin": (pParentNodeID), "destination": (tNodeID), "type": (tEdgeType)}
315+
set tEdgeObj = {"source": (pParentNodeID), "target": (tNodeID), "type": (tEdgeType)}
316316
do pObjects.edges.%Push(tEdgeObj)
317317

318318
set tSC = ..AppendChildObjects(.pObjects, .pGraph, .pEntityTokens, tNodeID, pLevel+1)

src/static/index.html

+16
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ <h1>Selected Nodes</h1>
7070
</div>
7171
<div id="settings">
7272
<i id="closeSettingsToggle" class="ui icon-close"></i>
73+
<h1>General Settings</h1>
74+
<div>
75+
<div>
76+
<b>Data source:</b>
77+
<input type="text" value="http://localhost" id="settings.host" autosize placeholder="http://host.name"/>
78+
: <input id="settings.port" autosize type="number" placeholder="port" value="57772"/>
79+
/ <input id="settings.webAppName" type="text" placeholder="domain" value="EntityBrowser"/>
80+
/domain/ <input id="settings.domain" type="text" placeholder="domain" value="1"/>
81+
/
82+
<select id="settings.queryType">
83+
<option value="related">related</option>
84+
<option value="similar">similar</option>
85+
</select>
86+
/ <input autosize placeholder="seed string" id="settings.seed" value="crew"/>
87+
</div>
88+
</div>
7389
</div>
7490
</div>
7591
</body>

src/static/js/graph/index.js

+134-125
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,27 @@ import { updateSelectedNodes } from "../tabular";
22
import { getGraphData } from "../model";
33
import { updateSelection, setLastSelectedNode } from "../selection";
44

5-
export function update () {
6-
7-
var graph = getGraphData();
8-
9-
var shiftKey, ctrlKey,
10-
width = window.innerWidth,
11-
height = window.innerHeight;
12-
13-
var zoomer = d3.zoom()
14-
.scaleExtent([1/4, 40])
5+
let shiftKey, ctrlKey,
6+
width = window.innerWidth,
7+
height = window.innerHeight,
8+
foreverUniq = 0;
9+
10+
let svg = null,
11+
brush = null,
12+
node,
13+
link,
14+
links,
15+
nodes,
16+
zoomer = d3.zoom()
17+
.scaleExtent([1/4, 100])
1518
.on("zoom", () => {
1619
view.attr("transform", d3.event.transform);
17-
});
18-
19-
var dragger = d3.drag()
20+
}),
21+
dragger = d3.drag()
2022
.on("start", dragstarted)
2123
.on("drag", dragged)
22-
.on("end", dragended);
23-
24-
d3.select(window)
25-
.on("keydown", keyDown)
26-
.on("keyup", keyUp);
27-
28-
var svg = d3.select("#graph")
29-
.call(zoomer);
30-
31-
var view = svg
32-
.append("g")
33-
.attr("class", "view");
34-
35-
var brush = view.append("g")
36-
.datum(() => { return { selected: false, previouslySelected: false }; })
37-
.attr("class", "brush");
38-
39-
// var color = d3.scaleOrdinal(d3.schemeCategory20);
40-
41-
var simulation = d3.forceSimulation()
24+
.on("end", dragended),
25+
simulation = d3.forceSimulation()
4226
.force("link",
4327
d3.forceLink()
4428
.distance(d => 50 + (d.source.radius + d.target.radius) * 2)
@@ -48,25 +32,125 @@ export function update () {
4832
d3.forceManyBody()
4933
.strength(d => { return -10 * d.radius; })
5034
)
51-
.force("center", d3.forceCenter(width / 2, height / 2));
35+
.force("center", d3.forceCenter(width / 2, height / 2)),
36+
brusher = d3.brush()
37+
.extent([[-9999999, -9999999], [9999999, 9999999]])
38+
.on("start.brush", () => {
39+
if (!d3.event.sourceEvent) return;
40+
node.each((d) => {
41+
d.previouslySelected = ctrlKey && d.selected;
42+
});
43+
})
44+
.on("brush.brush", () => {
45+
if (!d3.event.sourceEvent) return;
46+
let extent = d3.event.selection;
47+
if (!extent)
48+
return;
49+
node.classed("selected", (d) => {
50+
let selected = (extent[0][0] <= d.x && d.x < extent[1][0]
51+
&& extent[0][1] <= d.y && d.y < extent[1][1]);
52+
if (selected) setLastSelectedNode(d);
53+
return d.selected = d.previouslySelected ^ selected;
54+
});
55+
})
56+
.on("end.brush", () => {
57+
if (!d3.event.sourceEvent) return;
58+
setTimeout(() => {
59+
brush.call(brusher.move, null);
60+
updateSelection();
61+
}, 25);
62+
}),
63+
view = null;
64+
65+
function ticked () {
66+
link
67+
.attr("x1", d => d.source.x)
68+
.attr("y1", d => d.source.y)
69+
.attr("x2", d => d.target.x)
70+
.attr("y2", d => d.target.y);
71+
node
72+
.attr("transform", (d) => `translate(${ d.x },${ d.y })`)
73+
}
74+
75+
function dragstarted (d) {
76+
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
77+
d.fx = d.x;
78+
d.fy = d.y;
79+
}
80+
81+
function dragged (d) {
82+
d.fx = d3.event.x;
83+
d.fy = d3.event.y;
84+
}
85+
86+
function dragended (d) {
87+
if (!d3.event.active) simulation.alphaTarget(0);
88+
d.fx = null;
89+
d.fy = null;
90+
}
91+
92+
function keyDown () {
93+
shiftKey = d3.event.shiftKey || d3.event.metaKey;
94+
ctrlKey = d3.event.ctrlKey;
95+
96+
if (d3.event.keyCode == 67) { // the 'c' key
97+
// do stuff
98+
}
99+
100+
if (ctrlKey) {
101+
brush.select('.overlay').style('cursor', 'crosshair');
102+
brush.call(brusher);
103+
d3.event.preventDefault();
104+
}
105+
}
106+
107+
function keyUp () {
108+
shiftKey = d3.event.shiftKey || d3.event.metaKey;
109+
ctrlKey = d3.event.ctrlKey;
52110

53-
var link = view.append("g")
54-
.attr("class", "links")
55-
.selectAll("line")
56-
.data(graph.edges)
57-
.enter().append("line")
111+
brush.call(brusher)
112+
.on(".brush", null);
113+
114+
brush.select('.overlay').style('cursor', 'auto');
115+
}
116+
117+
export function init () {
118+
svg = d3.select("#graph")
119+
.call(zoomer);
120+
view = svg
121+
.append("g")
122+
.attr("class", "view");
123+
brush = view.append("g")
124+
.datum(() => { return { selected: false, previouslySelected: false }; })
125+
.attr("class", "brush");
126+
links = view.append("g").attr("class", "links");
127+
nodes = view.append("g").attr("class", "nodes");
128+
link = links.selectAll("line");
129+
node = nodes.selectAll(".node");
130+
d3.select(window)
131+
.on("keydown", keyDown)
132+
.on("keyup", keyUp);
133+
}
134+
135+
export function update () {
136+
137+
let graph = getGraphData();
138+
139+
link = link
140+
.data(graph.edges, (d) => foreverUniq++);
141+
link.exit().remove();
142+
link = link.enter().append("line")
58143
.attr("class", d => d.type === "similar"
59144
? "similar"
60145
: d.type === "related"
61146
? "related"
62147
: "other"
63148
);
64149

65-
var node = view.append("g")
66-
.attr("class", "nodes")
67-
.selectAll(".node")
68-
.data(graph.nodes)
69-
.enter().append("g")
150+
node = node
151+
.data(graph.nodes, (d) => foreverUniq++);
152+
node.exit().remove();
153+
node = node.enter().append("g")
70154
.attr("class", "node")
71155
.call(dragger)
72156
.on("dblclick", () => d3.event.stopPropagation())
@@ -80,106 +164,31 @@ export function update () {
80164
updateSelection();
81165
});
82166

83-
var circle = node.append("circle")
167+
node.append("circle")
84168
.attr("r", d => d.radius);
85169

86170
node.append("text")
87171
.attr("dy", ".3em")
88172
.attr("style", d => `font-size:${ Math.round(d.radius / 2) }px`)
89173
.text(d => d.label);
90174

175+
node.exit().remove();
176+
link.exit().remove();
177+
91178
simulation
92179
.nodes(graph.nodes)
93180
.on("tick", ticked);
94181

95182
simulation.force("link")
96183
.links(graph.edges);
97184

98-
var brusher = d3.brush()
99-
.extent([[-9999999, -9999999], [9999999, 9999999]])
100-
.on("start.brush", () => {
101-
if (!d3.event.sourceEvent) return;
102-
node.each((d) => {
103-
d.previouslySelected = ctrlKey && d.selected;
104-
});
105-
})
106-
.on("brush.brush", () => {
107-
if (!d3.event.sourceEvent) return;
108-
var extent = d3.event.selection;
109-
if (!extent)
110-
return;
111-
node.classed("selected", (d) => {
112-
let selected = (extent[0][0] <= d.x && d.x < extent[1][0]
113-
&& extent[0][1] <= d.y && d.y < extent[1][1]);
114-
if (selected) setLastSelectedNode(d);
115-
return d.selected = d.previouslySelected ^ selected;
116-
});
117-
})
118-
.on("end.brush", () => {
119-
if (!d3.event.sourceEvent) return;
120-
setTimeout(() => {
121-
brush.call(brusher.move, null);
122-
updateSelection();
123-
}, 25);
124-
});
185+
simulation.restart();
125186

126187
brush.call(brusher)
127188
.on(".brush", null);
128189

129190
brush.select('.overlay').style('cursor', 'auto');
130191

131-
for (var i = 100; i > 0; --i) simulation.tick();
132-
133-
function ticked () {
134-
link
135-
.attr("x1", d => d.source.x)
136-
.attr("y1", d => d.source.y)
137-
.attr("x2", d => d.target.x)
138-
.attr("y2", d => d.target.y);
139-
node
140-
.attr("transform", (d) => `translate(${ d.x },${ d.y })`)
141-
}
142-
143-
function dragstarted (d) {
144-
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
145-
d.fx = d.x;
146-
d.fy = d.y;
147-
}
148-
149-
function dragged (d) {
150-
d.fx = d3.event.x;
151-
d.fy = d3.event.y;
152-
}
153-
154-
function dragended (d) {
155-
if (!d3.event.active) simulation.alphaTarget(0);
156-
d.fx = null;
157-
d.fy = null;
158-
}
159-
160-
function keyDown () {
161-
shiftKey = d3.event.shiftKey || d3.event.metaKey;
162-
ctrlKey = d3.event.ctrlKey;
163-
164-
if (d3.event.keyCode == 67) { // the 'c' key
165-
// do stuff
166-
}
167-
168-
if (ctrlKey) {
169-
brush.select('.overlay').style('cursor', 'crosshair');
170-
brush.call(brusher);
171-
d3.event.preventDefault();
172-
}
173-
}
174-
175-
function keyUp () {
176-
shiftKey = d3.event.shiftKey || d3.event.metaKey;
177-
ctrlKey = d3.event.ctrlKey;
178-
179-
brush.call(brusher)
180-
.on(".brush", null);
181-
182-
brush.select('.overlay').style('cursor', 'auto');
183-
}
192+
for (let i = 100; i > 0; --i) simulation.tick();
184193

185194
}

src/static/js/index.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
import { update } from "./graph";
1+
import * as graph from "./graph";
22
import * as tabular from "./tabular";
33
import * as details from "./details";
44
import * as settings from "./settings";
5+
import * as source from "./source";
6+
import * as model from "./model";
57

68
window.init = () => {
79

8-
update();
910
tabular.init();
1011
details.init();
1112
settings.init();
13+
source.init();
14+
graph.init();
15+
model.update(() => graph.update());
1216

1317
};

0 commit comments

Comments
 (0)