Google Analytics: Suggestion

Q&A about the latest versions
Post Reply
sparrow
Posts: 67
Joined: Thu Aug 04, 2016 12:44 pm

Would be great to have a field into which I can add my Google Analytics tracking ID.

Then, when I hit the "generate output" button (cog icon), the index created in the Output folder would already have GA embedded.
User avatar
Hopki
Gnome
Posts: 13004
Joined: Thu Jan 10, 2008 3:16 pm
Location: Layer de la Haye, Essex UK
Contact:

Hi sparrow,
What you can do is add the your Analytics code to a copy of the normal.ggt.
1) Open Pano2VR and select settings/preferences
2) Select the Files tab and right button click on the HTML Template Directory
3) Open HtmlTemplates, html5 folders
4) Copy the normal.ggt and label it normal_analyics.ggt, or whatever you want to call it
5) Open the .ggt with a plan text editor such as note pad, then add your code in the template.
6) Save and close the .ggt, now back in Pano2VR you can select this template which will have your code.
Regards,
Hopki
Garden Gnome Support
If you send an e-mail to support please send a link to the forum post for reference.
support@ggnome.com
https://ggnome.com/wiki/documentation/
sparrow
Posts: 67
Joined: Thu Aug 04, 2016 12:44 pm

Cheers Hopki

That's a very straightforward idea. Hadn't thought of directly editing the html template for some reason.

I think it would be good to explore the ability though to add Analytics code directly into the UI. For example, if I have 50 clients, I don't want to create 50 templates each for the sake of separate GA code.

If I could build an array of GA codes and give them a name (client A, client B) etc then I could use a drop down in the GUI to select the appropriate one. That variable would then be assigned to the template file and keep the markup and presentation separate.

Happy to wireframe up what I was thinking if it helps?
Jamesladdr360
Posts: 2
Joined: Tue Oct 18, 2016 12:55 pm

Hi Guys,

I agree that analytics would be a very useful addition to tours, It is certainly something that customers have asked me for. Please bear in mind that I came to Pano2VR from a business/photography perspective not from a coding background so my knowledge is very limited...

I have followed Hopki's instructions (thanks Hopki) and added the Google analytics HTML snippet to the header of the HTML template so that it looks like this:

::-webkit-scrollbar-thumb {
background-color: rgba(255,255,255,0.5);
}
</style>

<!-- Google Analytics -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-83151512-4', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics —>
</head>
<body>



I pleased to say that it is capturing data however the data is limited to simple metrics on the number of visitors, demographic, location and OS. Although it shows a bounce rate of 80%, I assume it only picks up the visitor at the index.html page and that 20% opened it twice. It also shows an average session time of 2 seconds which seems too short to be true. I have one visitor showing from Spain, more that likely a friend who was looking at the tour while discussing it with me on the phone and yet it shows a bounce rate of 100% and an average session time of 1 second for Spain.

Is there any way to improve the data that we can capture showing which nodes are visited and which external URLs are folllowed? It would be great to be able to present the client with more analytics and it would also be useful if we could track users thorough tours to see how they behave and how in turn to improve the layout of the tour?

Thanks
User avatar
3DV
Posts: 145
Joined: Tue Dec 15, 2015 12:44 pm
Contact:

You can add fields in the template that can be filled in inside Pano2VR, so you don't need 50 templates.

Based on normal.ggt, copied to normal-analytics.ggt and edited.
In the section that says 'Create the form in the HTML dialog box' the fields that are visible in Pano2VR are added, commented with '// Google Analytics and Statcounter form'
For the HTML output the Google Analytics code is added inside the <head> section. The Statcounter code is at the end of the <body> section. Hope that helps, it would be cool though if a few standard statistics counters (or at least Google Analytics) could be added by default in the templates.

Code: Select all

<?ggf
/*
	Create the form in the HTML dialog box
*/
	form.addCheckBox("parseanchor","Direct node access",false);
	form.addCheckBox("gyro","Include gyroscope control",false);
	form.addCheckBox("gyrodisable","     Disable on startup",false);
	form.addCheckBox("gyronorth",  "     Use true north",false);
	form.addLine();
	form.addCheckBox("swfgeneric","Flash fallback player",false);
	form.addFileNameInput("swf","Flash fallback file","Flash Panorama","Flash (*.swf)");
	form.addCheckBox("swffirst","Prefer Flash if available",false);
	form.addLine();
	form.addCheckBox("jsxml","Embedded XML",false);
	form.addCheckBox("gginfo","Create files for external embedding",false);

// Google Analytics and Statcounter form | Added by Ruud van Reenen - 3DV
	form.addLine();
	form.addLineEdit("trackingcode-google","Google Analytics Tracking Code","40","");
	form.addLineEdit("trackingcode-statcounter","Statcounter Tracking Code","40","");
	form.addLineEdit("trackingcode-statcounter-sec","Statcounter Security Code","40","");

	// define possible output formats
	form.addOutputFormat("HTML (.html)","html");
	form.addOutputFormat("HTML (.htm)","htm");
?>
<?ggs
	var configobj={ version: 1.0, type: 'panorama', external:{ js:[], css:[] }, skin:{}, player: {} };
	var d=new Date();
	configobj.creationdate=d.toISOString();
	configobj.configuration=outputfile;
	configobj.player.js='pano2vr_player.js';
	
	if (formvalue["gginfo"]=="true") {
	 	document.addPreviewImage("preview.jpg",output.windowWidth,output.windowHeight);
		configobj.preview={ img:'preview.jpg', width: output.windowWidth,height: output.windowHeight };
	}
// Functions to write out HTML5 and Flash code
	function addHtml5Code() {
?>
			// create the panorama player with the container
			pano=new pano2vrPlayer("container");
<?ggs
		if (formvalue['swf']!='') {
			addLoadConfigCode();
		} 
	}
	
	function addLoadConfigCode() {
		var gyroFunction;
		if (formvalue["gyro"]=="true") {
			// add gyroscope controller
			gyroFunction='gyro=new pano2vrGyro(pano,"container");';
			if (formvalue["gyrodisable"]=="true") {
				gyroFunction+=' gyro.disable();' // disable on startup
			}
			if (formvalue["gyronorth"]=="true") {
				gyroFunction+=' gyro.setTrueNorth(true);' // set to true north
			}
		} 
?>
<?ggs	if (formvalue["parseanchor"]=="true") {  ?>
			pano.startNode=startNode;
<?ggs 	}  ?>
<?ggs 	if (output.skinFile!="") { ?>
		// add the skin object
		skin=new pano2vrSkin(pano);
		// load the configuration
<?ggs 	} ?>
<?ggs
		if ((formvalue["jsxml"]=="true") && (formvalue["_gg_panorama"])) {
			panostr=document.encode(formvalue["_gg_panorama"].toString(),true);
			panostr=panostr.split("'").join("'"); // workaround for .replace
			panostr=panostr.split("\n").join("';\n\t\t\tpanorama+='");
?>
		panorama='<?ggs document.write(panostr); ?>';
		pano.readConfigString(panorama);
<?ggs
			if (gyroFunction) {
				document.writeln("\t\t\t" + gyroFunction);
			}
		} else {
?>
		window.addEventListener("load", function() {
			pano.readConfigUrlAsync("<?ggs document.write(outputfile); ?>"<?ggs 
				if (gyroFunction) document.write(",function() {  " + gyroFunction + "}"); ?>);
		});
<?ggs
		}
?>
<?ggs
	}	
	function addFlashCode() {
?>
			var flashvars = {};
			var params = {};
			// enable javascript interface
			flashvars.externalinterface="1";
			params.quality = "high";
			params.bgcolor = "<?ggs document.write(formvalue["bgcolor"]); ?>";
			params.allowscriptaccess = "sameDomain";
			params.allowfullscreen = "true";
			var attributes = {};
			attributes.id = "flashpano";
			attributes.name = "flashpano";
			attributes.align = "middle";
<?ggs if (formvalue["parseanchor"]=="true") {  ?>
			if (startNode.length>0) {
				flashvars.startnode=startNode;
			}
<?ggs }  ?>
<?ggs
		if (formvalue['swf']=='') {
			addGenericFlashCode();
		} else {
			addFileFlashCode();
		}
			
	}
	function addFileFlashCode() {
?>
			swfobject.embedSWF(
				"<?ggs 
					var swffn=document.expandVariables(formvalue['swf']); // replace placeholders
					swffn=document.expandFilename(swffn); // absolute path
					swffn=document.relativeOutputFilename(swffn); // relative to HTML file
					document.write(document.encodeUrl(swffn)); 
				?>", "container", "100%", "100%","10.0.0", "", flashvars, params, attributes);
<?ggs
	}
	function addGenericFlashCode() {
?>
<?ggs
	document.addfile("../html5/pano2vr_player.swf","pano2vr_player.swf");
	configobj.player.flash='pano2vr_player.swf';
?>	
			params.base="<?ggs document.write(outputbase); ?>";
			params.wmode = "transparent";
			pano=new pano2vrPlayer("container",{ useFlash:true, flashPlayerId: 'flashpano', flashContainerId:'flashcontainer'});
			swfobject.embedSWF("pano2vr_player.swf", "flashcontainer", "100%", "100%", "10.0.0", "", flashvars, params, attributes);
<?ggs
	}
	
	function writeUserdata(v) 
	{
		var s;
		s=document.expandVariables(v);
		document.write(document.encode(document.removeTags(s),true));
	}
?>
<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
		<title><?ggs document.write(document.encode(document.removeTags(document.expandVariables(config.userdata.title)))); ?></title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-status-bar-style" content="black" />
		<meta name="mobile-web-app-capable" content="yes" />		
<?ggs
	addFlashFallback=(formvalue['swf']!='') || (formvalue["swfgeneric"]=="true");
	if (addFlashFallback) {
		document.addfile("../3rdparty/swfobject/swfobject.js","swfobject.js");
		document.writeln('\t\t<script type="text/javascript" src="swfobject.js">');
		document.writeln('\t\t</script>');
	}
?>

	<!-- Google Universal Analytics code | Added by Ruud van Reenen - 3DV -->
	<?ggs if (formvalue["trackingcode-google"]!="") {   ?>
	<script>
	  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
	  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
	  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
	  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
	  ga('create', '<?ggs document.write(formvalue["trackingcode-google"]); ?>', 'auto');
	  ga('send', 'pageview');
	</script>
	<?ggs } ?>
	
		<style type="text/css" title="Default">
			body, div, h1, h2, h3, span, p {
				font-family: Verdana,Arial,Helvetica,sans-serif;
			}
			/* fullscreen */
			html {
				height:100%;
			}
			body {
				height:100%;
				margin: 0px;
				overflow:hidden; /* disable scrollbars */
				font-size: 10pt;
			}
			/* fix for scroll bars on webkit & >=Mac OS X Lion */ 
			::-webkit-scrollbar {
				background-color: rgba(0,0,0,0.5);
				width: 0.75em;
			}
			::-webkit-scrollbar-thumb {
    			background-color:  rgba(255,255,255,0.5);
			}
		</style>	
	</head>
	<body>
<!-- - - - - - - 8<- - - - - - cut here - - - - - 8<- - - - - - - -->
		<script type="text/javascript" src="pano2vr_player.js">
		</script>
<?ggs 
	if (output.skinFile!="") { 
		configobj.skin.js='skin.js';
?>
		<script type="text/javascript" src="skin.js">
		</script>
<?ggs } ?>
<?ggs if (formvalue["gyro"]=="true") { 
		document.addfile("../common/pano2vrgyro.js","pano2vrgyro.js");
?>
		<script type="text/javascript" src="pano2vrgyro.js">
		</script>
<?ggs } ?>
<?ggs 
	if (formvalue["_gg_google_maps_api"]=="1") { 
		configobj.external.js.push("https://maps.googleapis.com/maps/api/js?v=3.exp");
?>
		<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp">
		</script>
<?ggs } ?>
		<div id="container" style="width:100%;height:100%;">
		<br>Loading...<br><br>
<?ggs	if (addFlashFallback) {  ?>
		This content requires HTML5/CSS3, WebGL, or Adobe Flash Player Version 10 or higher.
<?ggs } else { ?>
		This content requires HTML5 with CSS3 3D Transforms or WebGL.
<?ggs } ?>
		</div>
		<script type="text/javascript">
<?ggs if (formvalue["parseanchor"]=="true") {  ?>
		var startNode=document.location.hash.substring(1);

		if (("onhashchange" in window) && (!(/MSIE (\d+\.\d+);/.test(navigator.userAgent)))) {
			window.onhashchange = function () {
				pano.openNext('{' + window.location.hash.substring(1) + '}');
         	}
	    } else {
        	var lastHash = window.location.hash;
        	window.setInterval(function () {
	           	if (window.location.hash != lastHash) {
   	        		lastHash = window.location.hash;
					pano.openNext('{' + window.location.hash.substring(1) + '}');
        	   	}
        	}, 100);
		}
<?ggs } ?>	
<?ggs	if (addFlashFallback) { 
			if (formvalue["swffirst"]=="true") {  
?>
		if (swfobject.hasFlashPlayerVersion("10.0.0")) {
<?ggs 			addFlashCode(); ?>			
		} else 
		// check for CSS3 3D transformations and WebGL
		if (ggHasHtml5Css3D() || ggHasWebGL()) {
<?ggs 			addHtml5Code(); ?>
<?ggs 		} else { /* swf first */ ?>
		// check for CSS3 3D transformations and WebGL
		if (ggHasHtml5Css3D() || ggHasWebGL()) {
			// use HTML5 panorama
<?ggs 			addHtml5Code(); ?>
		} else 
		if (swfobject.hasFlashPlayerVersion("10.0.0")) {
<?ggs 			addFlashCode(); ?>
<?ggs		} /* swf first */  ?>
		}
<?ggs	} else {
			addHtml5Code();
		}
    	if (formvalue['swf']=='') {
	  		addLoadConfigCode();
	  	}
?>
		</script>
		
		<!-- Statcounter code | Added by Ruud van Reenen - 3DV -->
		<?ggs if (formvalue["trackingcode-statcounter"]!="") {   ?>
			<script type="text/javascript">
				var sc_project=<?ggs document.write(formvalue["trackingcode-statcounter"]); ?>; 
				var sc_invisible=1; 
				var sc_security="<?ggs document.write(formvalue["trackingcode-statcounter-sec"]); ?>"; 
				var scJsHost = (("https:" == document.location.protocol) ?
				"https://secure." : "http://www.");
				document.write("<sc"+"ript type='text/javascript' src='" +
				scJsHost+
				"statcounter.com/counter/counter.js'></"+"script>");
			</script>
		<?ggs } ?>
		
		<noscript>
			<p><b>Please enable Javascript!</b></p>
		</noscript>
<!-- - - - - - - 8<- - - - - - cut here - - - - - 8<- - - - - - - --> 
		<!-- Hack needed to hide the url bar on iOS 9, iPhone 5s --> 
		<div style="width:1px;height:1px;"></div>
	</body>
</html>
<?ggs
	if (formvalue["gginfo"]=="true") {
		document.createutf8file("gginfo.json", JSON.stringify(configobj,null,"\t"));
	}
?>

Ruud van Reenen
3DV - Real estate artist impressions and animations
VR Tourviewer - Experience Pano2VR tours on Oculus Go, Quest, Rift, Pico and Cardboard VR headsets
User avatar
Laurent B
Posts: 79
Joined: Wed Aug 25, 2010 11:33 am
Location: France
Contact:

Hello,
Thank you for this solution. :)
Laurent
Laurent BIZIEN Photographies
MacBook Pro 2,6 GHz Intel Core i7 : Mojave 10.14.6 - 6.1 beta3b pro
bogsdolox
Posts: 16
Joined: Mon Sep 08, 2014 4:58 pm

The solution from £DV is great and works.

I am struggling to get Hopki's node code to work though... I have changed the info that gets sent but think I may have it wrong,... any ideas?

See attached for what I have done
Capture.JPG
Capture.JPG (38.02 KiB) Viewed 7708 times
bogsdolox
Posts: 16
Joined: Mon Sep 08, 2014 4:58 pm

Answrred by own query - I had left an underscore in! should have been javascript:ga.......
Post Reply