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.

482 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">
  93. var nodes = null;
  94. var edges = null;
  95. var network = null;
  96. function destroy() {
  97. if (network !== null) {
  98. network.destroy();
  99. network = null;
  100. }
  101. }
  102. function draw() {
  103. destroy();
  104. nodes = [];
  105. edges = [];
  106. // create a network
  107. var DIR = "public/images/";
  108. nodes = [
  109. {id: 0, shape: 'circularImage', image: DIR + 'canna.jpg', "label": "Cannabis", "group": 1, title: 'I am a plant' },
  110. {id: 1, shape: 'circularImage', image: DIR + 'rose.jpg', "label": "Rose", "group": 1},
  111. {id: 2, "label": "Tomato", "group": 1},
  112. {id: 3, "label": "Mint", "group": 1},
  113. {id: 4, "label": "Basil", "group": 1},
  114. {id: 5, "label": "Acorn", "group": 1},
  115. {id: 6, "label": "Pine", "group": 1},
  116. {id: 7, "label": "Orange", "group": 1},
  117. {id: 8, "label": "Lemon", "group": 1},
  118. {id: 9, shape: 'circularImage', image: DIR + 'sunflower.jpg', "label": "Sunflower", "group": 1},
  119. {id: 10, "label": "Marigold", "group": 1},
  120. {id: 11, "label": "Alfalfa", "group": 1},
  121. {id: 12, "label": "Red Clover", "group": 1},
  122. {id: 13, "label": "Chervil", "group": 1},
  123. {id: 14, "label": "White Clover", "group": 1},
  124. {id: 15, "label": "Lavender", "group": 1},
  125. {id: 16, "label": "Coriander", "group": 1},
  126. {id: 17, shape: 'circularImage', image: DIR + 'chamomile.jpg', "label": "Chamomile", "group": 1},
  127. {id: 18, "label": "Yarrow", "group": 1},
  128. {id: 19, "label": "Dill", "group": 1},
  129. {id: 20, "label": "Lemon Balm", "group": 1},
  130. {id: 21, "label": "Borage", "group": 1},
  131. {id: 22, "label": "Ant", "group": 2},
  132. {id: 23, "label": "Bee", "group": 2},
  133. {id: 24, "label": "Snail", "group": 2},
  134. {id: 25, "label": "Heat", "group": 3},
  135. {id: 26, "label": "Water", "group": 3},
  136. {id: 27, "label": "Luminance", "group": 3},
  137. {id: 28, "label": "Bird", "group": 2}
  138. ];
  139. var Edgebox1 = '<p class="test">'
  140. var Edgebox2 = '</p>'
  141. // create some edges
  142. var edges = [
  143. {"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},
  144. {"from": 2, "to": 0},
  145. {"from": 3, "to": 0},
  146. {"from": 3, "to": 2},
  147. {"from": 4, "to": 0},
  148. {"from": 5, "to": 0},
  149. {"from": 6, "to": 0},
  150. {"from": 7, "to": 0},
  151. {"from": 8, "to": 0},
  152. {"from": 9, "to": 0},
  153. {"from": 11, "to": 10},
  154. {"from": 11, "to": 3},
  155. {"from": 11, "to": 2},
  156. {"from": 11, "to": 0},
  157. {"from": 12, "to": 11},
  158. {"from": 13, "to": 11},
  159. {"from": 14, "to": 11},
  160. {"from": 15, "to": 11},
  161. {"from": 17, "to": 16},
  162. {"from": 18, "to": 16},
  163. {"from": 18, "to": 17},
  164. {"from": 19, "to": 16},
  165. {"from": 19, "to": 17},
  166. {"from": 19, "to": 18},
  167. {"from": 20, "to": 16},
  168. {"from": 20, "to": 17},
  169. {"from": 20, "to": 18},
  170. {"from": 20, "to": 19},
  171. {"from": 21, "to": 16},
  172. {"from": 21, "to": 17},
  173. {"from": 21, "to": 18},
  174. {"from": 21, "to": 19},
  175. {"from": 21, "to": 20},
  176. {"from": 22, "to": 16},
  177. {"from": 22, "to": 17},
  178. {"from": 22, "to": 18},
  179. {"from": 22, "to": 19},
  180. {"from": 22, "to": 20},
  181. {"from": 22, "to": 21},
  182. {"from": 23, "to": 16},
  183. {"from": 23, "to": 17},
  184. {"from": 23, "to": 18},
  185. {"from": 23, "to": 19},
  186. {"from": 23, "to": 20},
  187. {"from": 23, "to": 21},
  188. {"from": 23, "to": 22},
  189. {"from": 23, "to": 12},
  190. {"from": 23, "to": 11},
  191. {"from": 24, "to": 23},
  192. {"from": 24, "to": 11},
  193. {"from": 25, "to": 24},
  194. {"from": 25, "to": 23},
  195. {"from": 25, "to": 11},
  196. {"from": 26, "to": 24},
  197. {"from": 26, "to": 11},
  198. {"from": 26, "to": 16},
  199. {"from": 26, "to": 25},
  200. {"from": 27, "to": 11},
  201. {"from": 27, "to": 23},
  202. {"from": 27, "to": 25},
  203. {"from": 27, "to": 24},
  204. {"from": 27, "to": 26},
  205. {"from": 28, "to": 11},
  206. {"from": 28, "to": 27}
  207. ];
  208. // create a network
  209. var container = document.getElementById('mynetwork');
  210. var data = {
  211. nodes: nodes,
  212. edges: edges
  213. };
  214. var options = {
  215. manipulation: {
  216. addNode: function (data, callback) {
  217. // filling in the popup DOM elements
  218. document.getElementById('node-operation').innerHTML = "Add Node";
  219. editNode(data, clearNodePopUp, callback);
  220. },
  221. editNode: function (data, callback) {
  222. // filling in the popup DOM elements
  223. document.getElementById('node-operation').innerHTML = "Edit Node";
  224. editNode(data, cancelNodeEdit, callback);
  225. },
  226. addEdge: function (data, callback) {
  227. if (data.from == data.to) {
  228. var r = confirm("Do you want to connect the node to itself?");
  229. if (r != true) {
  230. callback(null);
  231. return;
  232. }
  233. }
  234. document.getElementById('edge-operation').innerHTML = "Add Edge";
  235. editEdgeWithoutDrag(data, callback);
  236. },
  237. editEdge: {
  238. editWithoutDrag: function(data, callback) {
  239. document.getElementById('edge-operation').innerHTML = "Edit Edge";
  240. editEdgeWithoutDrag(data,callback);
  241. }
  242. }
  243. }
  244. };
  245. network = new vis.Network(container, data, options);
  246. }
  247. var Nodebox1 = '<p class="test"><img src="'
  248. var Nodebox2 = '" style="width:300px;height:200px;float:up;">'
  249. var Nodebox3 = '</p>'
  250. function editNode(data, cancelAction, callback) {
  251. document.getElementById('node-descript').value = data.title;
  252. document.getElementById('node-label').value = data.label;
  253. document.getElementById('node-saveButton').onclick = saveNodeData.bind(this, data, callback);
  254. document.getElementById('node-cancelButton').onclick = cancelAction.bind(this, callback);
  255. document.getElementById('node-popUp').style.display = 'block';
  256. }
  257. // Callback passed as parameter is ignored
  258. function clearNodePopUp() {
  259. document.getElementById('node-saveButton').onclick = null;
  260. document.getElementById('node-cancelButton').onclick = null;
  261. document.getElementById('node-popUp').style.display = 'none';
  262. }
  263. function cancelNodeEdit(callback) {
  264. clearNodePopUp();
  265. callback(null);
  266. }
  267. function saveNodeData(data, callback) {
  268. data.label = document.getElementById('node-label').value;
  269. data.title = Nodebox1 + data.image + Nodebox2 + document.getElementById('node-descript').value + Nodebox3;
  270. clearNodePopUp();
  271. callback(data);
  272. }
  273. function editEdgeWithoutDrag(data, callback) {
  274. // filling in the popup DOM elements
  275. document.getElementById('edge-color').value = data.color;
  276. document.getElementById('edge-descript').value = data.title;
  277. document.getElementById('edge-saveButton').onclick = saveEdgeData.bind(this, data, callback);
  278. document.getElementById('edge-cancelButton').onclick = cancelEdgeEdit.bind(this,callback);
  279. document.getElementById('edge-popUp').style.display = 'block';
  280. }
  281. function clearEdgePopUp() {
  282. document.getElementById('edge-saveButton').onclick = null;
  283. document.getElementById('edge-cancelButton').onclick = null;
  284. document.getElementById('edge-popUp').style.display = 'none';
  285. }
  286. function cancelEdgeEdit(callback) {
  287. clearEdgePopUp();
  288. callback(null);
  289. }
  290. var Edgebox1 = '<p class="test">'
  291. var Edgebox2 = '</p>'
  292. function saveEdgeData(data, callback) {
  293. if (typeof data.to === 'object')
  294. data.to = data.to.id
  295. if (typeof data.from === 'object')
  296. data.from = data.from.id
  297. data.arrows = 'to';
  298. data.color = document.getElementById('edge-color').value;
  299. data.title = Edgebox1 + document.getElementById('edge-descript').value + Edgebox2;
  300. clearEdgePopUp();
  301. callback(data);
  302. }
  303. function init() {
  304. draw();
  305. }
  306. function exportnetwork() {
  307. // import fs module in which writeFile function is defined.
  308. const fsLibrary = require('fs')
  309. // Data which will need to add in a file.
  310. // Write data in 'newfile.txt' .
  311. fsLibrary.writeFile('network_edges.txt', edges, (error) => {
  312. // In case of a error throw err exception.
  313. if (error) throw err;
  314. })
  315. fsLibrary.writeFile('network_nodes.txt', nodes, (error) => {
  316. // In case of a error throw err exception.
  317. if (error) throw err;
  318. })
  319. }
  320. function importnetwork() {
  321. // import fs module in which readFile function is specified.
  322. const fsLibrary = require('fs')
  323. fsLibrary.readFile('network_nodes.txt', (error, nodes) => {
  324. if (error) throw err;
  325. console.log(nodes.toString());
  326. })
  327. fsLibrary.readFile('network_edges.txt', (error, edges) => {
  328. if (error) throw err;
  329. console.log(nodes.toString());
  330. })
  331. }
  332. function focusOnNode() {
  333. var labeltofocus = ""
  334. labeltofocus = document.getElementById('labelinput').value;
  335. var nodeid
  336. var i;
  337. for (i = 0; i < nodes.length; i++) {
  338. if (nodes[i].label == labeltofocus) {
  339. nodeid = nodes[i].id;
  340. };
  341. }
  342. network.fit({
  343. nodes:[nodeid],
  344. animation: { // -------------------> can be a boolean too!
  345. duration: 1000,
  346. easingFunction: "easeInOutQuad"
  347. }
  348. }
  349. );
  350. }
  351. </script>
  352. </head>
  353. <body onload="init();">
  354. <h2 style="height:20px; font-size:90px">
  355. <span style='color: green'>perm</span><span style='color: red'>A</span><span style='color: green'>pp</span>
  356. </h2>
  357. <p style="width: 700px; font-size:16px; text-align: justify;">
  358. .explore relations between entities of the ecosystem
  359. </p>
  360. <div id="node-popUp">
  361. <span id="node-operation">node</span> <br>
  362. <table style="margin:auto;">
  363. <tr>
  364. <td>label</td><td><input id="node-label" value="new value" /></td>
  365. </tr>
  366. <tr>
  367. <td>description</td><td><input id="node-descript" value="new value" /></td>
  368. </tr>
  369. </table>
  370. <input type="button" value="save" id="node-saveButton" />
  371. <input type="button" value="cancel" id="node-cancelButton" />
  372. </div>
  373. <div id="edge-popUp">
  374. <span id="edge-operation">edge</span> <br>
  375. <table style="margin:auto;">
  376. <tr>
  377. <td>red/green</td><td><input id="edge-color" value="new value" /></td>
  378. </tr></table>
  379. <tr>
  380. <td>description</td><td><input id="edge-descript" value="new value" /></td>
  381. </tr></table>
  382. <input type="button" value="save" id="edge-saveButton" />
  383. <input type="button" value="cancel" id="edge-cancelButton" />
  384. </div>
  385. <div class="bottom">
  386. <span id="statusUpdate"></span>
  387. <br />
  388. <input type="button" onclick="exportnetwork();" value="export network to txt file:" style="width:800px;height:50px;color:black;background-color:lightblue;" id="btnFocus"><br/>
  389. <br />
  390. <input type="button" onclick="focusOnNode();" value="Focus on node:" style="width:800px;height:50px;color:black;background-color:lightblue;" id="btnFocus"><br/>
  391. <tr>
  392. <td> </td><td><input type="text" value="" id="labelinput" style="width:785px;"> </td>
  393. </tr>
  394. </div>
  395. <br />
  396. <div id="mynetwork"></div>
  397. </body>
  398. </html>