heatContainer.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import LineHeatmap from "./lineHeatmap";
  2. import "nouislider";
  3. const template = `<div>
  4. <div class="line-heatmap-controls">
  5. <div id="line-heatmap-slider"></div>
  6. </div>
  7. <div id="line-heatmap-canvas">
  8. <div id="line-heatmap-view"></div>
  9. <div id="line-heatmap-tooltip"></div>
  10. </div>
  11. </div>
  12. `;
  13. const cursorDist = 10;
  14. const stateObject = {};
  15. let x1, y1, x2, y2;
  16. let firstClick = true;
  17. let div = null;
  18. let posLeft;
  19. let posTop;
  20. let yBottom;
  21. let xBottom;
  22. function init (elementId, logString, useTooltip = false, config = {}) {
  23. const el = document.getElementById(elementId);
  24. el.innerHTML = template;
  25. const logData = logTransform(logString);
  26. // create container
  27. const heatmap = new LineHeatmap('line-heatmap-view');
  28. heatmap.create(config);
  29. heatmap.setTrackData(logData);
  30. const html5Slider = document.getElementById('line-heatmap-slider');
  31. noUiSlider.create(html5Slider, {
  32. start: [1, logData.length],
  33. connect: true,
  34. step: 1,
  35. margin: 1,
  36. range: {
  37. 'min': 1,
  38. 'max': logData.length
  39. }
  40. });
  41. stateObject['container'] = el;
  42. stateObject['heatmap'] = heatmap;
  43. stateObject['data'] = logData;
  44. stateObject['slider'] = html5Slider;
  45. if (useTooltip) {
  46. registerClickEvent();
  47. const canvasWrapper = document.getElementById('line-heatmap-canvas');
  48. const tooltip = document.getElementById('line-heatmap-tooltip');
  49. function updateTooltip (x, y, value) {
  50. const transl = `translate(${x + cursorDist}px, ${y + cursorDist}px)`;
  51. tooltip.style.webkitTransform = transl;
  52. tooltip.innerHTML = `(${x},${y},${value})`;
  53. };
  54. canvasWrapper.onmousemove = function (ev) {
  55. var x = ev.layerX;
  56. var y = ev.layerY;
  57. // getValueAt gives us the value for a point p(x/y)
  58. var value = stateObject['heatmap'].instance.getValueAt({
  59. x: x,
  60. y: y
  61. });
  62. tooltip.style.display = 'block';
  63. updateTooltip(x, y, value);
  64. };
  65. // hide tooltip on mouseout
  66. canvasWrapper.onmouseout = function() {
  67. tooltip.style.display = 'none';
  68. };
  69. /* tooltip code end */
  70. }
  71. html5Slider.noUiSlider.on('update', function (values, handle) {
  72. const logValues = this.get();
  73. const newData = stateObject['data'].slice(+logValues[0]-1, +logValues[1] + 1);
  74. stateObject['heatmap'].setTrackData(newData);
  75. if(div !== null)
  76. updateDivText(div, posLeft, posTop, xBottom, yBottom);
  77. });
  78. }
  79. function updateLogString (logString) {
  80. const logData = logTransform(logString);
  81. stateObject['data'] = logData;
  82. stateObject['slider'].noUiSlider.updateOptions({
  83. range: {
  84. 'min': 1,
  85. 'max': logData.length
  86. }
  87. });
  88. stateObject['heatmap'].setTrackData(logData);
  89. }
  90. function countClicks (x1, y1, x2, y2) {
  91. const instance = stateObject['heatmap'].instance;
  92. const points = instance.getData().data;
  93. let counter = 0;
  94. for(let i = 0; i < points.length; ++i) {
  95. const point = points[i];
  96. if (point.x >= x1 && point.y >= y1) {
  97. if (point.x <= x2 && point.y <= y2) {
  98. counter += point.value;
  99. }
  100. }
  101. }
  102. return counter;
  103. }
  104. function totalClicks () {
  105. return stateObject['data'].length;
  106. }
  107. function logTransform (logString) {
  108. const data = logString.split("\n")
  109. .filter(v => v.split(',').length > 3)
  110. .map(v => {
  111. const o = JSON.parse('[' + v + ']');
  112. return {
  113. x: o[0],
  114. y: o[1],
  115. value: 1
  116. };
  117. });
  118. return data;
  119. }
  120. function registerClickEvent () {
  121. const elemen = document.querySelector(".heatmap-canvas");
  122. window.onclick = function (evt) {
  123. if(evt.target !== elemen) {
  124. return;
  125. }
  126. if (firstClick) {
  127. if (evt.pageX || evt.pageY) {
  128. x1 = evt.pageX;
  129. y1 = evt.pageY;
  130. } else {
  131. x1 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
  132. y1 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
  133. }
  134. x1 -= elemen.offsetLeft;
  135. y1 -= elemen.offsetTop;
  136. firstClick = false;
  137. } else {
  138. if (evt.pageX || evt.pageY) {
  139. x2 = evt.pageX;
  140. y2 = evt.pageY;
  141. } else {
  142. x2 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
  143. y2 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
  144. }
  145. x2 -= elemen.offsetLeft;
  146. y2 -= elemen.offsetTop;
  147. firstClick = true;
  148. if (div !== null) {
  149. document.getElementById("line-heatmap-canvas").removeChild(div);
  150. div = null;
  151. }
  152. div = document.createElement("div");
  153. posLeft = Math.min(x1,x2);
  154. posTop = Math.min(y1,y2) - 585;
  155. yBottom = Math.max(y1,y2) - 585;
  156. xBottom = Math.max(x1,x2);
  157. const width = Math.abs(xBottom - posLeft);
  158. const height = Math.abs(yBottom - posTop);
  159. updateDivText(div, posLeft, posTop, xBottom, yBottom);
  160. div.style.width = width + "px";
  161. div.style.height = height + "px";
  162. div.style.position = "absolute";
  163. div.style.top = posTop + "px";
  164. div.style.left = posLeft + "px";
  165. div.style.border = "1px solid green";
  166. document.getElementById("line-heatmap-canvas").append(div);
  167. }
  168. }
  169. }
  170. function updateDivText (div, posLeft, posTop, xBottom, yBottom) {
  171. const count = countClicks(posLeft, posTop, xBottom, yBottom);
  172. const ratio = count/totalClicks();
  173. div.innerHTML = `<span style="font-size:14px">Quantidade de clicks: ${count}</span>
  174. <span style="font-size:14px">Proporção em relação ao total: ${ratio}</span>`;
  175. }
  176. export default {
  177. init,
  178. updateLogString,
  179. countClicks,
  180. totalClicks
  181. }
  182. /**
  183. var x1, y1, x2, y2;
  184. var sequencia = 1;
  185. window.onclick = function(evt) {
  186. var elemen = document.querySelector(".heatmap-canvas");
  187. if (sequencia == 1) {
  188. if (evt.pageX || evt.pageY) {
  189. x1 = evt.pageX;
  190. y1 = evt.pageY;
  191. } else {
  192. x1 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
  193. y1 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
  194. }
  195. x1 -= elemen.offsetLeft;
  196. y1 -= elemen.offsetTop;
  197. sequencia ++;
  198. } else {
  199. if (evt.pageX || evt.pageY) {
  200. x2 = evt.pageX;
  201. y2 = evt.pageY;
  202. } else {
  203. x2 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
  204. y2 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
  205. }
  206. x2 -= elemen.offsetLeft;
  207. y2 -= elemen.offsetTop;
  208. var width = Math.abs(x2 - x1);
  209. var height = Math.abs(y2 - y1);
  210. sequencia = 1;
  211. $('#line-heatmap-canvas').append($('<div style="position: absolute; border: 1px solid green; top: '+(y1 - 580)+'px; left: '+x1+'px; width: '+width+'px; height: '+height+'px; "></div>'));
  212. }
  213. }
  214. */