module Heatmap::Helper
Public Instance Methods
exact_route()
click to toggle source
# File lib/heatmap/rails/helper.rb, line 6 def exact_route "#{params[:controller]}/#{params[:action]}" end
save_heatmap(options = {})
click to toggle source
# File lib/heatmap/rails/helper.rb, line 10 def save_heatmap(options = {}) click = options[:click] || Heatmap::Rails.options[:click] move = options[:move] || Heatmap::Rails.options[:move] scroll = options[:scroll] || Heatmap::Rails.options[:scroll] html_element = options[:html_element] || Heatmap::Rails.options[:html_element] html = "" js = <<JS <script type="text/javascript"> $( document ).ready(function() { var move_array = []; var scroll_array = []; (function() { document.onwheel = handleWheelMove; function handleWheelMove(event) { var dot, eventDoc, doc, body, offsetX, offsetY; event = event || window.event; if (event.offsetX == null && event.clientX != null) { eventDoc = (event.target && event.target.ownerDocument) || document; doc = eventDoc.documentElement; body = eventDoc.body; event.offsetX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.offsetY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0 ); } var xpath_element = xpathstring(event); var element_width = event.target.getBoundingClientRect().width; var element_height= event.target.getBoundingClientRect().height; offset_x_element = event.offsetX / element_width; offset_y_element = event.offsetY / element_height; var pageCoords = { path: "#{exact_route}", type: 'scroll', xpath: xpath_element, offset_x: offset_x_element , offset_y: offset_y_element, }; scroll_array.push(pageCoords); if (scroll_array.length >= parseInt(#{scroll})) { var coordinates = scroll_array; sendRequest({'scroll_data': coordinates, 'total_scrolls': #{scroll} }); scroll_array = []; } } })(); document.querySelector('#{html_element}').onmousemove = function(ev) { var xpath_element = xpathstring(ev); var element_width = ev.target.getBoundingClientRect().width; var element_height= ev.target.getBoundingClientRect().height; offset_x_element = ev.offsetX / element_width; offset_y_element = ev.offsetY / element_height; var pageCoords = { path: "#{exact_route}", type: 'move', xpath: xpath_element, offset_x: offset_x_element , offset_y: offset_y_element, }; var obj = move_array.find(function (obj) { return obj.xpath === xpath_element; }); if (obj == null){ move_array.push(pageCoords); } if (move_array.length >= parseInt(#{move})) { var coordinates = move_array; sendRequest({'move_data': coordinates,'total_moves': #{move} }); move_array = []; } }; var click_array = []; document.querySelector('#{html_element}').onclick = function(ev) { var xpath_element= xpathstring(ev); var element_width = ev.target.getBoundingClientRect().width; var element_height= ev.target.getBoundingClientRect().height; offset_x_element = ev.offsetX / element_width; offset_y_element = ev.offsetY / element_height; var pageCoords = { path: "#{exact_route}", type: 'click', xpath: xpath_element, offset_x: offset_x_element , offset_y: offset_y_element, }; click_array.push(pageCoords); if (click_array.length >= parseInt(#{click})) { var coordinates = click_array; sendRequest({'click_data': coordinates, 'total_clicks': #{click} }); click_array = []; } }; function sendRequest(coordinates_data){ $.ajax({ method: "POST", url: '/points', data: coordinates_data, dataType: 'application/json' }); } }); function xpathstring(event) { var e = event.srcElement || event.originalTarget, path = xpath(e, ''); return path } function xpath(element, suffix) { var parent, child_index, node_name; parent = element.parentElement; if (parent) { node_name = element.nodeName.toLowerCase(); child_index = nodeindex(element, parent.children) + 1; return xpath(parent, '/' + node_name + '[' + child_index + ']' + suffix); } else { return '//html[1]' + suffix; } } function nodeindex(element, array) { var i, found = -1, element_name = element.nodeName.toLowerCase(), matched ; for (i = 0; i != array.length; ++i) { matched = array[i]; if (matched.nodeName.toLowerCase() === element_name) { ++found; if (matched === element) { return found; } } } return -1; } function getOffset( path ) { el = document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; var _x = 0; var _y = 0; while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) { _x += el.offsetLeft - el.scrollLeft; _y += el.offsetTop - el.scrollTop; el = el.offsetParent; } return { y: _y, x: _x }; } </script> JS html += js html.respond_to?(:html_safe) ? html.html_safe : html end
show_heatmap(type = false)
click to toggle source
# File lib/heatmap/rails/helper.rb, line 159 def show_heatmap(type = false) if type heatmap = HeatMap.where(path: exact_route.to_s , click_type: type) heatmap_count = HeatMap.where(path: exact_route.to_s , click_type: type).count type = type + 's' else heatmap = HeatMap.where(path: exact_route.to_s) heatmap_count = HeatMap.where(path: exact_route.to_s).count type = 'heatmaps' end @data_points = [] @data_xpaths = [] @scroll_data = [] heatmap.each do |coordinate| if (coordinate.click_type == "scroll") @scroll_data.push({xpath: coordinate.xpath, offset_x: coordinate.offset_x, offset_y:coordinate.offset_y}) else @data_xpaths.push({xpath: coordinate.xpath, offset_x: coordinate.offset_x, offset_y:coordinate.offset_y, value: 100}) end end html = "" js = <<JS <script type="text/javascript"> var heatmapInstance = h337.create({ container: document.querySelector('body'), radius: 40 }); window.onload = function() { var parent_div = document.createElement("div"); var text_div = document.createElement("span"); parent_div.style.padding= "14px"; parent_div.style.position = "absolute"; parent_div.style.top = "0"; parent_div.style.right = "0"; parent_div.style.background ="rgba(0, 0, 0, 0.7)"; parent_div.style.color ="white"; parent_div.style.textAlign ="center"; var text_node = document.createTextNode("#{type.capitalize} Recorded"); text_div.appendChild(text_node); parent_div.appendChild(text_div); var numeric_div = document.createElement("h1"); var numeric_node = document.createTextNode("#{heatmap_count}"); numeric_div.appendChild(numeric_node); parent_div.appendChild(numeric_div); document.body.appendChild(parent_div); } function getOffset( path ) { el = document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; var _x = 0; var _y = 0; while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) { _x += el.offsetLeft - el.scrollLeft; _y += el.offsetTop - el.scrollTop; el = el.offsetParent; } return { y: _y, x: _x }; } function getElement(xpath){ return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } var xpath_current = JSON.parse('#{raw(@data_xpaths.to_json.html_safe)}'); var data_xpath = xpath_current.map(function(path){ if (path != null) { element = getElement(path.xpath); if (element != null){ width = element.getBoundingClientRect().width; height = element.getBoundingClientRect().height; var x_coord = getOffset(path.xpath).x+ (width * path.offset_x); var y_coord = getOffset(path.xpath).y+ (height * path.offset_y); delete path["xpath_current"]; delete path["offset_x"]; delete path["offset_y"]; path.x = Math.ceil(parseFloat(x_coord)); path.y = Math.ceil(parseFloat(y_coord)); return path; } } }); // Removed: Null Xpath(s) var data_xpath = data_xpath.filter(function(val){ return val!==undefined; }); heatmapInstance.addData(data_xpath); var scroll = JSON.parse('#{raw(@scroll_data.to_json.html_safe)}'); var scroll_data = scroll.map(function(element){ width = getElement(element.xpath).getBoundingClientRect().width; height = getElement(element.xpath).getBoundingClientRect().height; dot = document.createElement('div'); dot.className = "dot"; dot.style.left = (getOffset(element.xpath).x+ (width * element.offset_x)) + "px"; dot.style.top = (getOffset(element.xpath).y+ (height * element.offset_y) )+ "px"; delete element["xpath"]; delete element["offset_x"]; delete element["offset_y"]; dot.style.backgroundColor ="white"; dot.style.position ="absolute"; dot.style.borderWidth ="8px"; dot.style.borderStyle ="solid"; var colors = Array('#ee3e32', '#f68838' ,'#fbb021', '#1b8a5a','#1d4877'); var color = colors[Math.floor(Math.random()*colors.length)]; dot.style.borderColor = color; dot.style.borderRadius ="50%"; dot.style.opacity ="0.7"; var arrow_node = document.createTextNode("\u21C5"); dot.appendChild(arrow_node); document.body.appendChild(dot); }); scroll_data = scroll_data.filter(function(val){ return val!==undefined; }); </script> JS html += js html.respond_to?(:html_safe) ? html.html_safe : html end