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.

527 lines
16 KiB

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8"/>
  5. <title>permAppv3</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. //
  147. //
  148. // var Edgebox1 = '<p class="test">'
  149. // var Edgebox2 = '</p>'
  150. // create some edges
  151. edges = new vis.DataSet();
  152. edges.on("*", function () {
  153. document.getElementById("edges").innerHTML = JSON.stringify(
  154. edges.get(),
  155. null,
  156. 4
  157. );
  158. });
  159. // edges.add( [
  160. // {"from": 1, "to": 0, arrows:'to', color:'green', title: '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.'},
  161. // {"from": 2, "to": 0},
  162. // {"from": 3, "to": 0},
  163. // {"from": 3, "to": 2},
  164. // {"from": 4, "to": 0},
  165. // {"from": 5, "to": 0},
  166. // {"from": 6, "to": 0},
  167. // {"from": 7, "to": 0},
  168. // {"from": 8, "to": 0},
  169. // {"from": 9, "to": 0},
  170. // {"from": 11, "to": 10},
  171. // {"from": 11, "to": 3},
  172. // {"from": 11, "to": 2},
  173. // {"from": 11, "to": 0},
  174. // {"from": 12, "to": 11},
  175. // {"from": 13, "to": 11},
  176. // {"from": 14, "to": 11},
  177. // {"from": 15, "to": 11},
  178. // {"from": 17, "to": 16},
  179. // {"from": 18, "to": 16},
  180. // {"from": 18, "to": 17},
  181. // {"from": 19, "to": 16},
  182. // {"from": 19, "to": 17},
  183. // {"from": 19, "to": 18},
  184. // {"from": 20, "to": 16},
  185. // {"from": 20, "to": 17},
  186. // {"from": 20, "to": 18},
  187. // {"from": 20, "to": 19},
  188. // {"from": 21, "to": 16},
  189. // {"from": 21, "to": 17},
  190. // {"from": 21, "to": 18},
  191. // {"from": 21, "to": 19},
  192. // {"from": 21, "to": 20},
  193. // {"from": 22, "to": 16},
  194. // {"from": 22, "to": 17},
  195. // {"from": 22, "to": 18},
  196. // {"from": 22, "to": 19},
  197. // {"from": 22, "to": 20},
  198. // {"from": 22, "to": 21},
  199. // {"from": 23, "to": 16},
  200. // {"from": 23, "to": 17},
  201. // {"from": 23, "to": 18},
  202. // {"from": 23, "to": 19},
  203. // {"from": 23, "to": 20},
  204. // {"from": 23, "to": 21},
  205. // {"from": 23, "to": 22},
  206. // {"from": 23, "to": 12},
  207. // {"from": 23, "to": 11},
  208. // {"from": 24, "to": 23},
  209. // {"from": 24, "to": 11},
  210. // {"from": 25, "to": 24},
  211. // {"from": 25, "to": 23},
  212. // {"from": 25, "to": 11},
  213. // {"from": 26, "to": 24},
  214. // {"from": 26, "to": 11},
  215. // {"from": 26, "to": 16},
  216. // {"from": 26, "to": 25},
  217. // {"from": 27, "to": 11},
  218. // {"from": 27, "to": 23},
  219. // {"from": 27, "to": 25},
  220. // {"from": 27, "to": 24},
  221. // {"from": 27, "to": 26},
  222. // {"from": 28, "to": 11},
  223. // {"from": 28, "to": 27}
  224. // ]);
  225. var importedNetwork = '';
  226. var xhr3 = new XMLHttpRequest();
  227. xhr3.open("POST",'public/data.json', true);
  228. xhr3.send('givemethatshit');
  229. xhr3.onreadystatechange = function () {
  230. if (xhr3.readyState == 4) {
  231. importedNetwork = xhr3.responseText
  232. console.log(importedNetwork);
  233. nodes.add( JSON.parse(importedNetwork).nodes);
  234. console.log('mammmmmamia', JSON.parse(importedNetwork).nodes)
  235. edges.add(JSON.parse(importedNetwork).edges);
  236. }
  237. };
  238. // create a network
  239. var container = document.getElementById('mynetwork');
  240. var data = {
  241. nodes: nodes,
  242. edges: edges
  243. };
  244. var options = {
  245. manipulation: {
  246. addNode: function (data, callback) {
  247. // filling in the popup DOM elements
  248. document.getElementById('node-operation').innerHTML = "Add Node";
  249. editNode(data, clearNodePopUp, callback);
  250. },
  251. editNode: function (data, callback) {
  252. // filling in the popup DOM elements
  253. document.getElementById('node-operation').innerHTML = "Edit Node";
  254. editNode(data, cancelNodeEdit, callback);
  255. },
  256. addEdge: function (data, callback) {
  257. if (data.from == data.to) {
  258. var r = confirm("Do you want to connect the node to itself?");
  259. if (r != true) {
  260. callback(null);
  261. return;
  262. }
  263. }
  264. document.getElementById('edge-operation').innerHTML = "Add Edge";
  265. editEdgeWithoutDrag(data, callback);
  266. },
  267. editEdge: {
  268. editWithoutDrag: function(data, callback) {
  269. document.getElementById('edge-operation').innerHTML = "Edit Edge";
  270. editEdgeWithoutDrag(data,callback);
  271. }
  272. }
  273. }
  274. };
  275. network = new vis.Network(container, data, options);
  276. }
  277. var Nodebox1 = '<p class="test"><img src="'
  278. var Nodebox2 = '" style="width:300px;height:200px;float:up;">'
  279. var Nodebox3 = '</p>'
  280. function editNode(data, cancelAction, callback) {
  281. document.getElementById('node-descript').value = data.title;
  282. document.getElementById('node-label').value = data.label;
  283. document.getElementById('node-saveButton').onclick = saveNodeData.bind(this, data, callback);
  284. document.getElementById('node-cancelButton').onclick = cancelAction.bind(this, callback);
  285. document.getElementById('node-popUp').style.display = 'block';
  286. }
  287. // Callback passed as parameter is ignored
  288. function clearNodePopUp() {
  289. document.getElementById('node-saveButton').onclick = null;
  290. document.getElementById('node-cancelButton').onclick = null;
  291. document.getElementById('node-popUp').style.display = 'none';
  292. }
  293. function cancelNodeEdit(callback) {
  294. clearNodePopUp();
  295. callback(null);
  296. }
  297. function saveNodeData(data, callback) {
  298. data.label = document.getElementById('node-label').value;
  299. // data.title = Nodebox1 + data.image + Nodebox2 + document.getElementById('node-descript').value + Nodebox3;
  300. data.title = document.getElementById('node-descript').value;
  301. clearNodePopUp();
  302. callback(data);
  303. }
  304. function editEdgeWithoutDrag(data, callback) {
  305. // filling in the popup DOM elements
  306. document.getElementById('edge-color').value = data.color;
  307. document.getElementById('edge-descript').value = data.title;
  308. document.getElementById('edge-saveButton').onclick = saveEdgeData.bind(this, data, callback);
  309. document.getElementById('edge-cancelButton').onclick = cancelEdgeEdit.bind(this,callback);
  310. document.getElementById('edge-popUp').style.display = 'block';
  311. }
  312. function clearEdgePopUp() {
  313. document.getElementById('edge-saveButton').onclick = null;
  314. document.getElementById('edge-cancelButton').onclick = null;
  315. document.getElementById('edge-popUp').style.display = 'none';
  316. }
  317. function cancelEdgeEdit(callback) {
  318. clearEdgePopUp();
  319. callback(null);
  320. }
  321. var Edgebox1 = '<p class="test">'
  322. var Edgebox2 = '</p>'
  323. function saveEdgeData(data, callback) {
  324. if (typeof data.to === 'object')
  325. data.to = data.to.id
  326. if (typeof data.from === 'object')
  327. data.from = data.from.id
  328. data.arrows = 'to';
  329. data.color = document.getElementById('edge-color').value;
  330. // data.title = Edgebox1 + document.getElementById('edge-descript').value + Edgebox2;
  331. data.title = document.getElementById('edge-descript').value;
  332. clearEdgePopUp();
  333. callback(data);
  334. }
  335. function init() {
  336. draw();
  337. }
  338. function exportnetwork() {
  339. // import fs module in which writeFile function is defined.
  340. // myJSON = JSON.stringify(egdes);
  341. var xhr1=new XMLHttpRequest();
  342. var nodearray = JSON.stringify(JSON.parse(document.getElementById('nodes').firstChild.data));
  343. console.log(document.getElementById('edges').firstChild.data)
  344. // var array = document.getElementById('nodes').firstChild;
  345. xhr1.open("POST",'public/data.json', true);
  346. xhr1.send(nodearray);
  347. var edgearray = JSON.stringify(JSON.parse(document.getElementById('edges').firstChild.data));
  348. var xhr2 = new XMLHttpRequest();
  349. xhr1.onreadystatechange = function () {
  350. if (xhr1.readyState == 4) {
  351. xhr2.open("POST",'public/data.json', true);
  352. xhr2.send(edgearray);
  353. }
  354. };
  355. // xhr.send(null);
  356. xhr2.onreadystatechange = function () {
  357. if (xhr2.readyState == 4) {
  358. alert(xhr2.responseText);
  359. }
  360. };
  361. //
  362. }
  363. function focusOnNode() {
  364. var labeltofocus = ""
  365. labeltofocus = document.getElementById('labelinput').value;
  366. var nodeid
  367. console.log(document.getElementById('nodes').firstChild.data)
  368. console.log(document.getElementById('labelinput'))
  369. var i;
  370. nodeshere = JSON.parse(document.getElementById('nodes').firstChild.data)
  371. for (i = 0; i < nodeshere.length; i++) {
  372. if (nodeshere[i].label == labeltofocus) {
  373. nodeid = nodeshere[i].id;
  374. };
  375. }
  376. network.fit({
  377. nodes:[nodeid],
  378. animation: { // -------------------> can be a boolean too!
  379. duration: 1000,
  380. easingFunction: "easeInOutQuad"
  381. }
  382. }
  383. );
  384. }
  385. </script>
  386. </head>
  387. <body onload="init();">
  388. <h2 style="height:20px; font-size:90px">
  389. <span style='color: green'>perm</span><span style='color: red'>A</span><span style='color: green'>pp</span>
  390. </h2>
  391. <p style="width: 700px; font-size:16px; text-align: justify;">
  392. .explore relations between entities of the ecosystem
  393. </p>
  394. <div id="node-popUp">
  395. <span id="node-operation">node</span> <br>
  396. <table style="margin:auto;">
  397. <tr>
  398. <td>label</td><td><input id="node-label" value="new value" /></td>
  399. </tr>
  400. <tr>
  401. <td>description</td><td><input id="node-descript" value="new value" /></td>
  402. </tr>
  403. </table>
  404. <input type="button" value="save" id="node-saveButton" />
  405. <input type="button" value="cancel" id="node-cancelButton" />
  406. </div>
  407. <div id="edge-popUp">
  408. <span id="edge-operation">edge</span> <br>
  409. <table style="margin:auto;">
  410. <tr>
  411. <td>red/green</td><td><input id="edge-color" value="new value" /></td>
  412. </tr></table>
  413. <tr>
  414. <td>description</td><td><input id="edge-descript" value="new value" /></td>
  415. </tr></table>
  416. <input type="button" value="save" id="edge-saveButton" />
  417. <input type="button" value="cancel" id="edge-cancelButton" />
  418. </div>
  419. <div class="bottom">
  420. <span id="statusUpdate"></span>
  421. <br />
  422. <input type="button" onclick="exportnetwork();" value="save changes" style="width:800px;height:50px;color:black;background-color:lightblue;" id="btnexport"><br/>
  423. <br />
  424. <input type="button" onclick="focusOnNode();" value="Focus on node:" style="width:800px;height:50px;color:black;background-color:lightblue;" id="btnFocus"><br/>
  425. <tr>
  426. <td> </td><td><input type="text" value="" id="labelinput" style="width:785px;"> </td>
  427. </tr>
  428. </div>
  429. <br />
  430. <div id="mynetwork"></div>
  431. <h1>View</h1>
  432. <table class="view">
  433. <tr>
  434. <td>
  435. <h2>Nodes</h2>
  436. <pre id="nodes"></pre>
  437. </td>
  438. <td>
  439. <h2>Edges</h2>
  440. <pre id="edges"></pre>
  441. </td>
  442. </body>
  443. </html>