Revize c044ee46
Přidáno uživatelem Pavel Fidranský před více než 6 roky(ů)
sources/src/main/webapp/css/main.css | ||
---|---|---|
120 | 120 |
cursor: pointer; |
121 | 121 |
} |
122 | 122 |
|
123 |
.header .username { |
|
124 |
margin-right: 5px; |
|
125 |
} |
|
126 |
|
|
123 | 127 |
/* login popup */ |
124 | 128 |
|
125 | 129 |
.header .login_popup { |
sources/src/main/webapp/js/components/floatingPoint.js | ||
---|---|---|
87 | 87 |
var viewportPosition = app.viewportComponent.getPosition(); |
88 | 88 |
|
89 | 89 |
position.x = (bbox.left - viewportPosition.x); |
90 |
position.y = (bbox.top - viewportPosition.y - app.headerHeight);
|
|
90 |
position.y = (bbox.top - viewportPosition.y - app.headerComponent.height - app.navbarComponent.height);
|
|
91 | 91 |
|
92 | 92 |
if (node instanceof Vertex) { |
93 | 93 |
var edgeOffsetY = 10; |
sources/src/main/webapp/js/components/group.js | ||
---|---|---|
715 | 715 |
return; |
716 | 716 |
} |
717 | 717 |
|
718 |
switch (document.actionForm.actionMove.value) {
|
|
718 |
switch (document.modeForm.mode.value) {
|
|
719 | 719 |
case 'move': |
720 | 720 |
this.setHighlightedWithNeighbours(!highlighted); |
721 | 721 |
break; |
sources/src/main/webapp/js/components/vertex.js | ||
---|---|---|
696 | 696 |
return; |
697 | 697 |
} |
698 | 698 |
|
699 |
switch (document.actionForm.actionMove.value) {
|
|
699 |
switch (document.modeForm.mode.value) {
|
|
700 | 700 |
case 'move': |
701 | 701 |
this.setHighlightedWithNeighbours(!highlighted); |
702 | 702 |
break; |
sources/src/main/webapp/js/showGraphApp.js | ||
---|---|---|
21 | 21 |
/** @prop {string} HOME_URL Application home URL. */ |
22 | 22 |
this.HOME_URL = appHomeUrl; |
23 | 23 |
|
24 |
/** @prop {float} headerHeight Current height of the application header. */ |
|
25 |
this.headerHeight = getHeaderHeight(); |
|
26 |
|
|
27 | 24 |
/** @prop {Sidebar} sidebarComponent */ |
28 | 25 |
this.sidebarComponent = null; |
29 | 26 |
/** @prop {Viewport} viewportComponent */ |
... | ... | |
116 | 113 |
* Binds user interactions to local handler functions. |
117 | 114 |
*/ |
118 | 115 |
function bootstrap() { |
119 |
var self = this; |
|
120 |
|
|
121 |
self.loader.enable(); |
|
122 |
|
|
123 |
var content = document.getElementById('content'); |
|
124 |
|
|
125 |
self.viewportComponent = new Viewport; |
|
126 |
content.appendChild(self.viewportComponent.render()); |
|
127 |
|
|
128 |
self.sidebarComponent = new Sidebar; |
|
129 |
content.appendChild(self.sidebarComponent.render()); |
|
130 |
self.sidebarComponent.minimapComponent.setViewportSize(self.viewportComponent.getSize()); |
|
131 |
|
|
132 |
self.modalWindowComponent = new SaveDiagramModalWindow; |
|
133 |
content.appendChild(self.modalWindowComponent.render()); |
|
134 |
|
|
135 |
// auth events |
|
136 |
const usernameLabel = document.getElementById('usernameLabel'); |
|
116 |
this.loader.enable(); |
|
137 | 117 |
|
138 |
document.addEventListener('imiger.userLoggedIn', e => { |
|
139 |
usernameLabel.innerText = e.detail.user.username; |
|
140 |
}); |
|
141 |
document.addEventListener('imiger.userLoggedOut', () => { |
|
142 |
usernameLabel.innerText = ''; |
|
143 |
}); |
|
118 |
this.headerComponent = new Header; |
|
119 |
this.navbarComponent = new Navbar; |
|
120 |
this.viewportComponent = new Viewport; |
|
121 |
this.sidebarComponent = new Sidebar; |
|
122 |
this.modalWindowComponent = new SaveDiagramModalWindow; |
|
123 |
|
|
124 |
const appElement = document.getElementById('app'); |
|
125 |
appElement.appendChild(this.headerComponent.render()); |
|
126 |
appElement.appendChild(this.navbarComponent.render()); |
|
127 |
appElement.appendChild(DOM.h('main', { |
|
128 |
class: 'graph-content', |
|
129 |
id: 'content', |
|
130 |
}, [ |
|
131 |
this.viewportComponent.render(), |
|
132 |
this.sidebarComponent.render(), |
|
133 |
])); |
|
134 |
appElement.appendChild(this.modalWindowComponent.render()); |
|
135 |
|
|
136 |
this.sidebarComponent.minimapComponent.setViewportSize(this.viewportComponent.getSize()); |
|
144 | 137 |
|
145 | 138 |
// diagram |
146 | 139 |
document.addEventListener('imiger.diagramUpdated', e => { |
147 | 140 |
this.diagram = new Diagram(e.detail); |
148 | 141 |
|
149 |
document.title = this.name + ' - ' + this.diagram.name;
|
|
150 |
history.replaceState({} , document.title, this.homeUrl + 'graph?diagramId=' + this.diagram.id);
|
|
142 |
document.title = this.NAME + ' - ' + this.diagram.name;
|
|
143 |
history.replaceState({} , document.title, this.HOME_URL + 'graph?diagramId=' + this.diagram.id);
|
|
151 | 144 |
}); |
152 | 145 |
|
153 | 146 |
// context menu |
154 |
document.body.addEventListener('mousedown', function() {
|
|
155 |
self.closeFloatingComponents();
|
|
147 |
document.body.addEventListener('mousedown', () => {
|
|
148 |
this.closeFloatingComponents();
|
|
156 | 149 |
}); |
157 | 150 |
|
158 | 151 |
// zoom |
159 |
document.getElementById('zoomIn').addEventListener('click', function(e) { |
|
160 |
self.zoom.zoomIn(); |
|
161 |
}); |
|
162 |
|
|
163 |
document.getElementById('zoomOut').addEventListener('click', function(e) { |
|
164 |
self.zoom.zoomOut(); |
|
165 |
}); |
|
166 |
|
|
167 |
document.getElementById('zoomValue').innerText = Math.round(self.zoom.scale * 100) + '%'; |
|
168 |
document.getElementById('graph').setAttribute('transform', 'scale(' + self.zoom.scale + ')'); |
|
169 |
|
|
170 |
// search |
|
171 |
document.getElementById('searchText').addEventListener('keyup', function(e) { |
|
172 |
// enter key |
|
173 |
if (e.keyCode === 13) { |
|
174 |
search(this.value); |
|
175 |
return; |
|
176 |
} |
|
177 |
|
|
178 |
// escape key |
|
179 |
if (e.keyCode === 27) { |
|
180 |
resetSearch(); |
|
181 |
return; |
|
182 |
} |
|
183 |
}); |
|
184 |
|
|
185 |
document.getElementById('search').addEventListener('click', function(e) { |
|
186 |
search(document.getElementById('searchText').value); |
|
187 |
}); |
|
188 |
|
|
189 |
document.getElementById('countOfFound').addEventListener('click', resetSearch); |
|
190 |
|
|
191 |
function search(term) { |
|
192 |
if (term.length < 2) return; |
|
193 |
|
|
194 |
var found = 0; |
|
195 |
|
|
196 |
var nodeList = self.viewportComponent.getNodeList(); |
|
197 |
nodeList.forEach(function(node) { |
|
198 |
if (!node.name.toLowerCase().includes(term.toLowerCase())) { |
|
199 |
node.setFound(false); |
|
200 |
|
|
201 |
} else { |
|
202 |
node.setFound(true); |
|
203 |
|
|
204 |
found++; |
|
205 |
} |
|
206 |
}); |
|
207 |
|
|
208 |
document.getElementById('countOfFound').innerText = found; |
|
209 |
} |
|
210 |
|
|
211 |
function resetSearch(e) { |
|
212 |
var nodeList = self.viewportComponent.getNodeList(); |
|
213 |
nodeList.forEach(function(node) { |
|
214 |
node.setFound(false); |
|
215 |
}); |
|
216 |
|
|
217 |
document.getElementById('searchText').value = ''; |
|
218 |
document.getElementById('countOfFound').innerText = 0; |
|
219 |
} |
|
220 |
|
|
221 |
// exclude vertices with most edges button |
|
222 |
document.getElementById('mostEdge').addEventListener('click', function(e) { |
|
223 |
var vertexList = self.viewportComponent.getVertexList(); |
|
224 |
if (vertexList.length === 0) return; |
|
225 |
|
|
226 |
var vertexWithMostEdges = vertexList.reduce(function(prev, vertex) { |
|
227 |
return vertex.countEdges() > prev.countEdges() ? vertex : prev; |
|
228 |
}); |
|
229 |
|
|
230 |
if (vertexWithMostEdges !== null) { |
|
231 |
vertexWithMostEdges.exclude(); |
|
232 |
self.sidebarComponent.excludedNodeListComponent.add(vertexWithMostEdges); |
|
233 |
} |
|
234 |
}); |
|
235 |
|
|
236 |
// exclude vertices with most edges to group button |
|
237 |
document.getElementById('vertexToGroup').addEventListener('click', function(e) { |
|
238 |
var vertexList = self.viewportComponent.getVertexList(); |
|
239 |
if (vertexList.length === 0) return; |
|
240 |
|
|
241 |
var vertexWithMostEdges = vertexList.reduce(function(prev, vertex) { |
|
242 |
return vertex.countEdges() > prev.countEdges() ? vertex : prev; |
|
243 |
}); |
|
244 |
|
|
245 |
var verticesWithMostEdges = vertexList.filter(function(vertex) { |
|
246 |
return vertex.countEdges() === vertexWithMostEdges.countEdges(); |
|
247 |
}); |
|
248 |
|
|
249 |
if (verticesWithMostEdges.length > 0) { |
|
250 |
var group = new Group({}); |
|
251 |
|
|
252 |
verticesWithMostEdges.forEach(function(vertex) { |
|
253 |
group.addVertex(vertex); |
|
254 |
}); |
|
255 |
|
|
256 |
self.nodeList.push(group); |
|
257 |
self.groupList.push(group); |
|
258 |
|
|
259 |
self.viewportComponent.addGroup(group); |
|
260 |
} |
|
261 |
}); |
|
262 |
|
|
263 |
// apply force-directed layout |
|
264 |
var layouting = false; |
|
265 |
var layoutingInterval; |
|
266 |
|
|
267 |
document.getElementById('applyLayout').addEventListener('click', function() { |
|
268 |
if (layouting) { |
|
269 |
document.getElementById('applyLayoutImg').setAttribute('src', 'images/layout_off.png'); |
|
270 |
|
|
271 |
layouting = false; |
|
272 |
clearInterval(layoutingInterval); |
|
273 |
|
|
274 |
} else { |
|
275 |
document.getElementById('applyLayoutImg').setAttribute('src', 'images/layout_on.png'); |
|
276 |
|
|
277 |
layouting = true; |
|
278 |
layoutingInterval = window.setInterval(self.viewportComponent.forceDirected.run, 10); |
|
279 |
} |
|
280 |
}); |
|
281 |
|
|
282 |
// save as PNG button |
|
283 |
document.getElementById('btnSaveDiagram').addEventListener('click', function(e) { |
|
284 |
saveSvgAsPng(document.getElementById('svg1'), 'diagram.png', { |
|
285 |
scale: 1, |
|
286 |
}); |
|
287 |
}); |
|
288 |
|
|
289 |
// save to database button |
|
290 |
document.getElementById('btnSaveDiagramToDatabase').addEventListener('click', function(e) { |
|
291 |
self.modalWindowComponent.open(); |
|
292 |
}); |
|
152 |
document.getElementById('zoomValue').innerText = Math.round(this.zoom.scale * 100) + '%'; |
|
153 |
document.getElementById('graph').setAttribute('transform', 'scale(' + this.zoom.scale + ')'); |
|
293 | 154 |
|
294 | 155 |
// window resize |
295 |
window.addEventListener('resize', function(e) { |
|
296 |
self.headerHeight = getHeaderHeight(); |
|
297 |
self.redrawEdges(); |
|
298 |
|
|
299 |
self.sidebarComponent.minimapComponent.setViewportSize(self.viewportComponent.getSize()); |
|
156 |
window.addEventListener('resize', e => { |
|
157 |
this.redrawEdges(); |
|
158 |
this.sidebarComponent.minimapComponent.setViewportSize(this.viewportComponent.getSize()); |
|
300 | 159 |
}); |
301 | 160 |
} |
302 | 161 |
|
... | ... | |
349 | 208 |
window.location.replace('./'); |
350 | 209 |
} |
351 | 210 |
} |
352 |
|
|
353 |
/** |
|
354 |
* @returns {integer} Height of the header. |
|
355 |
*/ |
|
356 |
function getHeaderHeight() { |
|
357 |
return document.getElementById('header').offsetHeight; |
|
358 |
} |
|
359 | 211 |
} |
sources/src/main/webapp/showGraph.jsp | ||
---|---|---|
1 | 1 |
<%@page contentType="text/html" pageEncoding="UTF-8"%> |
2 | 2 |
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> |
3 | 3 |
|
4 |
<c:set var="HOME_URL" value="${initParam.HOME_URL}"/> |
|
4 |
<c:set var="APP_NAME" value="IMiGEr"/> |
|
5 |
<c:set var="APP_HOME_URL" value="${initParam.HOME_URL}"/> |
|
5 | 6 |
<c:set var="isLoggedIn" value="${sessionScope.isLoggedIn}"/> |
6 | 7 |
<c:set var="user" value="${sessionScope.user}"/> |
7 | 8 |
|
... | ... | |
30 | 31 |
<script src="js/components/floatingPoint.js"></script> |
31 | 32 |
<script src="js/components/group.js"></script> |
32 | 33 |
<script src="js/components/groupVertexList.js"></script> |
34 |
<script src="js/components/header.js"></script> |
|
33 | 35 |
<script src="js/components/loginPopup.js"></script> |
34 | 36 |
<script src="js/components/minimap.js"></script> |
37 |
<script src="js/components/navbar.js"></script> |
|
35 | 38 |
<script src="js/components/registerPopup.js"></script> |
36 | 39 |
<script src="js/components/saveDiagramModalWindow.js"></script> |
37 | 40 |
<script src="js/components/sidebar.js"></script> |
... | ... | |
62 | 65 |
<script src="js/valueObjects/diagram.js"></script> |
63 | 66 |
<script src="js/valueObjects/dimensions.js"></script> |
64 | 67 |
|
65 |
<script src="js/userMenu.js"></script> |
|
66 | 68 |
<script src="js/markSymbol.js"></script> |
67 | 69 |
<script src="js/constants.js"></script> |
68 | 70 |
<script src="js/showGraphApp.js"></script> |
... | ... | |
71 | 73 |
</head> |
72 | 74 |
|
73 | 75 |
<body class="${isLoggedIn ? 'loggedIn' : 'loggedOut'}"> |
74 |
<div class="wrapper"> |
|
75 |
<header class="header" id="header"> |
|
76 |
<img src="images/logo.png" class="header-logo" alt="logo of University of West Bohemia" title="University of West Bohemia"> |
|
77 |
|
|
78 |
<h2 class="header-title">Interactive Multimodal Graph Explorer</h2> |
|
79 |
|
|
80 |
<%@ include file="userMenu.jsp" %> |
|
81 |
|
|
82 |
<nav class="navbar" id="navigation"> |
|
83 |
<ul> |
|
84 |
<li> |
|
85 |
<button class="btn zoom" id="zoomOut" title="zoom-"><img src="images/zoom_out.png" alt="zoom-"></button> |
|
86 |
<span class="zoom-value" id="zoomValue"></span> |
|
87 |
<button class="btn zoom" id="zoomIn" title="zoom+"><img src="images/zoom_in.png" alt="zoom+"></button> |
|
88 |
</li> |
|
89 |
<li> |
|
90 |
<hr class="navbar-separator"> |
|
91 |
</li> |
|
92 |
<li> |
|
93 |
<input class="search-text" id="searchText" type="text" placeholder="Search components..."> |
|
94 |
<button class="btn search" id="search"><img src="images/search.png" title="search" alt="search"></button> |
|
95 |
<span class="search-count" id="countOfFound" title="Count of components found">0</span> |
|
96 |
</li> |
|
97 |
<li> |
|
98 |
<hr class="navbar-separator"> |
|
99 |
</li> |
|
100 |
<li> |
|
101 |
<form name="actionForm"> |
|
102 |
<label for="move"> |
|
103 |
<input type="radio" name="actionMove" value="move" id="move" checked> |
|
104 |
move |
|
105 |
<img class="navbar-image" src="images/move.png" alt="move"> |
|
106 |
</label> |
|
107 |
<label for="remove"> |
|
108 |
<input type="radio" name="actionMove" value="exclude" id="remove"> |
|
109 |
exclude |
|
110 |
<img class="navbar-image" src="images/remove2.png" alt="remove"> |
|
111 |
</label> |
|
112 |
</form> |
|
113 |
</li> |
|
114 |
<li> |
|
115 |
<hr class="navbar-separator"> |
|
116 |
</li> |
|
117 |
<li> |
|
118 |
<button id="mostEdge" class="btn exclude-separately" title="Exclude components with the most count of edges separately."> |
|
119 |
<img src="images/excludeSeparately.png" alt="excludeSeparately"> |
|
120 |
</button> |
|
121 |
</li> |
|
122 |
<li> |
|
123 |
<hr class="navbar-separator"> |
|
124 |
</li> |
|
125 |
<li> |
|
126 |
<button id="vertexToGroup" class="btn exclude-to-group" title="Exclude components with the most count of edges to group."> |
|
127 |
<img src="images/package.png" alt="Exclude components to group"> |
|
128 |
</button> |
|
129 |
</li> |
|
130 |
<li> |
|
131 |
<hr class="navbar-separator"> |
|
132 |
</li> |
|
133 |
<li> |
|
134 |
<a href="${HOME_URL}" class="btn btn-block back-to-upload" id="view_back_to_upload" title="Back to upload"></a> |
|
135 |
</li> |
|
136 |
<li> |
|
137 |
<hr class="navbar-separator"> |
|
138 |
</li> |
|
139 |
<li> |
|
140 |
<button class="btn" id="applyLayout" title="Apply layout to current graph"> |
|
141 |
<img src="images/layout_off.png" id="applyLayoutImg" alt="Apply layout to current graph."> |
|
142 |
</button> |
|
143 |
</li> |
|
144 |
<li> |
|
145 |
<hr class="navbar-separator"> |
|
146 |
</li> |
|
147 |
<li> |
|
148 |
<button class="btn save-diagram" id="btnSaveDiagram" title="Save diagram as PNG"> |
|
149 |
<img src="images/png_save.png" id="applyLayoutImg" alt="Save diagram as PNG."> |
|
150 |
</button> |
|
151 |
</li> |
|
152 |
<li class="loggedInOnly"> |
|
153 |
<hr class="navbar-separator"> |
|
154 |
</li> |
|
155 |
<li class="loggedInOnly"> |
|
156 |
<button class="btn save-diagram" id="btnSaveDiagramToDatabase" title="Save diagram"> |
|
157 |
<img src="images/icon_save.png" id="applyLayoutImg" alt="Save diagram"> |
|
158 |
</button> |
|
159 |
</li> |
|
160 |
<li> |
|
161 |
<hr class="navbar-separator"> |
|
162 |
</li> |
|
163 |
<li> |
|
164 |
<a href="${HOME_URL}graph?diagramId=${param.diagramId}" class="btn btn-block view-refresh-diagram" id="view_refresh_diagram" title="Refresh diagram"></a> |
|
165 |
</li> |
|
166 |
<li> |
|
167 |
<hr class="navbar-separator"> |
|
168 |
</li> |
|
169 |
<li> |
|
170 |
<button class="btn btn-block view-refresh-reset-diagram" id="view_refresh_reset_diagram" title="Refresh diagram - reset position"></button> |
|
171 |
</li> |
|
172 |
</ul> |
|
173 |
</nav> |
|
174 |
</header> |
|
175 |
|
|
176 |
<main class="graph-content" id="content"></main> |
|
177 |
</div> |
|
76 |
<div id="app"></div> |
|
178 | 77 |
|
179 | 78 |
<div class="loader" id="loader"> |
180 | 79 |
<div class="loader-content" id="spinLoader"> |
... | ... | |
183 | 82 |
</div> |
184 | 83 |
|
185 | 84 |
<script> |
186 |
const app = new ShowGraphApp('${APP_NAME}', '${APP_HOME_URL}'); |
|
85 |
const app = new ShowGraphApp('${APP_NAME}', '${APP_HOME_URL}'); |
|
86 |
|
|
87 |
document.addEventListener('DOMContentLoaded', () => { |
|
88 |
let loaderFn = app.diagramLoader('${param.diagramId}'); |
|
187 | 89 |
|
188 |
document.addEventListener('DOMContentLoaded', () => { |
|
189 |
var loaderFn = app.diagramLoader('${param.diagramId}'); |
|
90 |
app.run(loaderFn); |
|
190 | 91 |
|
191 |
app.run(loaderFn); |
|
192 |
}); |
|
92 |
// user is logged in |
|
93 |
if ('${user}' !== '') { |
|
94 |
document.dispatchEvent(new LoggedInEvent({ |
|
95 |
id: '${user.id}', |
|
96 |
username: '${user.username}', |
|
97 |
})); |
|
98 |
} |
|
99 |
}); |
|
193 | 100 |
</script> |
194 | 101 |
</body> |
195 | 102 |
</html> |
sources/src/main/webapp/uploadFiles.jsp | ||
---|---|---|
41 | 41 |
<h2 class="header-title">Interactive Multimodal Graph Explorer</h2> |
42 | 42 |
|
43 | 43 |
<div class="user-menu loggedInOnly"> |
44 |
<span id="usernameLabel">${user.username}</span> |
|
44 |
<span class="username" id="usernameLabel">${user.username}</span>
|
|
45 | 45 |
<button class="button" id="logoutButton">Log out</button> |
46 | 46 |
</div> |
47 | 47 |
|
Také k dispozici: Unified diff
modified ShowGraphApp to use newly created Header and Navbar JS classes