server actix for cannabinieri website
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.

278 lines
7.3 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. // replace div data with translated (html output askama)
  2. // like this ? title: "{{"title1"|translate(lang)}}"
  3. let graph = {
  4. nodes : [
  5. {id : "hemp", url: "/hemp" ,index: 0, x: 719.1790913580512, y: 326.11409230900296, vy: 0.0009665554475078223, vx: 0.00044710537175425926, title: "Title1", content: "Content 1"},
  6. {id : "permapp", url: "/spider/permapp",index: 1, x: 473.51321690437135, y: 317.1181430586339, vy: 0.0005811239352358496, vx: 0.0005105059544352408, title: "Title 2", content: "Content 2"},
  7. {id : "offgrid",url: "/offgrid", index: 2, x: 495.66982580572676, y: 18.53, vy: 0.0007713356454593206, vx: 0.0007887999665437037, title: "Title 3", content: "Content 3"},
  8. {id : "cyberpreneur",url: "/cyberpreneur", index: 3, x: 457.9995206323447, y: 277.13445200140694, vy: 0.0004637678594351416, vx: 0.0007441570379881761, title: "Title 4", content: "Content 4" },
  9. {id : "kaoscube",url: "/kaoscube", index: 4, x: 428.05791236956037, y: 237.65121337678465, vy: 0.00037483669542696317, vx: 0.00039028860355878376, title: "Title 5", content: "Content 5"},
  10. {id : "spider", url: "/spider",index: 5, x: 461.65464520161396, y: 189.18158017082138, vy: -0.00023265081878199873, vx: 0.00006278089396472572, title: "Title 6", content: "Content 6" }
  11. ],
  12. links : [
  13. {source: 0, target: 1, index: 0 },
  14. {source: 0, target: 2, index: 1 },
  15. {source: 0, target: 3, index: 2 },
  16. {source: 0, target: 4, index: 3 },
  17. {source: 1, target: 2, index: 4 },
  18. {source: 1, target: 4, index: 5 },
  19. {source: 2, target: 3 ,index: 6 },
  20. {source: 2, target: 4 ,index: 7 },
  21. {source: 2, target: 5 ,index: 8 },
  22. {source: 4, target: 5 ,index: 9 }
  23. ],
  24. }
  25. // has to be made responsive to actual screensize !
  26. let width = 100;
  27. let height = 200;
  28. let radius = 15;
  29. const svg = d3.select("#mobile_network").append("svg").attr("viewBox", "0, 0, 100, 200").attr("preserveAspectRatio", "xMidYMid meet").attr("style", "position: relative;"),
  30. link = svg
  31. .selectAll(".link")
  32. .data(graph.links)
  33. .join("line")
  34. .classed("link", true),
  35. node = svg
  36. .selectAll(".node")
  37. .data(graph.nodes)
  38. .join("circle")
  39. .attr("id", d => d.id)
  40. .attr("r", 15)
  41. .classed("node", true)
  42. .classed("fixed", d => d.fx !== undefined);
  43. const node1 = svg.select("#hemp")
  44. .attr("fill", "url(#imgHemp)")
  45. const node2 = svg.select("#permapp")
  46. .attr("fill", "url(#imgPermapp)");
  47. const node3 = svg.select("#spider")
  48. .attr("fill", "url(#imgSpider)");
  49. const node4 = svg.select("#cyberpreneur")
  50. .attr("fill", "url(#imgCyber)");
  51. const node5 = svg.select("#kaoscube")
  52. .attr("fill", "url(#imgKaos)");
  53. const node6 = svg.select("#offgrid")
  54. .attr("fill", "url(#imgOff)");
  55. const defs = svg.append("svg:defs");
  56. defs.append("svg:pattern")
  57. .attr("width", "100%")
  58. .attr("height", "100%")
  59. .attr("id", "imgHemp")
  60. .append("svg:image")
  61. .attr("xlink:href", "/assets/img/hemp.webp")
  62. .attr("width", 45)
  63. .attr("height", 45)
  64. .attr("x", -7 )
  65. .attr("y", 0);
  66. defs.append("svg:pattern")
  67. .attr("width", "100%")
  68. .attr("height", "100%")
  69. .attr("id", "imgPermapp")
  70. .append("svg:image")
  71. .attr("xlink:href", "/assets/img/v1-permapp.webp")
  72. .attr("width", 35)
  73. .attr("height", 35)
  74. .attr("x", 0 )
  75. .attr("y", 0);
  76. defs.append("svg:pattern")
  77. .attr("width", "100%")
  78. .attr("height", "100%")
  79. .attr("id", "imgSpider")
  80. .append("svg:image")
  81. .attr("xlink:href", "/assets/img/spider_out.webp")
  82. .attr("width", 45)
  83. .attr("height", 45)
  84. .attr("x", -4 )
  85. .attr("y", -7);
  86. defs.append("svg:pattern")
  87. .attr("width", "100%")
  88. .attr("height", "100%")
  89. .attr("id", "imgCyber")
  90. .append("svg:image")
  91. .attr("xlink:href", "/assets/img/3d_greenhouse.webp")
  92. .attr("width", 50)
  93. .attr("height", 50)
  94. .attr("x", -5 )
  95. .attr("y", -10);
  96. defs.append("svg:pattern")
  97. .attr("width", "100%")
  98. .attr("height", "100%")
  99. .attr("id", "imgKaos")
  100. .append("svg:image")
  101. .attr("xlink:href", "/assets/img/cube_space.webp")
  102. .attr("width", 40)
  103. .attr("height", 40)
  104. .attr("x", -6 )
  105. .attr("y", -6);
  106. defs.append("svg:pattern")
  107. .attr("width", "100%")
  108. .attr("height", "100%")
  109. .attr("id", "imgOff")
  110. .append("svg:image")
  111. .attr("xlink:href", "/assets/img/boat_construction.webp")
  112. .attr("width", 40)
  113. .attr("height", 40)
  114. .attr("x", -5 )
  115. .attr("y", -6);
  116. const simulation = d3
  117. .forceSimulation()
  118. .nodes(graph.nodes)
  119. .force("charge", d3.forceManyBody().strength(-300))
  120. .force("center", d3.forceCenter(width / 2.5, height / 2.25))
  121. .force("link", d3.forceLink(graph.links).distance(30))
  122. .force("collide", d3.forceCollide(22))
  123. .force("x", d3.forceX(-30))
  124. .on("tick", tick);
  125. const drag = d3
  126. .drag()
  127. .on("start", dragstart)
  128. .on("drag", dragged);
  129. node.call(drag).on("click", click);
  130. // on doubleclick release position
  131. node.on("dblclick", release );
  132. function release(event, d) {
  133. // back to original position
  134. delete d.fx;
  135. delete d.fy;
  136. simulation.alpha(1).restart();
  137. }
  138. // make this work on touch as well !
  139. function click(event, d) {
  140. d3.select(this).classed("fixed", false);
  141. }
  142. function dragstart() {
  143. // select element and set position to fixed
  144. d3.select(this).classed("fixed", true);
  145. // show box on single click
  146. toggleDiv(this.id, status);
  147. console.log("box atrr", box.attr("class"));
  148. if ( box.attr("class") == "box_on" ) {
  149. // make nodes underneath unclickable as long as box is open !
  150. this.__on = null;
  151. }
  152. // this refers to dragged circle element
  153. console.log("dragstart", this.id);
  154. }
  155. function dragged(event, d) {
  156. console.log("dragged",d.id);
  157. // set x position of dragged node
  158. d.fx = clamp(event.x, 0, width);
  159. // set x position of dragged node
  160. d.fy = clamp(event.y, 0, height);
  161. // sets duration of animation before restart
  162. simulation.alpha(1).restart();
  163. }
  164. function tick() {
  165. link
  166. .attr("x1", d => d.source.x)
  167. .attr("y1", d => d.source.y)
  168. .attr("x2", d => d.target.x)
  169. .attr("y2", d => d.target.y);
  170. node
  171. .attr("cx", d => d.x = Math.max(radius, Math.min(width - radius, d.x)))
  172. .attr("cy", d => d.y = Math.max(radius, Math.min(height - radius, d.y)));
  173. }
  174. function clamp(x, lo, hi) {
  175. return x < lo ? lo : x > hi ? hi : x;
  176. }
  177. // show info divs with data based on id
  178. // the infobox
  179. const box = d3.select("#box")
  180. // state of box
  181. let toggleDiv = undefined;
  182. // all nodes
  183. let nodeArray = graph.nodes;
  184. // change status of a box from visible to hidden and viceversa on click
  185. toggleDiv = function( event, status ) {
  186. if ( status == "" ) {
  187. status = box.attr("class") == "box_off" ? "box_on" : "box_off";
  188. box.attr("class", status);
  189. } else {
  190. console.log("status is", status);
  191. }
  192. }
  193. // Like that somehow: embed data as html
  194. // Get content data
  195. //Parameters: data, array containing all nodes
  196. function getContent( n, nodeArray ) {
  197. info = '<div id="box">';
  198. if( n.link )
  199. // get link of node
  200. info += '<a href="' + n.url + '"/>';
  201. else
  202. console.log("couldn't get link:", n.url);
  203. if( n.title )
  204. info += '<h1 id="title">"' + n.title + '"/>'
  205. else
  206. console.log("couldn't get title:", n.title);
  207. if( n.content )
  208. info += '<p id="content><"' + n.content + '"/>'
  209. console.log("couldn't get title:", n.content);
  210. return info;
  211. }
  212. // Show box for a given node
  213. function showContent( node ) {
  214. // Fill it and display the box
  215. box
  216. .html( getContent(node,nodeArray) )
  217. }