You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

496 lines
14 KiB

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8"/>
  5. <title>permAppv2</title>
  6. <style type="text/css">
  7. body, select {
  8. font: 10pt sans;
  9. }
  10. #mynetwork {
  11. position:relative;
  12. width: 800px;
  13. height: 600px;
  14. border: 1px solid lightgray;
  15. }
  16. table.legend_table {
  17. font-size: 11px;
  18. border-width:1px;
  19. border-color:#d3d3d3;
  20. border-style:solid;
  21. }
  22. table.legend_table,td {
  23. border-width:1px;
  24. border-color:#d3d3d3;
  25. border-style:solid;
  26. padding: 2px;
  27. }
  28. div.table_content {
  29. width:80px;
  30. text-align:center;
  31. }
  32. div.table_description {
  33. width:100px;
  34. }
  35. #operation {
  36. font-size:28px;
  37. }
  38. #node-popUp {
  39. display:none;
  40. position:absolute;
  41. top:350px;
  42. left:170px;
  43. z-index:299;
  44. width:250px;
  45. height:120px;
  46. background-color: lightblue;
  47. border-style:solid;
  48. border-width:3px;
  49. border-color: #5394ed;
  50. padding:10px;
  51. text-align: center;
  52. }
  53. #title-box {
  54. top:350px;
  55. left:170px;
  56. z-index:299;
  57. width:400px;
  58. height:300px;
  59. background-color: lightblue;
  60. border-style:solid;
  61. border-width:3px;
  62. border-color: green;
  63. padding:10px;
  64. text-align: center;
  65. }
  66. p.test {
  67. background-color: lightblue;
  68. height: 400px;
  69. width: 300px;
  70. border: 0px solid green;
  71. word-wrap: break-word;
  72. word-break: keep-all;
  73. white-space:normal;
  74. }
  75. #edge-popUp {
  76. display:none;
  77. position:absolute;
  78. top:350px;
  79. left:170px;
  80. z-index:299;
  81. width:250px;
  82. height:90px;
  83. background-color: lightblue;
  84. border-style:solid;
  85. border-width:3px;
  86. border-color: lightblue;
  87. padding:10px;
  88. text-align: center;
  89. }
  90. </style>
  91. <script type="text/javascript" src="public/visjs.min.js"></script>
  92. <script type="text/javascript" src="public/axios.min.js"></script>
  93. <script type="text/javascript">
  94. var nodes;
  95. var edges;
  96. var network = null;
  97. function destroy() {
  98. if (network !== null) {
  99. network.destroy();
  100. network = null;
  101. }
  102. }
  103. function draw() {
  104. destroy();
  105. // create a network
  106. var DIR = "public/images/";
  107. nodes = new vis.DataSet();
  108. nodes.on("*", function () {
  109. document.getElementById("nodes").innerHTML = JSON.stringify(
  110. nodes.get(),
  111. null,
  112. 4
  113. );
  114. });
  115. nodes.add([
  116. {id: 0, shape: 'circularImage', image: DIR + 'canna.jpg', "label": "Cannabis", "group": 1, title: 'I am a plant' },
  117. {id: 1, shape: 'circularImage', image: DIR + 'rose.jpg', "label": "Rose", "group": 1},
  118. {id: 2, "label": "Tomato", "group": 1},
  119. {id: 3, "label": "Mint", "group": 1},
  120. {id: 4, "label": "Basil", "group": 1},
  121. {id: 5, "label": "Acorn", "group": 1},
  122. {id: 6, "label": "Pine", "group": 1},
  123. {id: 7, "label": "Orange", "group": 1},
  124. {id: 8, "label": "Lemon", "group": 1},
  125. {id: 9, shape: 'circularImage', image: DIR + 'sunflower.jpg', "label": "Sunflower", "group": 1},
  126. {id: 10, "label": "Marigold", "group": 1},
  127. {id: 11, "label": "Alfalfa", "group": 1},
  128. {id: 12, "label": "Red Clover", "group": 1},
  129. {id: 13, "label": "Chervil", "group": 1},
  130. {id: 14, "label": "White Clover", "group": 1},
  131. {id: 15, "label": "Lavender", "group": 1},
  132. {id: 16, "label": "Coriander", "group": 1},
  133. {id: 17, shape: 'circularImage', image: DIR + 'chamomile.jpg', "label": "Chamomile", "group": 1},
  134. {id: 18, "label": "Yarrow", "group": 1},
  135. {id: 19, "label": "Dill", "group": 1},
  136. {id: 20, "label": "Lemon Balm", "group": 1},
  137. {id: 21, "label": "Borage", "group": 1},
  138. {id: 22, "label": "Ant", "group": 2},
  139. {id: 23, "label": "Bee", "group": 2},
  140. {id: 24, "label": "Snail", "group": 2},
  141. {id: 25, "label": "Heat", "group": 3},
  142. {id: 26, "label": "Water", "group": 3},
  143. {id: 27, "label": "Luminance", "group": 3},
  144. {id: 28, "label": "Bird", "group": 2}
  145. ]);
  146. var Edgebox1 = '<p class="test">'
  147. var Edgebox2 = '</p>'
  148. // create some edges
  149. edges = new vis.DataSet();
  150. edges.on("*", function () {
  151. document.getElementById("edges").innerHTML = JSON.stringify(
  152. edges.get(),
  153. null,
  154. 4
  155. );
  156. });
  157. edges.add( [
  158. {"from": 1, "to": 0, arrows:'to', color:'green', title: Edgebox1 + 'the rose is very fragile. For that reason, she gets a lot of deseases some time before Cannabis gets it. That means, the rose can give you time to act.' + Edgebox2},
  159. {"from": 2, "to": 0},
  160. {"from": 3, "to": 0},
  161. {"from": 3, "to": 2},
  162. {"from": 4, "to": 0},
  163. {"from": 5, "to": 0},
  164. {"from": 6, "to": 0},
  165. {"from": 7, "to": 0},
  166. {"from": 8, "to": 0},
  167. {"from": 9, "to": 0},
  168. {"from": 11, "to": 10},
  169. {"from": 11, "to": 3},
  170. {"from": 11, "to": 2},
  171. {"from": 11, "to": 0},
  172. {"from": 12, "to": 11},
  173. {"from": 13, "to": 11},
  174. {"from": 14, "to": 11},
  175. {"from": 15, "to": 11},
  176. {"from": 17, "to": 16},
  177. {"from": 18, "to": 16},
  178. {"from": 18, "to": 17},
  179. {"from": 19, "to": 16},
  180. {"from": 19, "to": 17},
  181. {"from": 19, "to": 18},
  182. {"from": 20, "to": 16},
  183. {"from": 20, "to": 17},
  184. {"from": 20, "to": 18},
  185. {"from": 20, "to": 19},
  186. {"from": 21, "to": 16},
  187. {"from": 21, "to": 17},
  188. {"from": 21, "to": 18},
  189. {"from": 21, "to": 19},
  190. {"from": 21, "to": 20},
  191. {"from": 22, "to": 16},
  192. {"from": 22, "to": 17},
  193. {"from": 22, "to": 18},
  194. {"from": 22, "to": 19},
  195. {"from": 22, "to": 20},
  196. {"from": 22, "to": 21},
  197. {"from": 23, "to": 16},
  198. {"from": 23, "to": 17},
  199. {"from": 23, "to": 18},
  200. {"from": 23, "to": 19},
  201. {"from": 23, "to": 20},
  202. {"from": 23, "to": 21},
  203. {"from": 23, "to": 22},
  204. {"from": 23, "to": 12},
  205. {"from": 23, "to": 11},
  206. {"from": 24, "to": 23},
  207. {"from": 24, "to": 11},
  208. {"from": 25, "to": 24},
  209. {"from": 25, "to": 23},
  210. {"from": 25, "to": 11},
  211. {"from": 26, "to": 24},
  212. {"from": 26, "to": 11},
  213. {"from": 26, "to": 16},
  214. {"from": 26, "to": 25},
  215. {"from": 27, "to": 11},
  216. {"from": 27, "to": 23},
  217. {"from": 27, "to": 25},
  218. {"from": 27, "to": 24},
  219. {"from": 27, "to": 26},
  220. {"from": 28, "to": 11},
  221. {"from": 28, "to": 27}
  222. ]);
  223. // create a network
  224. var container = document.getElementById('mynetwork');
  225. var data = {
  226. nodes: nodes,
  227. edges: edges
  228. };
  229. var options = {
  230. manipulation: {
  231. addNode: function (data, callback) {
  232. // filling in the popup DOM elements
  233. document.getElementById('node-operation').innerHTML = "Add Node";
  234. editNode(data, clearNodePopUp, callback);
  235. },
  236. editNode: function (data, callback) {
  237. // filling in the popup DOM elements
  238. document.getElementById('node-operation').innerHTML = "Edit Node";
  239. editNode(data, cancelNodeEdit, callback);
  240. },
  241. addEdge: function (data, callback) {
  242. if (data.from == data.to) {
  243. var r = confirm("Do you want to connect the node to itself?");
  244. if (r != true) {
  245. callback(null);
  246. return;
  247. }
  248. }
  249. document.getElementById('edge-operation').innerHTML = "Add Edge";
  250. editEdgeWithoutDrag(data, callback);
  251. },
  252. editEdge: {
  253. editWithoutDrag: function(data, callback) {
  254. document.getElementById('edge-operation').innerHTML = "Edit Edge";
  255. editEdgeWithoutDrag(data,callback);
  256. }
  257. }
  258. }
  259. };
  260. network = new vis.Network(container, data, options);
  261. }
  262. var Nodebox1 = '<p class="test"><img src="'
  263. var Nodebox2 = '" style="width:300px;height:200px;float:up;">'
  264. var Nodebox3 = '</p>'
  265. function editNode(data, cancelAction, callback) {
  266. document.getElementById('node-descript').value = data.title;
  267. document.getElementById('node-label').value = data.label;
  268. document.getElementById('node-saveButton').onclick = saveNodeData.bind(this, data, callback);
  269. document.getElementById('node-cancelButton').onclick = cancelAction.bind(this, callback);
  270. document.getElementById('node-popUp').style.display = 'block';
  271. }
  272. // Callback passed as parameter is ignored
  273. function clearNodePopUp() {
  274. document.getElementById('node-saveButton').onclick = null;
  275. document.getElementById('node-cancelButton').onclick = null;
  276. document.getElementById('node-popUp').style.display = 'none';
  277. }
  278. function cancelNodeEdit(callback) {
  279. clearNodePopUp();
  280. callback(null);
  281. }
  282. function saveNodeData(data, callback) {
  283. data.label = document.getElementById('node-label').value;
  284. data.title = Nodebox1 + data.image + Nodebox2 + document.getElementById('node-descript').value + Nodebox3;
  285. clearNodePopUp();
  286. callback(data);
  287. }
  288. function editEdgeWithoutDrag(data, callback) {
  289. // filling in the popup DOM elements
  290. document.getElementById('edge-color').value = data.color;
  291. document.getElementById('edge-descript').value = data.title;
  292. document.getElementById('edge-saveButton').onclick = saveEdgeData.bind(this, data, callback);
  293. document.getElementById('edge-cancelButton').onclick = cancelEdgeEdit.bind(this,callback);
  294. document.getElementById('edge-popUp').style.display = 'block';
  295. }
  296. function clearEdgePopUp() {
  297. document.getElementById('edge-saveButton').onclick = null;
  298. document.getElementById('edge-cancelButton').onclick = null;
  299. document.getElementById('edge-popUp').style.display = 'none';
  300. }
  301. function cancelEdgeEdit(callback) {
  302. clearEdgePopUp();
  303. callback(null);
  304. }
  305. var Edgebox1 = '<p class="test">'
  306. var Edgebox2 = '</p>'
  307. function saveEdgeData(data, callback) {
  308. if (typeof data.to === 'object')
  309. data.to = data.to.id
  310. if (typeof data.from === 'object')
  311. data.from = data.from.id
  312. data.arrows = 'to';
  313. data.color = document.getElementById('edge-color').value;
  314. data.title = Edgebox1 + document.getElementById('edge-descript').value + Edgebox2;
  315. clearEdgePopUp();
  316. callback(data);
  317. }
  318. function exportnetwork() {
  319. try {
  320. nodes.add({
  321. id: document.getElementById("node-id").value,
  322. label: document.getElementById("node-label").value,
  323. from: document.getElementById("node-from").value
  324. });
  325. } catch (err) {
  326. alert(err);
  327. }
  328. }
  329. function init() {
  330. draw();
  331. }
  332. function exportnetwork() {
  333. // import fs module in which writeFile function is defined.
  334. // myJSON = JSON.stringify(egdes);
  335. //
  336. }
  337. function importnetwork() {
  338. }
  339. function focusOnNode() {
  340. var labeltofocus = ""
  341. labeltofocus = document.getElementById('labelinput').value;
  342. var nodeid
  343. var i;
  344. for (i = 0; i < nodes.length; i++) {
  345. if (nodes[i].label == labeltofocus) {
  346. nodeid = nodes[i].id;
  347. };
  348. }
  349. network.fit({
  350. nodes:[nodeid],
  351. animation: { // -------------------> can be a boolean too!
  352. duration: 1000,
  353. easingFunction: "easeInOutQuad"
  354. }
  355. }
  356. );
  357. }
  358. </script>
  359. </head>
  360. <body onload="init();">
  361. <h2 style="height:20px; font-size:90px">
  362. <span style='color: green'>perm</span><span style='color: red'>A</span><span style='color: green'>pp</span>
  363. </h2>
  364. <p style="width: 700px; font-size:16px; text-align: justify;">
  365. .explore relations between entities of the ecosystem
  366. </p>
  367. <div id="node-popUp">
  368. <span id="node-operation">node</span> <br>
  369. <table style="margin:auto;">
  370. <tr>
  371. <td>label</td><td><input id="node-label" value="new value" /></td>
  372. </tr>
  373. <tr>
  374. <td>description</td><td><input id="node-descript" value="new value" /></td>
  375. </tr>
  376. </table>
  377. <input type="button" value="save" id="node-saveButton" />
  378. <input type="button" value="cancel" id="node-cancelButton" />
  379. </div>
  380. <div id="edge-popUp">
  381. <span id="edge-operation">edge</span> <br>
  382. <table style="margin:auto;">
  383. <tr>
  384. <td>red/green</td><td><input id="edge-color" value="new value" /></td>
  385. </tr></table>
  386. <tr>
  387. <td>description</td><td><input id="edge-descript" value="new value" /></td>
  388. </tr></table>
  389. <input type="button" value="save" id="edge-saveButton" />
  390. <input type="button" value="cancel" id="edge-cancelButton" />
  391. </div>
  392. <div class="bottom">
  393. <span id="statusUpdate"></span>
  394. <br />
  395. <input type="button" onclick="exportnetwork();" value="export network to txt file:" style="width:800px;height:50px;color:black;background-color:lightblue;" id="btnFocus"><br/>
  396. <br />
  397. <input type="button" onclick="focusOnNode();" value="Focus on node:" style="width:800px;height:50px;color:black;background-color:lightblue;" id="btnFocus"><br/>
  398. <tr>
  399. <td> </td><td><input type="text" value="" id="labelinput" style="width:785px;"> </td>
  400. </tr>
  401. </div>
  402. <br />
  403. <div id="mynetwork"></div>
  404. <h1>View</h1>
  405. <table class="view">
  406. <tr>
  407. <td>
  408. <h2>Nodes</h2>
  409. <pre id="nodes"></pre>
  410. </td>
  411. <td>
  412. <h2>Edges</h2>
  413. <pre id="edges"></pre>
  414. </td>
  415. </body>
  416. </html>