Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 0d657135

Přidáno uživatelem Pavel Fidranský před více než 6 roky(ů)

dropped old CoCAEx frontend code

Zobrazit rozdíly:

sources/WebContent/old/images/interface.svg
1
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
<!-- Created with Inkscape (http://www.inkscape.org/) -->
3

  
4
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
5
  <g id="layer1">
6
    <rect
7
       width="8.483736"
8
       height="8.0177965"
9
       x="277.91251"
10
       y="144.85161"
11
       id="rect2984"
12
       style="fill:#00aad4;stroke:#000000;stroke-width:0.24770834;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:8.78740132" />
13
    <rect
14
       width="4.383657"
15
       height="2.2156539"
16
       x="275.53561"
17
       y="146.12935"
18
       id="rect2986-7-4"
19
       style="fill:#00aad4;stroke:#000000;stroke-width:0.30870754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:8.78740132" />
20
    <rect
21
       width="4.383657"
22
       height="2.2156539"
23
       x="275.53561"
24
       y="149.50435"
25
       id="rect2986-7-4-0"
26
       style="fill:#00aad4;stroke:#000000;stroke-width:0.30870754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:8.78740132" />
27
  </g>
28
</svg>
sources/WebContent/old/index.jsp
1
<%@page import="cz.zcu.kiv.offscreen.graph.efp.EfpGraphicSettings"%>
2
<%--<%@page import="org.eclipse.jdt.internal.compiler.ast.ForeachStatement"%>--%>
3
<%@page import="org.apache.jasper.tagplugins.jstl.core.ForEach"%>
4
<%@page import="cz.zcu.kiv.comav.loaders.osgi.service.RequiredService"%>
5
<%@page import="sun.reflect.ReflectionFactory.GetReflectionFactoryAction"%>
6
<%@page contentType="text/html" pageEncoding="UTF-8"%>
7
<%@page import="java.util.Map"%>
8
<%@page import="com.google.gson.Gson"%>
9
<%@page import="com.google.gson.GsonBuilder"%>
10

  
11
<!DOCTYPE html>
12
<html>
13
	<head>
14
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
15

  
16
		<link rel="stylesheet" href="styles/libs/jquery-ui/smoothness/jquery-ui-1.10.3.custom.css" media="screen">
17
		<link rel="stylesheet" href="styles/libs/jquery.contextMenu.css" media="screen">
18
		<link rel="stylesheet" href="styles/libs/jquery.qtip.css" media="screen">
19
		<link rel="stylesheet" href="styles/basic.css" media="screen">
20
		<link rel="stylesheet" href="styles/tooltip.css" media="screen">
21
		<link rel="stylesheet" href="styles/tree.css" media="screen">
22
		<link rel="stylesheet" href="styles/dialog.css" media="screen">
23

  
24
		<script src="js/libs/jquery-1.8.3.js"></script>
25
		<script src="js/libs/jquery-ui-1.10.3.custom.js"></script>
26
		<script src="js/libs/jquery.contextMenu.js"></script>
27
		<script src="js/libs/jquery.qtip.js"></script>
28
		<script src="js/libs/jquery.jstree.js"></script>
29
		<script src="js/libs/saveSvgAsPng.js"></script>
30
		<script src="js/libs/spin.js"></script>
31

  
32
		<script src="js/app.js"></script>
33
		<script src="js/util.js"></script>
34
		<script src="js/svgFactory.js"></script>
35
		<script src="js/graphManager.js"></script>
36
		<script src="js/hash.js"></script>
37
		<script src="js/mark.js"></script>
38
		<script src="js/markSymbol.js"></script>
39
		<script src="js/gridMark.js"></script>
40
		<script src="js/group.js"></script>
41
		<script src="js/groupManager.js"></script>
42
		<script src="js/offScreenKiv.js"></script>
43
		<script src="js/zoom.js"></script>
44
		<script src="js/efps.js"></script>
45
		<script src="js/viewportManager.js"></script>
46
		<script src="js/dialog.js"></script>
47
		<script src="js/tooltips.js"></script>
48
		<script src="js/loader.js"></script>
49
		<script src="js/diagram.js"></script>
50
		<script src="js/user.js"></script>
51

  
52
		<title>Visualization of large component diagrams</title>
53
	</head>
54

  
55
	<body>
56
		<%
57
		//String path = request.getContextPath();
58
		String getProtocol=request.getScheme();
59
		String getDomain=request.getServerName();
60
		String getPort=Integer.toString(request.getServerPort());
61
		String getPath = getProtocol+"://"+getDomain+":"+getPort+"/";
62
		String getURI=request.getRequestURI();
63

  
64
		// set graphic settings for EFP graph
65
		ServletContext context = this.getServletContext();
66
		EfpGraphicSettings efpSettings = new EfpGraphicSettings();
67

  
68
		efpSettings.setMinInterfaceDiameter(Integer.valueOf(context.getInitParameter("minInterfaceDiameter")));
69
		efpSettings.setMaxInterfaceDiameter(Integer.valueOf(context.getInitParameter("maxInterfaceDiameter")));
70

  
71
		// JSONize graph settings
72
		GsonBuilder gsonBuilder = new GsonBuilder();
73
		Gson gson = gsonBuilder.create();
74

  
75
		String efpSettingsJson = gson.toJson(efpSettings);
76

  
77
		// logged-in user
78
		boolean logged_user = false;
79
		boolean diagram_id_hash_set = false;
80
		if (request.getSession().getAttribute("logged_user") == "1"){
81
			logged_user = true;
82
		}
83

  
84
		if (request.getParameter("diagram_id")!= null && request.getParameter("diagram_hash") != null) {
85
			diagram_id_hash_set = true;
86
		}
87

  
88
		String diagram_url = "";
89
		boolean show_icon_save = false;
90
		if (logged_user && diagram_id_hash_set) {
91
			diagram_url = "?diagram_id="+ request.getParameter("diagram_id")+"&diagram_hash=" + request.getParameter("diagram_hash");
92
			show_icon_save = true;
93
		}
94

  
95
		boolean is_efp_diagram = false;
96
		if (request.getAttribute("efpPortalRefererUrl") != null) {
97
			is_efp_diagram = true;
98
		}
99
		%>
100

  
101
		<div class="loader" id="loader">
102
			<div class="loader-content" id="spinLoader">
103
				<p>Loading graph...</p>
104
			</div>
105
		</div>
106

  
107
		<div class="dialog" id="dialog" title="Group rename">
108
			<p>Enter new group name:</p>
109

  
110
			<input type="text" name="name" id="groupNameTextarea" />
111
			<br>
112

  
113
			<button type="button" name="button" id="clearNameButton" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="Clear">
114
				<span class="ui-button-text">Clear</span>
115
			</button>
116
		</div>
117

  
118
		<div class="wrapper" id="envelope">
119
			<header class="header" id="header">
120
				<img src="images/logo.png" class="header-logo" alt="logo of University of West Bohemia" title="University of West Bohemia">
121

  
122
				<h2 class="header-title color-blue">Visualization of large component diagrams </h2>
123

  
124
				<% if (!is_efp_diagram) { %>
125
					<jsp:include page="logged_user.jsp" />
126
				<% } %>
127
			</header>
128

  
129
			<nav class="navbar" id="navigation">
130
				<ul>
131
					<li>
132
						<button class="btn zoom" id="zoomOut" title="zoom-"><img src="images/zoom_out.png" alt="zoom-"/></button>
133
						<span class="zoom-value" id="zoomValue">100%</span>
134
						<button class="btn zoom" id="zoomIn" title="zoom+"><img src="images/zoom_in.png" alt="zoom+"/></button>
135
					</li>
136

  
137
					<li><hr class="navbar-separator"></li>
138
					<li>
139
						<input class="search-text" id="searchText" type="text" value="Search components..."/>
140
						<button class="btn search" id="search"><img src="images/search.png" title="search" alt="search"></button>
141
						<span class="search-count" id="countOfFinded" title="Count of components found">0</span>
142
					</li>
143

  
144
					<li><hr class="navbar-separator"></li>
145
					<li>
146
						<form>
147
							<input type="radio" name="actionMove" value="move" id="move" checked><label for="move">move<img class="navbar-image" src="images/move.png" alt="move"></label>
148
							<input type="radio" name="actionMove" value="exclude" id="remove"><label for="remove">exclude<img class="navbar-image" src="images/remove2.png" alt="remove"></label>
149
						</form>
150
					</li>
151

  
152
					<li><hr class="navbar-separator"></li>
153
					<li><button id="mostEdge" class="btn exclude-separately" title="Exclude components with the most count of edges separately."><img src="images/excludeSeparately.png" alt="excludeSeparately"/></button></li>
154

  
155
					<li><hr class="navbar-separator"></li>
156
					<li><button id="vertexToGroup" class="btn exclude-to-group" title="Exclude components with the most count of edges to group."><img src="images/package.png" alt="Exclude components to group"/></button></li>
157

  
158
					<li><hr class="navbar-separator"></li>
159
					<li>
160
						<% if (!is_efp_diagram) { %>
161
							<a href="<%=getServletContext().getInitParameter("HOME_URL")%><%= diagram_url %>" class="btn btn-block back-to-upload" id="view_back_to_upload" title="Back to upload"></a>
162
						<% } else { %>
163
							<a href="<%=request.getAttribute("efpPortalRefererUrl")%>" class="btn btn-block back-to-upload" id="view_back_to_upload" title="Back"></a>
164
						<% } %>
165
					</li>
166

  
167
					<li><hr class="navbar-separator"></li>
168
					<li>
169
						<button class="btn" id="applyLayout" title="Apply layout to current graph.">
170
							<img src="images/layout_off.png" id="applyLayoutImg" alt="Apply layout to current graph.">
171
						</button>
172
					</li>
173

  
174
					<%
175
					if (request.getAttribute("efpPortalEfpNames") != null) {
176
						final Map<String, String> efpMappings = (Map<String, String>)request.getAttribute("efpPortalEfpNames");
177
						if (!efpMappings.isEmpty()) {
178
					%>
179
					<li><hr class="navbar-separator"></li>
180
					<li>
181
						<select name="EFPselector" class="EFP-selector" id="EFPselector">
182
							<option value="" selected="selected" class="option_default">none</option>
183
							<% for (Map.Entry<String, String> entry : efpMappings.entrySet()) { %>
184
								<option value="<%=entry.getValue()%>"><%=entry.getValue()%></option>
185
							<% } %>
186
						</select>
187
					</li>
188
					<%
189
						}
190
					}
191
					%>
192

  
193
					<% if (show_icon_save) { %>
194
						<li><hr class="navbar-separator"></li>
195
						<li><a href="#" class="btn btn-block view-save-diagram" id="view_save_diagram" onClick="saveDiagram(<%=request.getParameter("diagram_id")%>); return false;" title="Save diagram"></a></li>
196

  
197
						<li><hr class="navbar-separator"></li>
198
						<li><a href="<%=getServletContext().getInitParameter("HOME_URL")%>ShowGraph?diagram_id=<%=request.getParameter("diagram_id")%>&diagram_hash=<%=request.getParameter("diagram_hash")%>" class="btn btn-block view-refresh-diagram" id="view_refresh_diagram" title="Refresh diagram"></a></li>
199

  
200
						<li><hr class="navbar-separator"></li>
201
						<li><a href="<%=getServletContext().getInitParameter("HOME_URL")%>ShowGraph?diagram_id=<%=request.getParameter("diagram_id")%>&diagram_hash=<%=request.getParameter("diagram_hash")%>" class="btn btn-block view-refresh-reset-diagram" id="view_refresh_reset_diagram" onclick="return reset_diagram(<%=request.getParameter("diagram_id")%>,'<%=request.getParameter("diagram_hash")%>');" title="Refresh diagram - reset position"></a></li>
202
					<% } %>
203

  
204
					<li><hr class="navbar-separator"></li>
205
					<li>
206
						<button class="btn save-diagram" id="btnSaveDiagram" title="Save diagram as PNG." onclick="saveSvgAsPng(document.getElementById('svg1'), 'diagram.png', {scale: 1})">
207
							<img src="images/png_save.png" id="applyLayoutImg" alt="Save diagram as PNG.">
208
						</button>
209
					</li>
210
				</ul>
211
			</nav>
212

  
213
			<div class="content" id="content" >
214
				<div class="viewport" id="viewport" contextmenu="contextMenu">
215
					<img src="./images/zoom_help.png" class="zoom-help" id="zoom_help">
216

  
217
					<ul class="contextMenu" id="myMenu"></ul>
218

  
219
					<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
220
						<g class="graph" id="graph" transform="scale(1)">
221
							<g class="edges" id="edges"></g>
222
							<g class="vertices" id="vertices"></g>
223
						</g>
224
					</svg>
225
				</div>
226

  
227
				<div class="sidebar" id="rightPanel">
228
					<div class="sidebar-navbar" id="uploadMenu">
229
						<a class="button buttonClassic" id="postponed">Postponed</a>
230
						<a class="button buttonClassic" id="toChange">To Change</a>
231
						<a class="button buttonClassic" id="unconnected">Unconnected</a>
232
						<a class="button buttonClassic" id="incompatible" style="display: none;">Incompatible</a>
233
					</div>
234

  
235
					<div class="components-count" id="allComps"></div>
236

  
237
					<div class="components-box postponed-components" id="postponedComps">
238
						<h5>Postponed components</h5>
239
					</div>
240

  
241
					<div class="components-box to-change-components" id="toChangeComps">
242
						<h5>To Change components</h5>
243
						<button type="button" id="proposeChanges">
244
							<img class="buttonImage" src="images/tochange/crce-call-trans.gif" alt="Propose changes" title="Propose changes">
245
						</button>
246

  
247
						<!--
248
						<h5>Proposed components</h5>
249
						<div class="control-buttons">
250
							<div class="button buttonClassic" id="accept-proposed">
251
								<img class="buttonImage" src="images/tochange/accept-trans.gif" alt="Accept" title="Accept component change">
252
							</div>
253
							<div class="button buttonClassic" id="reject-proposed">
254
								<img class="buttonImage" src="images/button_cancel.png" alt="Reject" title="Reject component change">
255
							</div>
256
						</div>
257
						-->
258
					</div>
259

  
260
					<div class="components-box unconnected-components" id="unconComps">
261
						<h5>Unconnected components</h5>
262
						<div class="control-buttons">
263
							<div class="button buttonClassic" id="showUnconnected">
264
								<img src="images/unconnected/uncon_left.png" alt="<-" title="Show unconnected components">
265
							</div>
266
							<div class="button buttonClassic" id="hideUnconnected">
267
								<img src="images/unconnected/uncon_right.png" alt="->" title="Hide unconnected components">
268
							</div>
269
						</div>
270

  
271
						<ul id="unconCmpList"></ul>
272
					</div>
273

  
274
					<div class="components-box incompatible-components" id="allIncomps">
275
						<h5 class="notCompatible">Incompatible components</h5>
276

  
277
						<ul id="incomCmpList"></ul>
278
					</div>
279

  
280
					<div class="components-box excluded-components" id="excludedComponents">
281
						<h5>Excluded components</h5>
282

  
283
						<div class="btn-group">
284
							<button type="button" class="sort-button" id="sortComponents_name_asc">
285
								<span class="sort-icon">▲</span> Name
286
							</button>
287
							<button type="button" class="sort-button" id="sortComponents_name_desc">
288
								<span class="sort-icon">▼</span> Name
289
							</button>
290
							<button type="button" class="sort-button" id="sortComponents_count_asc">
291
								<span class="sort-icon">▲</span> #component
292
							</button>
293
							<button type="button" class="sort-button" id="sortComponents_count_desc">
294
								<span class="sort-icon">▼</span> #component
295
							</button>
296

  
297
							<button type="button" class="include-components-button" id="includeAllComponents">
298
								<img src="images/button_cancel.png" title="Include all components to graph">
299
							</button>
300
						</div>
301
					</div>
302
				</div>
303
			</div>
304
		</div>
305

  
306
		<script>
307
		var app = new App;
308
		app.HOME_URL = '<%=getPath%>cocaex-compatibility/';
309

  
310
		$(document).ready(function() {
311
			// set theme path for jsTree lib
312
			$.jstree._themes = "styles/libs/jstree/themes/";
313

  
314
			var loaderFn;
315
			<% if (request.getAttribute("graph_json") != null) { %>
316
				loaderFn = app.efpLoader(<%= request.getAttribute("graph_json") %>, <%= efpSettingsJson %>);
317
			<% } else { %>
318
				loaderFn = app.diagramLoader(<%= request.getParameter("diagram_id") %>, <%= request.getParameter("diagram_hash") %>);
319
			<% } %>
320

  
321
			app.run(loaderFn);
322
		});
323
		</script>
324
	</body>
325
</html>
sources/WebContent/old/js/app.js
1
/**
2
 * Main class of the application. 
3
 */
4
function App() {
5
	this.loader = new Loader;
6

  
7
	this.HOME_URL = null;
8

  
9
	this.api = {
10
		loadGraph: 'LoadGraphData',
11
		loadDiagram: 'LoadDiagram',
12
	};
13

  
14
	/**
15
	 * Loads graph using diagram (if available).
16
	 * @param diagramId Diagram identifier.
17
	 * @param diagramHash Diagram hash.
18
	 */
19
	this.diagramLoader = function(diagramId, diagramHash) {
20
		return function() {
21
			loadGraphData(diagramId, diagramHash, null, null);
22
		};
23
	};
24

  
25
	/**
26
	 * Loads graph using EFP data.
27
	 * @param withEfps Is EFPs in graph?
28
	 * @param efpSettings EFP settings.
29
	 */
30
	this.efpLoader = function(withEfps, efpSettings) {
31
		return function() {
32
			loadGraphData(null, null, withEfps, efpSettings);
33
		};
34
	};
35

  
36
	this.run = function(startFn) {
37
		console.log('running...');
38

  
39
		bootstrap();
40
		startFn();
41
	};
42

  
43
	function bootstrap() {
44
		GraphManager.init();
45
		ViewportManager.init();
46
		OffScreenKiv.init();
47

  
48
		// when user changes window size then set height and width #viewport and #rightPanel
49
		$(window).bind('resize', setHeight);
50

  
51
		setHeight();
52

  
53
		// zoom
54
		$('#zoomIn').click(function() {
55
			ViewportManager.zoom.zoomIn();
56
		});
57

  
58
		$('#zoomOut').click(function() {
59
			ViewportManager.zoom.zoomOut();
60
		});
61

  
62
		// viewport mode
63
		$("input[name='actionMove']").change(function() {
64
			var action = $("input[name='actionMove']:checked").val();
65
			var vertex;
66

  
67
			if (action == 'move') {
68
				for (var i = 0; i < GraphManager.graph.vertices.length; i++) {
69
					// remove context menu
70
					ViewportManager.removeContextMenu('#vertex'+ (i+1));
71
					
72
					vertex = GraphManager.graph.vertices[i];
73
					vertex.$selector.unbind('mousedown', OffScreenKiv.showVertexInRightPanel);
74
					vertex.$selector.mousedown(ViewportManager.vertexMousedownHandler);
75
				}
76

  
77
			} else if (action == 'exclude') {
78
				for (var j = 0; j < GraphManager.graph.vertices.length; j++) {
79
					vertex = GraphManager.graph.vertices[j];
80
					vertex.$selector.unbind('mousedown', ViewportManager.vertexMousedownHandler);
81
					vertex.$selector.mousedown(OffScreenKiv.showVertexInRightPanel);
82
					
83
					// add context menu
84
					ViewportManager.addContextMenu('#vertex'+ (j+1));
85
				}
86
			}
87
		});
88

  
89
		// search
90
		$("#search").click(OffScreenKiv.search);
91
		$("#searchText").focusin(function() {
92
			if ($(this).val() == 'Search components...') {
93
				$(this).val('');
94
			}
95
		});
96

  
97
		$("#countOfFinded").click(OffScreenKiv.deselectHighlightSearchedVertices);
98
		$("#mostEdge").click(OffScreenKiv.excludeVerticesWithMostEdges);
99
		$("#vertexToGroup").click(OffScreenKiv.excludeVerticesWithMostEdgesToGroup);
100
		$('#applyLayout').click(GraphManager.forceDirectedLayoutOnClick);
101

  
102
		$('.sort-button').click(OffScreenKiv.sortComponents);
103
		$('#includeAllComponents').click(OffScreenKiv.includeAllComponents);
104

  
105
		initSearchOnEnterPressed();
106
		initZoomKeys();
107
		initViewportMove();
108
	}
109

  
110
	function loadGraphData(diagram_id, diagram_hash, with_efps, efp_settings) {
111
		app.loader.enable();
112
	
113
		var load_url = app.api.loadGraph;
114
		var load_diagram_url = app.api.loadDiagram;
115
		
116
		if (diagram_id !== null) {
117
			load_url += "?diagram_id=" + diagram_id;
118
			load_diagram_url += "?diagram_id=" + diagram_id;
119
		}
120
		
121
		if (diagram_hash !== null) {
122
			load_url +=  "&diagram_hash=" + diagram_hash;
123
			load_diagram_url += "&diagram_hash=" + diagram_hash;
124
		}
125

  
126
		if (with_efps !== null) {
127
			/* Build graph with EFPs */
128
			GraphManager.isEfpGraph = true;
129
	
130
			// set EFP settings
131
			GraphManager.efpMinIntDiameter = efp_settings.minInterfaceDiameter;
132
			GraphManager.efpMaxIntDiameter = efp_settings.maxInterfaceDiameter;
133
		}
134

  
135
		// gets vertex position data
136
		$.getJSON(load_diagram_url, function(data) {
137
			GraphManager.vertices_position = data;
138
		});
139

  
140
		// build the graph
141
		$.getJSON(load_url, function(data) {
142
			GraphManager.graph = data;
143

  
144
			GraphManager.buildGraph();
145
			ViewportManager.revive();
146
		});
147
	}
148

  
149
	/**
150
	 * Set height of viewport and right panel.
151
	 */
152
	function setHeight() {
153
		var headerHeight = $('#header').height() + $('#navigation').height() + 5;	/* magic 5, dunno where it comes from */
154
		var contentHeight = $(window).height() - headerHeight;
155
		
156
		$('#viewport').height(contentHeight);
157
		$('#rightPanel').height(contentHeight - 40); /* 40px is the sidebar-navbar */
158
	}
159

  
160
	/**
161
	 * Set Enter as accelerator for the searching box
162
	 */
163
	function initSearchOnEnterPressed() {
164
		$("#searchText").keydown(function(event) {
165
			// react on Enter key pressed
166
			if (event.which === 13) {
167
				OffScreenKiv.search();
168
			}
169
		});
170
	}
171

  
172
	/**
173
	 * Initialize zoom keys.
174
	 */
175
	function initZoomKeys() {
176
		var scrollViewportOnZoom = function(e) {
177
			e = e ? e : window.event;
178
			var raw = e.detail ? e.detail : e.deltaY;
179
			
180
			if (event.ctrlKey === true) {
181
				e.preventDefault();
182

  
183
				if (raw > 0){
184
					ViewportManager.zoom.zoomOut();
185
				}
186
				if (raw < 0){
187
					ViewportManager.zoom.zoomIn();
188
				}
189
			}
190
		};
191

  
192
		$(window).keydown(function(event) {
193
			if (event.ctrlKey === false) return;
194
	
195
			$('#zoom_help').show();
196

  
197
			// key code 107 is the plus sign
198
			if (event.which === 107) {
199
				event.preventDefault();
200

  
201
				ViewportManager.zoom.zoomIn();
202
			}
203
	
204
			// key code 109 is the plus sign
205
			if (event.which === 109) {
206
				event.preventDefault();
207

  
208
				ViewportManager.zoom.zoomOut();
209
			}
210
		});
211
	
212
		$(window).keyup(function(event) {
213
			if (event.ctrlKey === false) {
214
				$('#zoom_help').hide();
215
			}
216
		});
217

  
218
		document.getElementById('envelope').addEventListener('wheel', scrollViewportOnZoom);
219
		document.getElementById('zoom_help').addEventListener('wheel', scrollViewportOnZoom);
220
	}
221

  
222
	/**
223
	 * Initialization of moving with viewport
224
	 */
225
	function initViewportMove() {
226
		var viewport = $('#viewport'),
227
			viewportX, viewportY,
228
			startX, startY;
229
		
230
		var bindMove = function(e) {
231
			if (e.button === 0) {
232
				document.getElementById('envelope').addEventListener('mousemove', move);
233
				
234
				viewportX = viewport.scrollLeft();
235
				viewportY = viewport.scrollTop();
236
				
237
				startX = e.screenX;
238
				startY = e.screenY;
239
			}
240
		};
241
		
242
		var unbindMove = function(e) {
243
			document.getElementById('envelope').removeEventListener('mousemove', move);
244
		};
245
		
246
		var move = function(e) {
247
			e.preventDefault();
248
			e.stopPropagation();
249
			
250
			viewport.scrollLeft(viewportX + startX - e.screenX);
251
			viewport.scrollTop(viewportY + startY - e.screenY);
252
		};
253
		
254
		document.getElementById('viewport').addEventListener('mousedown', bindMove);
255
		document.getElementById('envelope').addEventListener('mouseup', unbindMove);
256
		document.getElementById('envelope').addEventListener('mouseleave', unbindMove);
257
	}
258

  
259
}
sources/WebContent/old/js/diagram.js
1
/**
2
* Funkce zavola servlet, ktery odstrani diagram z databáze a ze serveru.
3
*
4
* @param id_diagram - id diagramu
5
*/
6
function deleteDiagram(id_diagram) {
7
	var really = confirm('Do you really want to remove diagram?');
8
	if (really === false) {
9
		return false;
10
	}
11

  
12
	$.ajax({
13
		url: 'api/diagram?id_diagram=' + id_diagram,
14
		type: 'DELETE',
15
		success: function(result) {
16
			$('#diagram_id_' + id_diagram).remove();
17
			$('#public_diagram_id_' + id_diagram).remove();
18
		},
19
	});
20
}
21

  
22
/**
23
* Funkce nalezne vsechny komponenty zobrazene ve viewportu, ulozi je jako json a odesle servletu.
24
* 
25
* @param id_diagram ID diagramu
26
*/
27
function saveDiagram(id_diagram) {
28
	var vertex_position = new Array(),
29
		vertex_position_counter = 0;
30
	
31
	$('g.vertex').each(function () {
32
		vertex_position[vertex_position_counter] = ' {"id":"' + $(this).attr('id') + '" , ' +
33
		'  "transform":"' + $(this).attr('transform') + '" }';
34
		vertex_position_counter++;
35
	});
36
	
37
	vertex_position.join(',');
38
	vertex_position = '{"vertices_position": [ ' + vertex_position + ' ]}';
39
	
40
	$.post('api/diagram', {
41
		id_diagram: id_diagram,
42
		vertices_position: vertex_position,
43
	}).done(function () {
44
		alert("Diagram saved.");
45
	}).fail(function () {
46
		alert("Error - Diagram not saved!");
47
	});
48
}
49

  
50
/**
51
* Funkce zobrazi vyskakovaci okno s potvrzenim
52
*
53
* @param id_diagram ID diagramu
54
* @param diagram_hash hash diagramu
55
* @returns {Boolean} true if reset confirmed
56
*/
57
function reset_diagram(id_diagram, diagram_hash) {
58
	var really = confirm('Do you want to reset components position and refresh page?');
59
	if (really === false) {
60
		return false;
61
	}
62

  
63
	$.post('api/diagram', {
64
		id_diagram: id_diagram,
65
		vertices_position: "",
66
	});
67

  
68
	return true;
69
}
sources/WebContent/old/js/dialog.js
1

  
2
/**
3
*
4
* Group rename dialog.
5
*/
6
var Dialog = {
7
	
8
	/**
9
	* Set up the dialog - settings and such.
10
	*/
11
	setDialog : function() {
12
		
13
		$("#dialog").dialog({
14
			dialogClass : "no-close",
15
			buttons : [ {
16
				text : "OK",
17
				
18
				click : function(e) {
19
					Dialog.saveDialogValue(this);
20
				}
21
			}, {
22
				text : "Cancel",
23
				click : function() {
24
					$(this).dialog("close");
25
				}
26
			} ],
27
			closeOnEscape : true,
28
			draggable : false,
29
			modal : true,
30
			autoOpen : false
31
		});
32
		
33
		// setup clearing button
34
		$("#clearNameButton").click(function() { $("#groupNameTextarea").val(""); });
35
		
36
		// when focused
37
		$("#dialog").on("dialogfocus", function(event, ui) {
38
			// set Enter as dialog completion accelerator
39
			$(this).keypress(function(e) {
40
				if(e.which == 13) {
41
					Dialog.saveDialogValue($("#dialog").dialog());
42
				}
43
			});
44
			
45
			// get the group object and set the input field value
46
			var group = $("#dialog").dialog().data('group');
47
			$("#groupNameTextarea").val(group.label);
48
		} );
49
	},
50

  
51
	/**
52
	 * Save the values in dialog textarea to the group.
53
	 * 
54
	 * @param callingParent parent
55
	 * 
56
	 * group - group object itself
57
	 * groupLabel - group label element
58
	 * isSvgElement - if SVG element then true, false otherwise
59
	 */
60
	saveDialogValue : function(callingParent) {
61
		var MAX_CHARS = 15;
62
		
63
		var newName = $("#groupNameTextarea").val();
64
		var group = $(callingParent).data('group');
65
		var groupLabel = $(callingParent).data('groupLabel');
66
		var isSVG = $(callingParent).data('isSvgElement');
67
		
68
		if (newName.replace(/ /g, '').length === 0) {
69
			// default name
70
			newName = 'Group';
71
			} else {
72
			if (newName.length > MAX_CHARS) {
73
				newName = newName.substring(0, MAX_CHARS);
74
				newName += "..";
75
			}
76
		}
77
		
78
		if(isSVG) {
79
			var test = document.getElementById('labelTextElement' + group.idGroup);
80
			test.textContent = newName;
81
			}else {
82
			groupLabel.html(newName);
83
		}
84
		
85
		// set new group label
86
		group.label = newName;
87
		
88
		// makes the label visible if newName isn't Group and adjusts position and size of the icon
89
		if (newName != 'Group') {
90
			$('#labelTextElement' + group.idGroup).attr('display', '');
91

  
92
			$('#symbol' + group.idGroup).attr('class', 'group-symbol');
93
			$('#symbol' + group.idGroup).attr('x', '20');
94
			$('#symbol' + group.idGroup).attr('y', '11');
95
		}
96

  
97

  
98

  
99
		$(callingParent).dialog("close");
100
	}
101
};
sources/WebContent/old/js/efps.js
1

  
2
/**
3
* Representation of EFP interface functionality.
4
*/
5
var EFPs = {
6
	elementName : "#EFPselector",
7
	graph : null,
8
	// map {EFP name, EFP ID}
9
	efpsIds : {},
10
	// array [EFP ID, edge ID]
11
	efpsStruct : new Array(),
12
	currentEfpSeclected : null,
13
	minDiameter : null,
14
	maxDiameter : null,
15
	// left - required - misticka
16
	minEfpsValuesLeft : {},
17
	maxEfpsValuesLeft : {},
18
	// right - provided - lizatko
19
	minEfpsValuesRight : {},
20
	maxEfpsValuesRight : {},
21
	
22
	/**
23
	* Init.
24
	*
25
	* @param graph
26
	*/
27
	init : function(graph) {
28
		this.graph = graph;
29
		this.minDiameter = GraphManager.efpMinIntDiameter;
30
		this.maxDiameter = GraphManager.efpMaxIntDiameter;
31
		
32
		// min is really min
33
		if (parseFloat(this.minDiameter) > parseFloat(this.maxDiameter)) {
34
			var tmp = this.minDiameter;
35
			this.minDiameter = this.maxDiameter;
36
			this.maxDiameter = tmp;
37
		}
38
		
39
		this.currentEfpSeclected = $(this.elementName).val();
40
		this.associateEfpsToEdgeIds();
41
	},
42
	
43
	/**
44
	* Make cached association EFP;edgeID.
45
	*/
46
	associateEfpsToEdgeIds : function() {
47
		// array of EFPs
48
		var efpsCount = $(this.elementName + " option").length - 1;
49
		
50
		var tmp = 0;
51
		
52
		// hack for "this" when entering to
53
		var ids = this.efpsIds;
54
		var minEfpsLeft = this.minEfpsValuesLeft;
55
		var maxEfpsLeft = this.maxEfpsValuesLeft;
56
		var minEfpsRight = this.minEfpsValuesRight;
57
		var maxEfpsRight = this.maxEfpsValuesRight;
58
		
59
		// fill map
60
		$("#EFPselector option").each(function(e) {
61
			if ($(this).val() != "") {
62
				ids[$(this).val()] = tmp++;
63
				
64
				// init the min/max arrays
65
				minEfpsLeft[$(this).val()] = Number.MAX_VALUE;
66
				maxEfpsLeft[$(this).val()] = -Number.MAX_VALUE;
67
				
68
				minEfpsRight[$(this).val()] = Number.MAX_VALUE;
69
				maxEfpsRight[$(this).val()] = -Number.MAX_VALUE;
70
			}
71
		});
72
		
73
		for ( var i = 0; i < efpsCount; i++) {
74
			// efpsStruct[i].push(new Array());
75
			this.efpsStruct[i] = new Array();
76
		}
77
		
78
		// edges
79
		for (var i = 0; i < this.graph.edges.length; i++) {
80
			var features = this.graph.edges[i].features;
81
			
82
			// features
83
			for (var j = 0; j < features.length; j++) {
84
				var efps = features[j].efps;
85
				
86
				// efps
87
				for (var k = 0; k < efps.length; k++) {
88
					if (efps[k].efpName != "") {
89
						var tmpEfpId = this.efpsIds[efps[k].efpName];
90
						var tmpEdgeId = this.graph.edges[i].id;
91
						
92
						// assign edge to the efps
93
						if (this.efpsStruct[tmpEfpId].indexOf(tmpEdgeId) < 0) {
94
							// check if the EFP values are really valid numbers
95
							if(!isNaN(efps[k].leftEfpValue) && !isNaN(efps[k].rightEfpValue)) {
96
								this.efpsStruct[tmpEfpId].push(tmpEdgeId);;
97
							}
98
						}
99
						
100
						/* LEFT numeric values */
101
						if (!isNaN(efps[k].leftEfpValue)) {
102
							// check and set min
103
							if (parseFloat(efps[k].leftEfpValue) < parseFloat(this.minEfpsValuesLeft[efps[k].efpName])) {
104
								this.minEfpsValuesLeft[efps[k].efpName] = efps[k].leftEfpValue;
105
							}
106
							
107
							// check and set max
108
							if (parseFloat(efps[k].leftEfpValue) > parseFloat(this.maxEfpsValuesLeft[efps[k].efpName])) {
109
								this.maxEfpsValuesLeft[efps[k].efpName] = efps[k].leftEfpValue;
110
							}
111
						}
112
						
113
						/* RIGHT numeric values */
114
						if (!isNaN(efps[k].rightEfpValue)) {
115
							// check and set min
116
							if (parseFloat(efps[k].rightEfpValue) < parseFloat(this.minEfpsValuesRight[efps[k].efpName])) {
117
								this.minEfpsValuesRight[efps[k].efpName] = efps[k].rightEfpValue;
118
							}
119
							
120
							// check and set max
121
							if (parseFloat(efps[k].rightEfpValue) > parseFloat(this.maxEfpsValuesRight[efps[k].efpName])) {
122
								this.maxEfpsValuesRight[efps[k].efpName] = efps[k].rightEfpValue;
123
							}
124
						}
125
					}
126
				}
127
			}
128
		}
129
	},
130
	
131
	/**
132
	* Triggered after a change of selected EFP.
133
	*
134
	* @param element
135
	*/
136
	recalculate : function(element) {
137
		var efpName = $(element).val();
138
		
139
		// empty selected => reset
140
		if (efpName == "") {
141
			this.changeEdges(this.currentEfpSeclected, true);
142
			
143
			this.currentEfpSeclected = efpName;
144
			
145
			return;
146
		}
147
		
148
		// is already empty => no need for a reset
149
		if (this.currentEfpSeclected != "") {
150
			this.changeEdges(this.currentEfpSeclected, true);
151
		}
152
		
153
		this.changeEdges(efpName, false);
154
		
155
		// set new selected value
156
		this.currentEfpSeclected = efpName;
157
	},
158
	
159
	/**
160
	*
161
	* Calculate average of all selected EFPs on given edge.
162
	*
163
	* @param efpName
164
	* @param edge
165
	* @returns {Array}
166
	*/
167
	calculateEfpAvg : function(efpName, edge) {
168
		var foundEFps = 0;
169
		var avgStructLeftRight = [Number(0),Number(0)];
170
		
171
		// get the EFP and its values
172
		for(var j = 0; j < edge.features.length; j++) {
173
			var tmpEdgeFeature = edge.features[j];
174
			
175
			for(var k = 0; k < tmpEdgeFeature.efps.length; k++) {
176
				var tmpEdgeFeatureEfp = tmpEdgeFeature.efps[k];
177
				
178
				// set the EFP if matched and numeric
179
				if(tmpEdgeFeatureEfp.efpName == efpName){
180
					if(!isNaN(tmpEdgeFeatureEfp.leftEfpValue) && !isNaN(tmpEdgeFeatureEfp.rightEfpValue)) {
181
						foundEFps++;
182
						
183
						avgStructLeftRight[0] += parseFloat(tmpEdgeFeatureEfp.leftEfpValue);
184
						avgStructLeftRight[0] /= foundEFps;
185
						
186
						avgStructLeftRight[1] += parseFloat(tmpEdgeFeatureEfp.rightEfpValue);
187
						avgStructLeftRight[1] /= foundEFps;
188
						}else {
189
						// found some non-numeric -> error state
190
						return null;
191
					}
192
				}
193
			}
194
		}
195
		
196
		return avgStructLeftRight;
197
	},
198
	
199
	/**
200
	*
201
	* @param efpName
202
	* @param reset
203
	*/
204
	changeEdges : function(efpName, reset) {
205
		var diameterLeft = null, diameterRight = this.minDiameter;
206
		var tmpEfpId = this.efpsIds[efpName];
207
		
208
		var singleSelectedEfpInDiagram = false;
209
		
210
		var kLeft = null, qLeft = null, kRight = null, qRight = null;
211
		
212
		// [minDiameter][maxDiameter] of chosen EFP
213
		var minMaxDiameterOfEfpLeft = [this.minEfpsValuesLeft[efpName], this.maxEfpsValuesLeft[efpName]];
214
		var minMaxDiameterOfEfpRight = [this.minEfpsValuesRight[efpName], this.maxEfpsValuesRight[efpName]];
215
		
216
		// check if we won't run into the DIV 0
217
		if((minMaxDiameterOfEfpLeft[0] - minMaxDiameterOfEfpLeft[1]) == 0 || (minMaxDiameterOfEfpRight[0] - minMaxDiameterOfEfpRight[1]) == 0){
218
			singleSelectedEfpInDiagram = true;
219
			}else {
220
			// y = k * x + q
221
			kLeft = (this.minDiameter - this.maxDiameter) / (minMaxDiameterOfEfpLeft[0] - minMaxDiameterOfEfpLeft[1]);
222
			qLeft = this.maxDiameter - kLeft * minMaxDiameterOfEfpLeft[1];
223
			
224
			kRight = (this.minDiameter - this.maxDiameter) / (minMaxDiameterOfEfpRight[0] - minMaxDiameterOfEfpRight[1]);
225
			qRight = this.maxDiameter - kRight * minMaxDiameterOfEfpRight[1];
226
		}
227
		
228
		// iterates through all edges which have the selected EFP
229
		for (var i = 0; i < this.efpsStruct[tmpEfpId].length; i++) {
230
			var tmpEdgeId = this.efpsStruct[tmpEfpId][i];
231
			diameterLeft = this.minDiameter;
232
			diameterRight = this.minDiameter;
233
			
234
			// calculate avg
235
			var selectedEfpAvg = this.calculateEfpAvg(efpName, this.graph.edges[tmpEdgeId - 1]);
236
			
237
			if (reset) {
238
				// remove tick symbol
239
				var lolliToRemove = document.getElementById("lollipop-tick" + tmpEdgeId);
240
				
241
				if(lolliToRemove != null) {
242
					var lolliParent = lolliToRemove.parentNode;
243
					lolliParent.removeChild(lolliToRemove);
244
				}
245
				
246
				}else {
247
				if(selectedEfpAvg != null && !singleSelectedEfpInDiagram) {
248
					// calculate the size - linear scaling
249
					diameterLeft = kLeft * selectedEfpAvg[0] + qLeft;
250
					diameterRight = kRight * selectedEfpAvg[1] + qRight;
251
				}
252
			}
253
			
254
			// set circle radius
255
			$(".lollipop[data-edgeid='" + tmpEdgeId + "'] circle").attr("r", diameterRight / 2);
256
			
257
			
258
			if (!reset) {
259
				if(selectedEfpAvg != null) {
260
					// set path dimensions
261
					var yDistance = diameterLeft / 2 + 4;
262
					// X distance of half-circle's "draggers" should be equal to 2/3 of circle diameter (eg. circle diametr=24, draggers=16)
263
					var xDistance = yDistance * 4 / 3;
264
					var distanceOffsetToRight = diameterRight / 2;
265
					// add distance between lolli and circle
266
					var dString = 'M' + distanceOffsetToRight + ',' + -yDistance + ' C' + (xDistance + distanceOffsetToRight) + ',' + -yDistance + ' ' + (xDistance + distanceOffsetToRight) + ',' + yDistance + ' ' + distanceOffsetToRight + ',' + yDistance;
267
					
268
					$(".lollipop[data-edgeid='" + tmpEdgeId + "'] path").first().attr("d", dString);
269
				}
270
				
271
				// add tick symbol if needed
272
				if(this.graph.edges[tmpEdgeId-1].edgeStatusOk) {
273
					// create tick element
274
					var tick = document.createElementNS('http://www.w3.org/2000/svg','path');
275
					tick.setAttribute('class','SamplePath');
276
					tick.setAttribute('id', 'lollipop-tick' + tmpEdgeId);
277
					tick.setAttribute('d','M-4,-2 C-3,12 1,0 5,-7');
278
					tick.setAttribute('stroke','green');
279
					
280
					// get the angle
281
					var xforms = $(".lollipop[data-edgeid='" + tmpEdgeId + "']").attr('transform');
282
					var parts  = /rotate\(\s*([^\s,)]+)[ ,]([^\s,)]+)[ ,]([^\s,)]+)/.exec(xforms);
283
					var angle = parts[1];
284
					
285
					// prevent rotation
286
					tick.setAttribute('transform','rotate(' + (-angle) + ',0,0) translate(0,0)');
287
					
288
					// add the tick
289
					var lollipop = $(".lollipop[data-edgeid='" + tmpEdgeId + "']")[0];
290
					lollipop.appendChild(tick);
291
				}
292
				}else {
293
				// set path dimensions
294
				var yDistance = diameterLeft / 2 + 4;
295
				// X distance of half-circle's "draggers" should be equal to 2/3 of circle diameter (eg. circle diametr=24, draggers=16)
296
				var xDistance = yDistance * 4 / 3;
297
				var dString = 'M0,' + -yDistance + ' C' + xDistance + ',' + -yDistance + ' ' + xDistance + ',' + yDistance + ' 0,' + yDistance;
298
				
299
				$(".lollipop[data-edgeid='" + tmpEdgeId + "'] path").first().attr("d", dString);
300
			}
301
		}
302
		
303
	},
304
	
305
};
sources/WebContent/old/js/graphManager.js
1

  
2
/**
3
 * Object which represent graph.
4
 */
5
var GraphManager = {
6
	graph: null,
7
	unconList: [],
8
	isEfpGraph : false,
9
	isCompatibilityGraph: true,
10
	vertices_position: null,
11
	forceField: [],
12
	otherVertex: [],
13
	canvasSize: 0,
14

  
15
	// parametry layoutu
16
	inumber: 30, // pocet iteraci; default 300
17
	inumberClick: 20, // pocet iteraci u tlacitka
18
	restrength: 400, // odpudiva sila (prima umera); default 450
19
	atstrength: 510, // pritazliva sila (neprima umera, nesmi byt 0); default 110
20
	deffect: 1000, // tlumeni sily (nesmi byt 0); default 200
21
	borderRatio: 1, // hranice layoutu (cislo kterym se deli velikost canvasu)
22
	// tahle funkce se mi nelibi, je treba to vyresit jinak, nici to layout (nechat na 1)
23

  
24
	layouting: false,
25
	myVar: null,
26

  
27
	/**
28
	 * Initialization
29
	 */
30
	init: function(){
31
		this.buildGraph.bind(this);
32
		this.forceDirectedLayoutOnClick = this.forceDirectedLayoutOnClick.bind(this);
33
	},
34

  
35
	/**
36
	 * Apply layout and set interval
37
	 */
38
	forceDirectedLayoutOnClick: function(){
39
		if (this.layouting === true) {
40
			$('#applyLayoutImg').attr('src', 'images/layout_off.png');
41
			this.layouting = false;
42
			clearInterval(this.myVar);
43
		} else {
44
			$('#applyLayoutImg').attr('src', 'images/layout_on.png');
45
			this.layouting = true;
46
			this.myVar = window.setInterval(this.awesomeFirePenguin.bind(this), 10);
47
		}
48
	},
49

  
50
	/**
51
	 * Force directed layout for visible components
52
	 */
53
	awesomeFirePenguin: function(){
54
		var canvas = this.canvasSize,
55

  
56
			repulsiveStrength = this.restrength, // more is more
57
			attractiveStrength = this.atstrength, // more is less
58
			dampeningEffect = this.deffect,
59
			border = canvas/this.borderRatio,
60

  
61
			visibleVertices = [],
62
			vertices = this.graph.vertices,
63
			i = 0,
64
			j = 0,
65
			counter = 0,
66
			otherVisibleVertices = [];
67

  
68
		// gets the visible components
69
		for (i = 0; i < vertices.length; i++){
70
			if (vertices[i].$selector[0].isVisible()){
71
				visibleVertices[counter] = vertices[i];
72
				counter++;
73
			}
74
		}
75

  
76
		for (i = 0; i < this.graph.vertices.length; i++){
77
			this.forceField[i][0] = 0;
78
			this.forceField[i][1] = 0;
79
		}
80

  
81
		// calculate repulsive force
82
		for (i = 0; i < visibleVertices.length; i++){
83
			var currVertex = visibleVertices[i];
84

  
85
			// other vertices
86
			for (var j = 0; j < visibleVertices.length; j++){
87
				otherVisibleVertices[j] = visibleVertices[j];
88
			}
89
			otherVisibleVertices.splice(i, 1);
90

  
91
			// iterate over other vertices
92
			for (j = 0; j < otherVisibleVertices.length; j++){
93
				// currVertex position
94
				var currX = currVertex.x,
95
					currY = currVertex.y,
96

  
97
				// otherVertex position
98
					otherX = otherVisibleVertices[j].x,
99
					otherY = otherVisibleVertices[j].y,
100

  
101
				// calculate force
102
					x = currX - otherX,
103
					y = currY - otherY,
104

  
105
					sum = Math.pow(x,2) + Math.pow(y,2),
106
					distance = Math.sqrt(sum);
107

  
108
				if (distance !== 0) {
109
					this.forceField[currVertex.id-1][0] += Math.floor((x * (repulsiveStrength / distance)));
110
					this.forceField[currVertex.id-1][1] += Math.floor((y * (repulsiveStrength / distance)));
111
				}
112
			}
113
		}
114

  
115
		// calculate attractive forces
116
		for (i = 0; i < visibleVertices.length; i++){
117
			var currVertex = visibleVertices[i];
118

  
119
			for (j = 0; j < currVertex.edges.length; j++){
120
				var otherVertex;
121

  
122
				if (currVertex.edges[j].to == currVertex){
123
					otherVertex = currVertex.edges[j].from;
124
				} else {
125
					otherVertex = currVertex.edges[j].to;
126
				}
127

  
128
				if (otherVertex.$selector[0].isHidden()) continue;
129

  
130
				// currVertex position
131
				var currX = currVertex.x,
132
					currY = currVertex.y,
133

  
134
				// otherVertex position
135
					otherX = otherVertex.x,
136
					otherY = otherVertex.y,
137

  
138
				// calculate force
139
					x = currX - otherX,
140
					y = currY - otherY,
141

  
142
					sum = Math.pow(x, 2) + Math.pow(y, 2),
143
					distance = Math.sqrt(sum);
144

  
145
				//$('#rightPanel').append(distance+"<BR>");
146
				this.forceField[visibleVertices[i].id-1][0] += Math.round(-( (x * (distance / attractiveStrength))));
147
				this.forceField[visibleVertices[i].id-1][1] += Math.round(-( (y * (distance / attractiveStrength))));
148
				/*
149
				 this.forceField[otherVertex.id-1][0] -= Math.round(-( (x * (distance / attractiveStrength))));
150
				 this.forceField[otherVertex.id-1][1] -= Math.round(-( (y * (distance / attractiveStrength))));
151
				 */
152
			}
153
		}
154

  
155
		// applying the force
156
		for (i = 0; i < this.graph.vertices.length; i++){
157
			var currVertex = this.graph.vertices[i],
158

  
159
				halfCan = canvas / 2,
160

  
161
				deltaX = currVertex.x - halfCan,
162
				deltaY = currVertex.y - halfCan;
163

  
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff