Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

HeatMap integration

  • david2013
  • david2013's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
9 years 4 months ago #122752 by david2013
HeatMap integration was created by david2013
Did anyone successfully integrate any heatmap tool (ie. heatmap.js, clickheat) into LimeSurvey without using iframe? Heatmap.js looks very cool. I want to display an image and allow people to click on it. Then save the coordiantes into open end question. Once project is done, I can load all the coordiantes into the image to generate the heatmap.

Does anyone done it before? Any help is appreciated
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
9 years 4 months ago #122790 by tpartner
Replied by tpartner on topic HeatMap integration
The heatmap isn't something you would do within LimeSurvey but to capture the coordinates of a click on an image (presumably in relative percentages), you could place something like this in the source of a short-text question. When the image is clicked, the script places a marker at that position and loads the coordinates (comma separated) into the text input. The text input can be hidden by uncommenting line 8 of the script.

Code:
Question 1:<br /><br />
<div class="image-wrapper" style="border:2px solid #999; width: 600px;">
  <img src="https://www.google.com/logos/doodles/2015/fifa-womens-world-cup-2015-finals-5184884003831808-hp2x.jpg" style="border:0 none; width: 100%; height: auto;" />
</div>
<script type="text/javascript" charset="utf-8">    
  $(document).ready(function() {  
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Hide the text input - uncomment below
    //$('input.text', thisQuestion).hide();
 
    // Create the click "marker"
    $('.image-wrapper', thisQuestion).append('<div class="click-marker" />');
    var leftVal = 0;
    var topVal = 0;
    var displayVal = 'none';
    if($.trim($('input.text', thisQuestion).val()) != '') {
      leftVal = $.trim($('input.text', thisQuestion).val()).split(',')[0]+'%';
      topVal = $.trim($('input.text', thisQuestion).val()).split(',')[1]+'%'; 
      displayVal = 'block';
    }
    $('.click-marker', thisQuestion).css({
      'display': displayVal,
      'position': 'absolute',
      'left': leftVal,
      'top': topVal,
      'margin': '-10px 0 0 -10px',
      'width': '18px',
      'height': '18px',
      '-moz-border-radius': '10px',
      '-webkit-border-radius': '10px',
      'border-radius': '10px',
      'background': '#0C0',
      'border': '1px solid #090'
    });
 
    // Insert an overlay to click on
    $('.image-wrapper', thisQuestion).css('position', 'relative').append('<div class="click-overlay" />');
    $('.click-overlay', thisQuestion).css({
      'position': 'absolute',
      'left': 0,
      'top': 0,
      'margin': 0,
      'width': $('.image-wrapper', thisQuestion).width()+'px',
      'height': $('.image-wrapper', thisQuestion).height()+'px'
    });
 
    // Click event on the overlay
    $('.click-overlay', thisQuestion).click(function(e) {
      var thisWidth = $(this).width();
      var thisHeight = $(this).height();
      var posX = $(this).offset().left;
      var posY = $(this).offset().top;
      var xCoord = e.pageX - posX;
      var yCoord = e.pageY - posY;
      var xCoordPercent = (xCoord/thisWidth)*100;
      var yCoordPercent = (yCoord/thisHeight)*100;
 
      // Load the click coordinates (as relative percentages)
      $('input.text', thisQuestion).val(xCoordPercent.toFixed(2)+','+yCoordPercent.toFixed(2));
 
      // Reposition the marker
      $('.click-marker', thisQuestion).css({
        'display': 'block',
        'left': xCoordPercent+'%',
        'top': yCoordPercent+'%'
      });
    });
 
  });
</script>

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: david2013, julius_meier
The topic has been locked.
  • david2013
  • david2013's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
9 years 4 months ago #122904 by david2013
Replied by david2013 on topic HeatMap integration
Thank you very much for your help. Just curious, why convert xCoord and yCoord into percentages (xCoordPercent and yCoordPercent)? What's the advantage?
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
9 years 4 months ago #122906 by tpartner
Replied by tpartner on topic HeatMap integration
There's no advantage in the data, I just assumed you would need relative coordinates for the heat map.

They are, however, needed to position the marker in case of resizing.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
More
5 years 1 week ago #191396 by gremlin
Replied by gremlin on topic HeatMap integration
Hi tpartner!

I just tried this on V3.18. While the overlay is working but the text input doesn't seem to show the coordinates. No data is stored. Is an update to the script required for V3.18?

Also, is there a way to make the image and overlay mobile responsive? The image exceeds the width on a mobile device screen.

Thanks!
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 1 week ago #191414 by tpartner
Replied by tpartner on topic HeatMap integration
I'm not sure what the thinking behind the overlay was but this will work in 3.x and is responsive. It also handles returning to the page.

Code:
Question 1:<br /><br />
<div class="image-wrapper" style="border:2px solid #999; width: 100%; max-width: 600px; position:relative">
  <img src="https://www.google.com/logos/doodles/2015/fifa-womens-world-cup-2015-finals-5184884003831808-hp2x.jpg" style="border:0 none; width: 100%; height: auto;" />
</div>
<script type="text/javascript" charset="utf-8">    
  $(document).ready(function() {  
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Hide the text input - un-comment below
    //$('input.text', thisQuestion).hide();
 
    // Create the click "marker"
    $('.image-wrapper', thisQuestion).append('<div class="click-marker" />');
    var leftVal = 0;
    var topVal = 0;
    var displayVal = 'none';
    if($.trim($('input.text', thisQuestion).val()) != '') {
      leftVal = $.trim($('input.text', thisQuestion).val()).split(',')[0]+'%';
      topVal = $.trim($('input.text', thisQuestion).val()).split(',')[1]+'%'; 
      displayVal = 'block';
    }
    $('.click-marker', thisQuestion).css({
      'display': displayVal,
      'position': 'absolute',
      'left': leftVal,
      'top': topVal,
      'margin': '-10px 0 0 -10px',
      'width': '18px',
      'height': '18px',
      '-moz-border-radius': '10px',
      '-webkit-border-radius': '10px',
      'border-radius': '10px',
      'background': '#0C0',
      'border': '1px solid #090'
    });
 
    // Click event on the image
    $('.image-wrapper, img', thisQuestion).on('click', function(e) {
      var thisWidth = $(this).width();
      var thisHeight = $(this).height();
      var posX = $(this).offset().left;
      var posY = $(this).offset().top;
      var xCoord = e.pageX - posX;
      var yCoord = e.pageY - posY;
      var xCoordPercent = (xCoord/thisWidth)*100;
      var yCoordPercent = (yCoord/thisHeight)*100;
 
      // Load the click coordinates (as relative percentages)
      $('input:text', thisQuestion).val(xCoordPercent.toFixed(2)+','+yCoordPercent.toFixed(2));
 
      // Reposition the marker
      $('.click-marker', thisQuestion).css({
        'display': 'block',
        'left': xCoordPercent+'%',
        'top': yCoordPercent+'%'
      });
    });
 
    // Returning to the page
    if($('input:text', thisQuestion).val() != '') {
      var coords = $.trim($('input:text', thisQuestion).val()).split(',');
      $('.click-marker', thisQuestion).css({
        'display': 'block',
        'left': coords[0]+'%',
        'top': coords[1]+'%'
      });
    }
  });
</script>



Sample survey attached:

File Attachment:

File Name: limesurvey...1-22.lss
File Size:18 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: julius_meier
The topic has been locked.
More
4 years 6 months ago #200593 by julius_meier
Replied by julius_meier on topic HeatMap integration
Hi tpartner!

Thanks, the code works great and this function is exactly what I was looking for. However, the text-input is not hidden, although I have un-commented the corresponding line as described by you. Do you happen to have an idea what I am doing wrong?
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
4 years 6 months ago - 4 years 6 months ago #200601 by tpartner
Replied by tpartner on topic HeatMap integration
Change:
Code:
$('input.text', thisQuestion).hide();

To:
Code:
$('input:text', thisQuestion).hide();

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 4 years 6 months ago by tpartner.
The following user(s) said Thank You: julius_meier
The topic has been locked.
More
4 years 6 months ago #200602 by julius_meier
Replied by julius_meier on topic HeatMap integration
It works, thank you so much!
The topic has been locked.
Moderators: tpartnerholch

Lime-years ahead

Online-surveys for every purse and purpose