heatmap-rails 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 568b92121f25bb606764d5c28b365142210db651
4
- data.tar.gz: 4bba25dc14b8727dd7080691467c56c1c64f8d68
3
+ metadata.gz: 87094bab47af8ff7d11ffa1ad7859bfd676663f0
4
+ data.tar.gz: b29655825150001bb58b16a34730967a674d113f
5
5
  SHA512:
6
- metadata.gz: b9dfe95586c7eb8f2f22487586e25ece9506c8ae384f6b36ebbeef1bf541f225602f045b5fd1065913346d186fe18d8eb15fb590aee70a13a975d8ada57825ce
7
- data.tar.gz: 25a45b31e1530430f91083afa58c577700501df9045886b42edd59cee98f01085f9ecdf877b860c6bd8f11c88af22dfa394688dfcc0e044adcd3afc76f79f3ac
6
+ metadata.gz: b73c339204943ab57d3581404621c0e40df06b887756845f74e12918753d3b6e431a06ab5cd81d2e3916abf5dc39ff045e1029bb805901842562ee98926ed220
7
+ data.tar.gz: d1d14d96f0a6168e02df4389680407713dc8921c642056cef95d239dd2bac112e50391963714785ea62c39da972fbd0a2da49f8bf675c6f22694e5b21e3e704a
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- heatmap-rails (0.1.0)
4
+ heatmap-rails (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,16 +1,11 @@
1
- # HeatmapRb :construction:
1
+ [![Gem Version](https://badge.fury.io/rb/heatmap-rails.svg)](https://badge.fury.io/rb/heatmap-rails)
2
+
3
+ # Heatmap-Rails
2
4
 
3
5
  Integrate heatmaps in your web application to see on which part the user spends most time on your web application. Where does users click on the page.
4
6
  Helping in gathering analytics to find out what works on the web, what attracts most of the users.
5
7
  View user interactions and make your application more amazing! :sparkles:
6
-
7
- ## Local Testing
8
-
9
- Use
10
-
11
- ```ruby
12
- gem 'heatmap-rails', git: 'https://github.com/Qbatch/heatmap-rails.git'
13
- ```
8
+ [Demo](https://heatmap-rails.herokuapp.com/)
14
9
 
15
10
  ## Installation
16
11
 
@@ -31,7 +26,8 @@ Or install it yourself as:
31
26
  ## Usage
32
27
 
33
28
  1. Install the gem
34
- 2. Run the command to generate migration:
29
+
30
+ 2. Run the command to generate a migration to save heatmaps data:
35
31
  ```console
36
32
  $ rails g heatmap_rails:install
37
33
  ```
@@ -50,8 +46,13 @@ $ rake db:migrate
50
46
  ```erb
51
47
  <%= show_heatmap(request.path) %>
52
48
  ```
49
+ 6. Before adding headmap.js in the application install **jquery-rails** gem and require it in application.js file
50
+ ```js
51
+ //= require jquery
52
+ ```
53
+
53
54
 
54
- 6. In respective JS file, Require HeatMap.Js to show the heatmap:
55
+ 7. In respective JS file, Require HeatMap.Js to show the heatmap:
55
56
  ```js
56
57
  //= require heatmap.js
57
58
  ```
@@ -69,43 +70,47 @@ The viewing can be done in multiple ways, for example if you want only the admin
69
70
  <% end %>
70
71
  ```
71
72
 
72
- Another way can be using some code in URL. For example is you want to use URL like
73
+ Another way can be using some param in the URL. For example if you want to use URL like:
73
74
 
74
75
  ```url
75
- www.website.com/see_heatmap
76
+ www.website.com/?see_heatmap
76
77
  ```
77
78
 
78
79
  You can use:
79
80
 
80
81
  ```erb
81
- <% if request.path.include?("see_heatmap") %>
82
+ <% if request.query_parameters.include?("see_heatmap") %>
82
83
  <%= show_heatmap(request.path) %>
83
84
  <% end %>
84
85
  ```
85
86
 
86
- And there can be multiple ways!
87
87
  ### Options
88
88
 
89
- You can customize:
89
+ You can customize the max stack limits before the data is sent to server side via http request. We understand for different application the average user interactions time on a specific page varies. You can set these values w.r.t to your application's needs:
90
90
  ```erb
91
91
  <%= save_heatmap({click: 3, move: 50}) %>
92
92
  ```
93
- These are default values.
93
+ The default values for clicks is `3`. For mouse movements tracking its `50`.
94
+
95
+ ```erb
96
+ <%= save_heatmap({click: 3, move: 50, html_element: 'body'}) %>
97
+ ```
98
+ you can even restrict heatmap generation to a specific DOM element. Default value for DOM element is `body` element. This can be change to any `.class` or any '#id'.
94
99
 
95
- ## Development :construction:
100
+ ## Development
96
101
 
97
102
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
98
103
 
99
104
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
100
105
 
101
106
  ## Credits
102
- heatmap-rails uses [HeatMap.Js](https://www.patrick-wied.at/static/heatmapjs/) to generated show heatmaps.
107
+ heatmap-rails uses [HeatMap.Js](https://www.patrick-wied.at/static/heatmapjs/) to show generated data in form of heatmaps.
103
108
 
104
109
  ## Contributing :construction:
105
110
 
106
111
  1. [Bug reports](https://github.com/Qbatch/heatmap-rails/issues) are always welcome.
107
112
  2. [Pull Requests](https://github.com/Qbatch/heatmap-rails/pulls). Suggest or Update.
108
113
 
109
- ## License :construction:
114
+ ## License
110
115
 
111
116
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,6 +1,2 @@
1
1
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
2
  task :default => :spec
@@ -3,14 +3,14 @@ class PointsController < ApplicationController
3
3
  skip_before_action :verify_authenticity_token
4
4
 
5
5
  def create
6
- if params[:data].present?
7
- for i in 0..Heatmap::Rails.options[:click]-1
8
- HeatMap.create(path: params[:data]["#{i}"][:path], click_type: 'click',xpath: params[:data]["#{i}"][:xpath])
6
+ if params[:click_data].present? && params[:total_clicks].to_i > 0
7
+ for i in 0..params[:total_clicks].to_i-1
8
+ HeatMap.create(path: params[:click_data]["#{i}"][:path], click_type: 'click',xpath: params[:click_data]["#{i}"][:xpath], offset_x: params[:click_data]["#{i}"][:offset_x], offset_y: params[:click_data]["#{i}"][:offset_y])
9
9
  end
10
10
  end
11
- if params[:move_data].present?
12
- for i in 0..Heatmap::Rails.options[:move]-1
13
- HeatMap.create(path: params[:move_data]["#{i}"][:path], click_type: 'click',xpath: params[:move_data]["#{i}"][:xpath])
11
+ if params[:move_data].present? && params[:total_moves].to_i > 0
12
+ for i in 0..params[:total_moves].to_i-1
13
+ HeatMap.create(path: params[:move_data]["#{i}"][:path], click_type: 'move',xpath: params[:move_data]["#{i}"][:xpath], offset_x: params[:move_data]["#{i}"][:offset_x], offset_y: params[:move_data]["#{i}"][:offset_y])
14
14
  end
15
15
  end
16
16
  end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "heatmap-rails"
4
+ require "heatmap/rails"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -1,11 +1,11 @@
1
1
 
2
2
  lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "heatmap/version"
4
+ require "heatmap/rails/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "heatmap-rails"
8
- spec.version = Heatmap::VERSION
8
+ spec.version = Heatmap::Rails::VERSION
9
9
  spec.authors = ["Hassan"]
10
10
  spec.email = ["hassan@qbatch.com"]
11
11
 
@@ -3,6 +3,8 @@ class CreateHeatMaps < ActiveRecord::Migration[5.1]
3
3
  create_table :heat_maps do |t|
4
4
  t.string :path
5
5
  t.string :click_type
6
+ t.float :offset_x
7
+ t.float :offset_y
6
8
  t.text :xpath
7
9
 
8
10
  t.timestamps
@@ -0,0 +1,12 @@
1
+ require "heatmap/rails/version"
2
+ require "heatmap/rails/engine"
3
+ require "heatmap/rails/helper"
4
+
5
+ module Heatmap
6
+ module Rails
7
+ class << self
8
+ attr_accessor :options
9
+ end
10
+ self.options = {click: 3, move: 10, html_element: 'body'}
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module Heatmap
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ initializer "helper" do
5
+ ActiveSupport.on_load(:action_view) do
6
+ include Helper
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -7,17 +7,21 @@ module Heatmap
7
7
 
8
8
  click = options[:click] || Heatmap::Rails.options[:click]
9
9
  move = options[:move] || Heatmap::Rails.options[:move]
10
-
10
+ html_element = options[:html_element] || Heatmap::Rails.options[:html_element]
11
11
  html = ""
12
12
 
13
13
  js = <<JS
14
14
  <script type="text/javascript">
15
15
  $( document ).ready(function() {
16
16
  var move_array = [];
17
- document.querySelector('body').onmousemove = function(ev) {
17
+ document.querySelector('#{html_element}').onmousemove = function(ev) {
18
18
  var xpath_element = xpathstring(ev);
19
- var pageCoords = { path: window.location.pathname, type: 'move', xpath: xpath_element };
20
- console.log(xpath_element);
19
+ var element_width = ev.target.getBoundingClientRect().width;
20
+ var element_height= ev.target.getBoundingClientRect().height;
21
+ offset_x_element = ev.offsetX / element_width;
22
+ offset_y_element = ev.offsetY / element_height;
23
+ var pageCoords = { path: window.location.pathname, type: 'move', xpath: xpath_element, offset_x: offset_x_element , offset_y: offset_y_element, };
24
+
21
25
  var obj = move_array.find(function (obj) { return obj.xpath === xpath_element; });
22
26
  if (obj == null){
23
27
  move_array.push(pageCoords);
@@ -25,21 +29,28 @@ $( document ).ready(function() {
25
29
  if (move_array.length >= parseInt(#{move}))
26
30
  {
27
31
  var coordinates = move_array;
28
- sendRequest({'move_data': coordinates});
32
+ sendRequest({'move_data': coordinates,'total_moves': #{move} });
29
33
  move_array = [];
30
34
  }
35
+
36
+
31
37
  };
32
38
  var click_array = [];
33
- document.querySelector('body').onclick = function(ev) {
39
+ document.querySelector('#{html_element}').onclick = function(ev) {
34
40
 
35
41
  var xpath_element= xpathstring(ev);
36
- var pageCoords = { path: window.location.pathname, type: 'click', xpath: xpath_element };
42
+ var element_width = ev.target.getBoundingClientRect().width;
43
+ var element_height= ev.target.getBoundingClientRect().height;
44
+ offset_x_element = ev.offsetX / element_width;
45
+ offset_y_element = ev.offsetY / element_height;
46
+ var pageCoords = { path: window.location.pathname, type: 'click', xpath: xpath_element, offset_x: offset_x_element , offset_y: offset_y_element, };
37
47
  click_array.push(pageCoords);
38
48
  if (click_array.length >= parseInt(#{click}))
39
49
  {
40
50
  var coordinates = click_array;
41
- sendRequest({'data': coordinates});
51
+ sendRequest({'click_data': coordinates, 'total_clicks': #{click} });
42
52
  click_array = [];
53
+
43
54
  }
44
55
  };
45
56
  function sendRequest(coordinates_data){
@@ -113,7 +124,7 @@ JS
113
124
  @data_points = []
114
125
  @data_xpaths = []
115
126
  heatmap.each do |coordinate|
116
- @data_xpaths.push({xpath: coordinate.xpath, x: 0, y:0, value: 100})
127
+ @data_xpaths.push({xpath: coordinate.xpath, offset_x: coordinate.offset_x, offset_y:coordinate.offset_y, value: 100})
117
128
  end
118
129
  html = ""
119
130
  js = <<JS
@@ -122,13 +133,31 @@ JS
122
133
  container: document.querySelector('body'),
123
134
  radius: 40
124
135
  });
136
+ function getOffset( path ) {
137
+ el = document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
138
+ var _x = 0;
139
+ var _y = 0;
140
+ while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
141
+ _x += el.offsetLeft - el.scrollLeft;
142
+ _y += el.offsetTop - el.scrollTop;
143
+ el = el.offsetParent;
144
+ }
145
+ return { y: _y, x: _x };
146
+ }
147
+ function getElement(xpath){
148
+ return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
149
+ }
125
150
  var xpath = JSON.parse('#{raw(@data_xpaths.to_json.html_safe)}');
126
151
  var data_xpath = xpath.map(function(path){
127
- var x_coord = getOffset(path.xpath).x+25;
128
- var y_coord = getOffset(path.xpath).y+25;
152
+ width = getElement(path.xpath).getBoundingClientRect().width;
153
+ height = getElement(path.xpath).getBoundingClientRect().height;
154
+ var x_coord = getOffset(path.xpath).x+ (width * path.offset_x);
155
+ var y_coord = getOffset(path.xpath).y+ (height * path.offset_y);
129
156
  delete path["xpath"];
130
- path.x = parseInt(x_coord);
131
- path.y = parseInt(y_coord);
157
+ delete path["offset_x"];
158
+ delete path["offset_y"];
159
+ path.x = Math.ceil(parseFloat(x_coord));
160
+ path.y = Math.ceil(parseFloat(y_coord));
132
161
  return path;
133
162
  });
134
163
  heatmapInstance.addData(data_xpath);
@@ -0,0 +1,5 @@
1
+ module Heatmap
2
+ module Rails
3
+ VERSION = "0.1.2"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'heatmap/rails/helper'
3
+
4
+ RSpec.describe Heatmap do
5
+ it "has a version number" do
6
+ expect(Heatmap::Rails::VERSION).not_to be nil
7
+ end
8
+ end
9
+
10
+ RSpec.describe Heatmap::Helper do
11
+ def run_save_heatmap
12
+ Heatmap::Helper.save_heatmap({move: 10, click: 2, html_element: '#test'})
13
+ end
14
+ let(:processed_message) { run_save_heatmap() }
15
+ end
@@ -1,5 +1,5 @@
1
1
  require "bundler/setup"
2
- require "heatmap-rails"
2
+ require "heatmap/rails/helper"
3
3
 
4
4
  RSpec.configure do |config|
5
5
  # Enable flags like --only-failures and --next-failure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heatmap-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hassan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-06 00:00:00.000000000 Z
11
+ date: 2017-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,11 +76,11 @@ files:
76
76
  - heatmap-rails.gemspec
77
77
  - lib/generators/heatmap_rails/install_generator.rb
78
78
  - lib/generators/heatmap_rails/templates/initializer.rb
79
- - lib/heatmap-rails.rb
80
- - lib/heatmap/engine.rb
81
- - lib/heatmap/helper.rb
82
- - lib/heatmap/version.rb
83
- - spec/heatmap_rb_spec.rb
79
+ - lib/heatmap/rails.rb
80
+ - lib/heatmap/rails/engine.rb
81
+ - lib/heatmap/rails/helper.rb
82
+ - lib/heatmap/rails/version.rb
83
+ - spec/heatmap_rails_spec.rb
84
84
  - spec/spec_helper.rb
85
85
  homepage: https://github.com/Qbatch/heatmap-rails
86
86
  licenses:
@@ -1,12 +0,0 @@
1
- require "heatmap/version"
2
- require "heatmap/engine"
3
- require "heatmap/helper"
4
-
5
- module Heatmap
6
- module Rails
7
- class << self
8
- attr_accessor :options
9
- end
10
- self.options = {click: 3, move: 10}
11
- end
12
- end
@@ -1,9 +0,0 @@
1
- module Heatmap
2
- class Engine < Rails::Engine
3
- initializer "helper" do
4
- ActiveSupport.on_load(:action_view) do
5
- include Helper
6
- end
7
- end
8
- end
9
- end
@@ -1,3 +0,0 @@
1
- module Heatmap
2
- VERSION = "0.1.1"
3
- end
@@ -1,9 +0,0 @@
1
- RSpec.describe HeatmapRb do
2
- it "has a version number" do
3
- expect(HeatmapRb::VERSION).not_to be nil
4
- end
5
-
6
- it "does something useful" do
7
- expect(false).to eq(true)
8
- end
9
- end