|
@@ -6,25 +6,39 @@ const template = `<div>
|
|
<div id="line-heatmap-slider"></div>
|
|
<div id="line-heatmap-slider"></div>
|
|
</div>
|
|
</div>
|
|
<div id="line-heatmap-canvas">
|
|
<div id="line-heatmap-canvas">
|
|
|
|
+ <div id="line-heatmap-view"></div>
|
|
|
|
+ <div id="line-heatmap-tooltip"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
`;
|
|
|
|
|
|
|
|
+const cursorDist = 10;
|
|
|
|
+
|
|
const stateObject = {};
|
|
const stateObject = {};
|
|
|
|
|
|
-function init (elementId, logString) {
|
|
|
|
|
|
+let x1, y1, x2, y2;
|
|
|
|
+let firstClick = true;
|
|
|
|
+let div = null;
|
|
|
|
+
|
|
|
|
+let posLeft;
|
|
|
|
+let posTop;
|
|
|
|
+let yBottom;
|
|
|
|
+let xBottom;
|
|
|
|
+
|
|
|
|
+function init (elementId, logString, useTooltip = false, config = {}) {
|
|
const el = document.getElementById(elementId);
|
|
const el = document.getElementById(elementId);
|
|
el.innerHTML = template;
|
|
el.innerHTML = template;
|
|
const logData = logTransform(logString);
|
|
const logData = logTransform(logString);
|
|
// create container
|
|
// create container
|
|
- const heatmap = new LineHeatmap('line-heatmap-canvas');
|
|
|
|
- heatmap.create();
|
|
|
|
|
|
+ const heatmap = new LineHeatmap('line-heatmap-view');
|
|
|
|
+ heatmap.create(config);
|
|
heatmap.setTrackData(logData);
|
|
heatmap.setTrackData(logData);
|
|
|
|
|
|
const html5Slider = document.getElementById('line-heatmap-slider');
|
|
const html5Slider = document.getElementById('line-heatmap-slider');
|
|
noUiSlider.create(html5Slider, {
|
|
noUiSlider.create(html5Slider, {
|
|
start: [1, logData.length],
|
|
start: [1, logData.length],
|
|
connect: true,
|
|
connect: true,
|
|
|
|
+ step: 1,
|
|
margin: 1,
|
|
margin: 1,
|
|
range: {
|
|
range: {
|
|
'min': 1,
|
|
'min': 1,
|
|
@@ -37,12 +51,40 @@ function init (elementId, logString) {
|
|
stateObject['data'] = logData;
|
|
stateObject['data'] = logData;
|
|
stateObject['slider'] = html5Slider;
|
|
stateObject['slider'] = html5Slider;
|
|
|
|
|
|
|
|
+ if (useTooltip) {
|
|
|
|
+ registerClickEvent();
|
|
|
|
+ const canvasWrapper = document.getElementById('line-heatmap-canvas');
|
|
|
|
+ const tooltip = document.getElementById('line-heatmap-tooltip');
|
|
|
|
+ function updateTooltip (x, y, value) {
|
|
|
|
+ const transl = `translate(${x + cursorDist}px, ${y + cursorDist}px)`;
|
|
|
|
+ tooltip.style.webkitTransform = transl;
|
|
|
|
+ tooltip.innerHTML = `(${x},${y},${value})`;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ canvasWrapper.onmousemove = function (ev) {
|
|
|
|
+ var x = ev.layerX;
|
|
|
|
+ var y = ev.layerY;
|
|
|
|
+ // getValueAt gives us the value for a point p(x/y)
|
|
|
|
+ var value = stateObject['heatmap'].instance.getValueAt({
|
|
|
|
+ x: x,
|
|
|
|
+ y: y
|
|
|
|
+ });
|
|
|
|
+ tooltip.style.display = 'block';
|
|
|
|
+ updateTooltip(x, y, value);
|
|
|
|
+ };
|
|
|
|
+ // hide tooltip on mouseout
|
|
|
|
+ canvasWrapper.onmouseout = function() {
|
|
|
|
+ tooltip.style.display = 'none';
|
|
|
|
+ };
|
|
|
|
+ /* tooltip code end */
|
|
|
|
+ }
|
|
|
|
+
|
|
html5Slider.noUiSlider.on('update', function (values, handle) {
|
|
html5Slider.noUiSlider.on('update', function (values, handle) {
|
|
const logValues = this.get();
|
|
const logValues = this.get();
|
|
- console.log(logValues);
|
|
|
|
const newData = stateObject['data'].slice(+logValues[0]-1, +logValues[1] + 1);
|
|
const newData = stateObject['data'].slice(+logValues[0]-1, +logValues[1] + 1);
|
|
- console.log(newData);
|
|
|
|
stateObject['heatmap'].setTrackData(newData);
|
|
stateObject['heatmap'].setTrackData(newData);
|
|
|
|
+ if(div !== null)
|
|
|
|
+ updateDivText(div, posLeft, posTop, xBottom, yBottom);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -58,6 +100,25 @@ function updateLogString (logString) {
|
|
stateObject['heatmap'].setTrackData(logData);
|
|
stateObject['heatmap'].setTrackData(logData);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+function countClicks (x1, y1, x2, y2) {
|
|
|
|
+ const instance = stateObject['heatmap'].instance;
|
|
|
|
+ const points = instance.getData().data;
|
|
|
|
+ let counter = 0;
|
|
|
|
+ for(let i = 0; i < points.length; ++i) {
|
|
|
|
+ const point = points[i];
|
|
|
|
+ if (point.x >= x1 && point.y >= y1) {
|
|
|
|
+ if (point.x <= x2 && point.y <= y2) {
|
|
|
|
+ counter += point.value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return counter;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function totalClicks () {
|
|
|
|
+ return stateObject['data'].length;
|
|
|
|
+}
|
|
|
|
+
|
|
function logTransform (logString) {
|
|
function logTransform (logString) {
|
|
const data = logString.split("\n")
|
|
const data = logString.split("\n")
|
|
.filter(v => v.split(',').length > 3)
|
|
.filter(v => v.split(',').length > 3)
|
|
@@ -72,7 +133,109 @@ function logTransform (logString) {
|
|
return data;
|
|
return data;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+function registerClickEvent () {
|
|
|
|
+ const elemen = document.querySelector(".heatmap-canvas");
|
|
|
|
+ window.onclick = function (evt) {
|
|
|
|
+ if(evt.target !== elemen) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (firstClick) {
|
|
|
|
+ if (evt.pageX || evt.pageY) {
|
|
|
|
+ x1 = evt.pageX;
|
|
|
|
+ y1 = evt.pageY;
|
|
|
|
+ } else {
|
|
|
|
+ x1 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
|
|
|
|
+ y1 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
|
|
|
|
+ }
|
|
|
|
+ x1 -= elemen.offsetLeft;
|
|
|
|
+ y1 -= elemen.offsetTop;
|
|
|
|
+ firstClick = false;
|
|
|
|
+ } else {
|
|
|
|
+ if (evt.pageX || evt.pageY) {
|
|
|
|
+ x2 = evt.pageX;
|
|
|
|
+ y2 = evt.pageY;
|
|
|
|
+ } else {
|
|
|
|
+ x2 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
|
|
|
|
+ y2 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
|
|
|
|
+ }
|
|
|
|
+ x2 -= elemen.offsetLeft;
|
|
|
|
+ y2 -= elemen.offsetTop;
|
|
|
|
+
|
|
|
|
+ firstClick = true;
|
|
|
|
+ if (div !== null) {
|
|
|
|
+ document.getElementById("line-heatmap-canvas").removeChild(div);
|
|
|
|
+ div = null;
|
|
|
|
+ }
|
|
|
|
+ div = document.createElement("div");
|
|
|
|
+ posLeft = Math.min(x1,x2);
|
|
|
|
+ posTop = Math.min(y1,y2) - 585;
|
|
|
|
+ yBottom = Math.max(y1,y2) - 585;
|
|
|
|
+ xBottom = Math.max(x1,x2);
|
|
|
|
+ const width = Math.abs(xBottom - posLeft);
|
|
|
|
+ const height = Math.abs(yBottom - posTop);
|
|
|
|
+ updateDivText(div, posLeft, posTop, xBottom, yBottom);
|
|
|
|
+ div.style.width = width + "px";
|
|
|
|
+ div.style.height = height + "px";
|
|
|
|
+ div.style.position = "absolute";
|
|
|
|
+ div.style.top = posTop + "px";
|
|
|
|
+ div.style.left = posLeft + "px";
|
|
|
|
+ div.style.border = "1px solid green";
|
|
|
|
+ document.getElementById("line-heatmap-canvas").append(div);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function updateDivText (div, posLeft, posTop, xBottom, yBottom) {
|
|
|
|
+ const count = countClicks(posLeft, posTop, xBottom, yBottom);
|
|
|
|
+ const ratio = count/totalClicks();
|
|
|
|
+ div.innerHTML = `<span style="font-size:14px">Quantidade de clicks: ${count}</span>
|
|
|
|
+ <span style="font-size:14px">Proporção em relação ao total: ${ratio}</span>`;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
init,
|
|
init,
|
|
- updateLogString
|
|
|
|
-}
|
|
|
|
|
|
+ updateLogString,
|
|
|
|
+ countClicks,
|
|
|
|
+ totalClicks
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ var x1, y1, x2, y2;
|
|
|
|
+var sequencia = 1;
|
|
|
|
+
|
|
|
|
+window.onclick = function(evt) {
|
|
|
|
+ var elemen = document.querySelector(".heatmap-canvas");
|
|
|
|
+ if (sequencia == 1) {
|
|
|
|
+ if (evt.pageX || evt.pageY) {
|
|
|
|
+ x1 = evt.pageX;
|
|
|
|
+ y1 = evt.pageY;
|
|
|
|
+ } else {
|
|
|
|
+ x1 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
|
|
|
|
+ y1 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
|
|
|
|
+ }
|
|
|
|
+ x1 -= elemen.offsetLeft;
|
|
|
|
+ y1 -= elemen.offsetTop;
|
|
|
|
+ sequencia ++;
|
|
|
|
+ } else {
|
|
|
|
+ if (evt.pageX || evt.pageY) {
|
|
|
|
+ x2 = evt.pageX;
|
|
|
|
+ y2 = evt.pageY;
|
|
|
|
+ } else {
|
|
|
|
+ x2 = evt.clientX + document.body.scrollLeft + elemen.scrollLeft;
|
|
|
|
+ y2 = evt.clientY + document.body.scrollTop + elemen.scrollTop;
|
|
|
|
+ }
|
|
|
|
+ x2 -= elemen.offsetLeft;
|
|
|
|
+ y2 -= elemen.offsetTop;
|
|
|
|
+
|
|
|
|
+ var width = Math.abs(x2 - x1);
|
|
|
|
+ var height = Math.abs(y2 - y1);
|
|
|
|
+ sequencia = 1;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ $('#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>'));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+ */
|