Google Analytics Embed API demo not showing at all - google-analytics

I am replicating Google Analytics Embed API demos, which you can find here. So far, I have been able to replicate the basic dashboard, multiple date ranges, multiple views and interactive charts using my clientid
The one that is giving me trouble is the Third Party Visualizations and I am following the steps according to what is posted.
By the way for step 3 I am using the full path "https://ga-dev-tools.appspot.com/public/..."
Once I log in with my Google Account, all I get is the embed-api-auth-container but not the charts. I am using the following code:
(Apologies, I am new to StackOverflow)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thirtd Party Visualizations</title>
<link rel="stylesheet" href="https://ga-dev-tools.appspot.com/public/css/main.css" />
<script>
(function(w,d,s,g,js,fs){
g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
js.src='https://apis.google.com/js/platform.js';
fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
</script>
</head>
<body>
<div id="embed-api-auth-container"></div>
<div id="view-selector-container"></div>
<div id="active-users-container"></div>
<div id="chart-1-container"></div>
<div id="legend-1-container"></div>
<div id="chart-2-container"></div>
<div id="legend-2-container"></div>
<div id="chart-3-container"></div>
<div id="legend-3-container"></div>
<div id="chart-4-container"></div>
<div id="legend-4-container"></div>
</body>
<script src="https://ga-dev-tools.appspot.com/public/javascript/Chart.min.js"></script>
<script src="https://ga-dev-tools.appspot.com/public/javascript/moment.min.js"></script>
<script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/view-selector2.js"></script>
<script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/date-range-selector.js"></script>
<script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/active-users.js"></script>
<script>
gapi.analytics.ready(function() {
gapi.analytics.auth.authorize({
container: 'embed-api-auth-container',
clientid: 'XXXX',
});
var activeUsers = new gapi.analytics.ext.ActiveUsers({
container: 'active-users-container',
pollingInterval: 5
});
activeUsers.once('success', function() {
var element = this.container.firstChild;
var timeout;
this.on('change', function(data) {
var element = this.container.firstChild;
var animationClass = data.delta > 0 ? 'is-increasing' : 'is-decreasing';
element.className += (' ' + animationClass);
clearTimeout(timeout);
timeout = setTimeout(function() {
element.className =
element.className.replace(/ is-(increasing|decreasing)/g, '');
}, 3000);
});
});
var viewSelector = new gapi.analytics.ext.ViewSelector2({
container: 'view-selector-container',
})
.execute();
viewSelector.on('viewChange', function(data) {
var title = document.getElementById('view-name');
title.innerHTML = data.property.name + ' (' + data.view.name + ')';
activeUsers.set(data).execute();
renderWeekOverWeekChart(data.ids);
renderYearOverYearChart(data.ids);
renderTopBrowsersChart(data.ids);
renderTopCountriesChart(data.ids);
});
function renderWeekOverWeekChart(ids) {
// Adjust `now` to experiment with different days, for testing only...
var now = moment(); // .subtract(3, 'day');
var thisWeek = query({
'ids': ids,
'dimensions': 'ga:date,ga:nthDay',
'metrics': 'ga:sessions',
'start-date': moment(now).subtract(1, 'day').day(0).format('YYYY-MM-DD'),
'end-date': moment(now).format('YYYY-MM-DD')
});
var lastWeek = query({
'ids': ids,
'dimensions': 'ga:date,ga:nthDay',
'metrics': 'ga:sessions',
'start-date': moment(now).subtract(1, 'day').day(0).subtract(1, 'week')
.format('YYYY-MM-DD'),
'end-date': moment(now).subtract(1, 'day').day(6).subtract(1, 'week')
.format('YYYY-MM-DD')
});
Promise.all([thisWeek, lastWeek]).then(function(results) {
var data1 = results[0].rows.map(function(row) { return +row[2]; });
var data2 = results[1].rows.map(function(row) { return +row[2]; });
var labels = results[1].rows.map(function(row) { return +row[0]; });
labels = labels.map(function(label) {
return moment(label, 'YYYYMMDD').format('ddd');
});
var data = {
labels : labels,
datasets : [
{
label: 'Last Week',
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : data2
},
{
label: 'This Week',
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : data1
}
]
};
new Chart(makeCanvas('chart-1-container')).Line(data);
generateLegend('legend-1-container', data.datasets);
});
}
function renderYearOverYearChart(ids) {
// Adjust `now` to experiment with different days, for testing only...
var now = moment(); // .subtract(3, 'day');
var thisYear = query({
'ids': ids,
'dimensions': 'ga:month,ga:nthMonth',
'metrics': 'ga:users',
'start-date': moment(now).date(1).month(0).format('YYYY-MM-DD'),
'end-date': moment(now).format('YYYY-MM-DD')
});
var lastYear = query({
'ids': ids,
'dimensions': 'ga:month,ga:nthMonth',
'metrics': 'ga:users',
'start-date': moment(now).subtract(1, 'year').date(1).month(0)
.format('YYYY-MM-DD'),
'end-date': moment(now).date(1).month(0).subtract(1, 'day')
.format('YYYY-MM-DD')
});
Promise.all([thisYear, lastYear]).then(function(results) {
var data1 = results[0].rows.map(function(row) { return +row[2]; });
var data2 = results[1].rows.map(function(row) { return +row[2]; });
var labels = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'];
for (var i = 0, len = labels.length; i < len; i++) {
if (data1[i] === undefined) data1[i] = null;
if (data2[i] === undefined) data2[i] = null;
}
var data = {
labels : labels,
datasets : [
{
label: 'Last Year',
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : data2
},
{
label: 'This Year',
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : data1
}
]
};
new Chart(makeCanvas('chart-2-container')).Bar(data);
generateLegend('legend-2-container', data.datasets);
})
.catch(function(err) {
console.error(err.stack);
})
}
function renderTopBrowsersChart(ids) {
query({
'ids': ids,
'dimensions': 'ga:browser',
'metrics': 'ga:pageviews',
'sort': '-ga:pageviews',
'max-results': 5
})
.then(function(response) {
var data = [];
var colors = ['#4D5360','#949FB1','#D4CCC5','#E2EAE9','#F7464A'];
response.rows.forEach(function(row, i) {
data.push({ value: +row[1], color: colors[i], label: row[0] });
});
new Chart(makeCanvas('chart-3-container')).Doughnut(data);
generateLegend('legend-3-container', data);
});
}
function renderTopCountriesChart(ids) {
query({
'ids': ids,
'dimensions': 'ga:country',
'metrics': 'ga:sessions',
'sort': '-ga:sessions',
'max-results': 5
})
.then(function(response) {
var data = [];
var colors = ['#4D5360','#949FB1','#D4CCC5','#E2EAE9','#F7464A'];
response.rows.forEach(function(row, i) {
data.push({
label: row[0],
value: +row[1],
color: colors[i]
});
});
new Chart(makeCanvas('chart-4-container')).Doughnut(data);
generateLegend('legend-4-container', data);
});
}
function query(params) {
return new Promise(function(resolve, reject) {
var data = new gapi.analytics.report.Data({query: params});
data.once('success', function(response) { resolve(response); })
.once('error', function(response) { reject(response); })
.execute();
});
}
function makeCanvas(id) {
var container = document.getElementById(id);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
container.innerHTML = '';
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
container.appendChild(canvas);
return ctx;
}
function generateLegend(id, items) {
var legend = document.getElementById(id);
legend.innerHTML = items.map(function(item) {
var color = item.color || item.fillColor;
var label = item.label;
return '<li><i style="background:' + color + '"></i>' + label + '</li>';
}).join('');
}
Chart.defaults.global.animationSteps = 60;
Chart.defaults.global.animationEasing = 'easeInOutQuart';
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
});
</script>
</html>

The example code you linked to is missing some elements and needs to be updated.
Check out this bug on Github which has a workaround and allows you to track the progress of the fix:
https://github.com/googleanalytics/ga-dev-tools/issues/51

Related

Unable to draw a Curved Polyline using Here Maps JS Api

Unable to Draw a curved polyline using Here Maps JS API.
Trying to add the logic based on my previous findings.
It throws an error "Uncaught TypeError: arc.GreatCircle is not a constructor"
Any Suggestions on how to fix this ?
My Earlier Querstion
Here is my working JSFiddle which is trying to draw a curve to multiple spots.
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Europe
var map = new H.Map(document.getElementById('map'),
defaultLayers.vector.normal.map,{
center: {lat:52, lng:5},
zoom: 5,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
window.addEventListener('resize', function() { map.getViewPort().resize(); });
var npoints = 100,
offset = 20;
// Now use the map as required...
//addPolylineToMap(map);
// Berlin -> Chicago0
add([52.51607,13.37699],[41.88425,-87.63245], { style: { strokeColor : "#00FF00", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Tokyo -> san Francisco
add([35.68019,139.81194],[37.77712,-122.41964], {style: { strokeColor: "rgba(0,0,255,0.7)", lineWidth: 15, lineDash: [1], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Melbourne
add([52.51607,13.37699],[-37.81753,144.96715], { style: { strokeColor : "rgba(255,0,255,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Paris -> Paris -> London
add([52.51607,13.37699],[48.85721, 2.34144], { style: { strokeColor : "rgba(0,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
add([48.85721, 2.34144],[51.50643,-0.12721], { style: { strokeColor : "rgba(255,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
function add(s,e,options) {
var arc = {};
arc.Coord = Coord;
arc.Arc = Arc;
arc.GreatCircle = GreatCircle;
var start_ll = new H.geo.Point(s[0],s[1]),
end_ll = new H.geo.Point(e[0],e[1]),
start_coord = {x: start_ll.lng, y:start_ll.lat},
end_coord = {x:end_ll.lng, y:end_ll.lat};
description = ''+s[0]+','+s[1]+'=>'+e[0]+','+e[1]+'',
gc0 = new arc.GreatCircle(start_coord,end_coord, {'name': 'line', 'color':'#ff7200','description':description}),
line0 = gc0.Arc(npoints,{offset:offset}),
strip = line0.strip();
map.addObject(new H.map.Polyline(strip, options));
}
var D2R = Math.PI / 180;
var R2D = 180 / Math.PI;
var Coord = function(lon, lat) {
this.lon = lon;
this.lat = lat;
this.x = D2R * lon;
this.y = D2R * lat;
};
Coord.prototype.view = function() {
return String(this.lon).slice(0, 4) + ',' + String(this.lat).slice(0, 4);
};
Coord.prototype.antipode = function() {
var anti_lat = -1 * this.lat;
var anti_lon = (this.lon < 0) ? 180 + this.lon : (180 - this.lon) * -1;
return new Coord(anti_lon, anti_lat);
};
var LineString = function() {
this.coords = [];
this.length = 0;
};
LineString.prototype.move_to = function(coord) {
this.length++;
this.coords.push(coord);
};
var Arc = function(properties) {
this.properties = properties || {};
this.geometries = [];
};
Arc.prototype.json = function() {
if (this.geometries.length <= 0) {
return { 'geometry': { 'type': 'LineString', 'coordinates': null }, 'type': 'Feature', 'properties': this.properties };
} else if (this.geometries.length == 1) {
return { 'geometry': { 'type': 'LineString', 'coordinates': this.geometries[0].coords }, 'type': 'Feature', 'properties': this.properties };
} else {
var multiline = [];
for (var i = 0; i < this.geometries.length; i++) {
multiline.push(this.geometries[i].coords);
}
return { 'geometry': { 'type': 'MultiLineString', 'coordinates': multiline }, 'type': 'Feature', 'properties': this.properties };
}
};
Arc.prototype.strip = function() {
var s = H.geo.Strip ? new H.geo.Strip() : new H.geo.LineString();
for (var i = 0; i < this.geometries.length; i++) {
if (this.geometries[i].coords.lenght !== 0) {
var coords = this.geometries[i].coords;
for (var j = 0; j < coords.length; j++) {
var p = new H.geo.Point(coords[j][1], coords[j][0]);
s.pushPoint(p);
}
}
}
return s;
}
var GreatCircle = function(start, end, properties) {
if (!start || start.x === undefined || start.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
if (!end || end.x === undefined || end.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
this.start = new Coord(start.x, start.y);
this.end = new Coord(end.x, end.y);
this.properties = properties || {};
var w = this.start.x - this.end.x;
var h = this.start.y - this.end.y;
var z = Math.pow(Math.sin(h / 2.0), 2) + Math.cos(this.start.y) * Math.cos(this.end.y) * Math.pow(Math.sin(w / 2.0), 2);
this.g = 2.0 * Math.asin(Math.sqrt(z));
if (this.g == Math.PI) {
throw new Error('it appears ' + start.view() + ' and ' + end.view() + " are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite");
} else if (isNaN(this.g)) {
throw new Error('could not calculate great circle between ' + start + ' and ' + end);
}
};
#map {
width: 95%;
height: 450px;
background: grey;
}
<script src="https://heremaps.github.io/maps-api-for-javascript-examples/test-credentials.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Polyline on the Map</title>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<link rel="stylesheet" type="text/css" href="demo.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="../template.css" />
<script type="text/javascript" src='../test-credentials.js'></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
</head>
<body id="markers-on-the-map">
<div id="map"></div>
<script type="text/javascript" src='demo.js'></script>
</body>
</html>
this is simple: the var GreatCircle is not defined yet but program code invoke GreatCircle
We moved some parts of code through each together
but any way there is error GreatCircle doesn't have 'arc' property defined.
there is this module https://demo.support.here.com/javascripts/examples/v31/geodesic-polyline.js
but you needs Bézier curve: https://en.wikipedia.org/wiki/B%C3%A9zier_curve
I found some implementation on this https://habr.com/ru/post/163073/ - (but in russian) - there a curve consists from lines based on 100 points (step 0.01)
flow = getBezierCurve(new Array(arr[0], arr[1], arr[2], arr[3]), 0.01);
drawLines(ctx, flow, 10);
In JS API wasn't implemented functionality of like Bézier curve
but search in google on "bezier curve javascript example code" - if you get points of curve you can use in JS API map.screenToGeo every point and plot it on the map

Problem in making chart with Chart.js in wix?

I am having a problem in building a pie chart with chart.js ..I am working in wix.com ..The problem i am facing is with 2 postmessage()..
Here is the page code....
import wixData from 'wix-data';
import { session } from 'wix-storage';
var name = session.getItem('name');
var platformName = session.getItem('platform');
import { getchampionranks } from 'backend/pcprofile.jsw';
$w.onReady(function () {
getchampionranks('pronil07').then(res => {
console.log(res);
var data = [];
var labels = [];
for (var i = 0; i <= res.length - 1; i++) {
data.push(res[i].Minutes.toString());
labels.push(res[i].champion.toString());
}
console.log(data);
console.log("Data length: " + data.length);
console.log(labels);
console.log("Label length: " + labels.length);
$w("#html1").postMessage(data);
//$w("#html1").postMessage(labels);
});
});
Here is the iframe code...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src ="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
</head>
<body onLoad="ready()">
<canvas id="myChart" width="146" height="149"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [],
datasets: [{
label: 'wins/loss',
data: [],
backgroundColor: [
'#3ddba1',
'#e02a2a',
'#4286f4',
'#6897e2',
'#444a54',
'#45a567',
'#91a545',
'#a87534',
'#8c6e8a'
],
borderWidth: 1
}]
},
options: {
cutoutPercentage : 0,
rotation: Math.PI * 0.8,
legend:{
display: false,
position: 'bottom',
},
animation: {
easing: 'easeOutElastic',
Steps: 100,
animateRotate : true,
animateScale : true
}
}
});
window.onmessage = function(event){
myChart.data.datasets[0].data = event.data;
myChart.update();
};
function ready(){
window.parent.postMessage({"type":"ready"}, "*");
}
</script>
</body>
</html>
On doing this..i am getting the result like this..
Result
I am getting the chart with the data array..but the labels is undefined..
And if i unquote the postmessage(labels) and send both data and labels via 2 postmessage()..the chart don't form...
I need to send both data and labels array to the iframe from page code...
Any solution?????
This is easiest done by sending both the data and the labels from your page code in one object. Then in the HTML element, you can set the chart's data and labels using that object.
In your case, that would look something like this:
Page Code:
let info = {data:data, labels:labels};
$w("#html1").postMessage(info);
HTML Element Code:
window.onmessage = function(event){
myChart.data.datasets[0].data = event.data.data;
myChart.data.labels = event.data.labels;
myChart.update();
};
You are right! This is the easiest way.
Here is the page code...
var data = [];
for (var i = 1; i < 7; i++) {
var _temp = Math.log10(i);
data.push(_temp);
}
var labels = ["September", "October", "Novemver", "December", "January", "February"];
$w.onReady(() => {
console.log("Data length: " + data.length);
console.log(data);
console.log("Label length: " + labels.length);
console.log(labels);
$w("#html1").onMessage((event) => {
let info = { data: data, labels: labels };
if (event.data.type === 'ready') {
$w("#html1").postMessage(info);
}
});
});
Here is the html code...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src ="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js">
</script>
</head>
<body onLoad="ready()">
<canvas id="myChart" width="250" height="200"></canvas>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Our activity',
data: []
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
window.onmessage = function(event){
myChart.data.datasets[0].data = event.data.data;
myChart.data.labels = event.data.labels;
myChart.update();
};
function ready(){
window.parent.postMessage({"type":"ready"}, "*");
}

Optimising fullcalendar with meteor for large data

I'm using an auto-run block where I re-execute the same mongo with a few session variables ! loop over those doc , construct an array of events then I call the addEventSource and refetchResources function which are pretty expensive computationally ! the fullcalendar becomes slow the more data ! on every action the auto-run block is rerun ! what in your in your opinion can be done to speed things up ? I thought about only re-rendering the delta elements but this doesn't cover the deletion and update .
calendar = $('#calendar').fullCalendar({
schedulerLicenseKey: Meteor.settings.public.fullCalendarLicenseKey,
now: new Date(),
editable: true, // enable draggable events
droppable: true, // this allows things to be dropped onto the calendar
aspectRatio: 1.8,
timezone:'local',
disableDragging: true,
displayEventTime: false,
selectable:true,
allDaySlot:true,
slotDuration:'24:00',
lazyFetching:true,
resourceLabelText: 'Employees',
nextDayThreshold:"12:00",
resources: function(callback) {
var tmp_obj = { usersSorting : { } };
tmp_obj.usersSorting["indexByLocation."+Session.get("locationId")] = 1;
var users = [];
var data = Meteor.users.find({
$or:[
{"profile.showInScheduler":{$exists:false}},
{"profile.showInScheduler":true}
],
assignedTo:{$in:[Session.get("locationId")]},
'locations._id':Session.get("locationId"),
"profile.companyId":Session.get("companyId")
},{sort : tmp_obj.usersSorting});
var arr = data.map(function(c) {
var employeeType = c.userSettings.employeeType;
var type = EmployeeType.findOne({_id:employeeType});
var img = Images.findOne({_id: c.picture});
var imgUrl = img ? img.url() : "/images/default-avatar.png";
c.name = c.name || "";
var totalHoursAllLocation = 0;
var totalHoursCurrentLocation = 0;
return {
id: c._id,
title: "t",
width:"2px"
};
});
callback(arr);
},
drop: function(date, jsEvent, ui, resourceId) {
},
eventResize: function( event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, view ) {
},
dayClick: function(date, jsEvent, view,res,res2) {
},
eventClick: function ( event, jsEvent, view ) {
}
}).data().fullCalendar;
/********************* reactive calendar *****************/
this.autorun(function() {
if(Session.get("activeUsers")) {
schedulerSubs = Meteor.subscribe("SchedulesByLocation", Session.get("companyId"), Session.get("locationId"), Session.get("activeUsers"), moment(Session.get("currentDate")).startOf('week').toDate(), moment(Session.get("currentDate")).startOf('week').add(2, "weeks").endOf('isoweek').add(1,"days").toDate());
}
const company = Companies.findOne({_id: Session.get("companyId")});
Session.set("loading", true);
let events = [];
let usersInLocation = Meteor.users.find({
assignedTo: {$in: [Session.get("locationId")]},
'locations._id': Session.get("locationId"),
"profile.companyId": Session.get("companyId")
}).fetch();
let userIds = _.map(usersInLocation, "_id");
userIds.push("temp" + Session.get("companyId") + Session.get("locationId"));
Session.set("activeUsers",userIds);
if(schedulerSubs && schedulerSubs.ready()) {
var data;
SchedulerEvts = Schedules.find({
uid: {$in: userIds},
locationId: Session.get("locationId"),
companyId: Session.get("companyId"),
start: {$gte: moment(Session.get("currentDate")).startOf('week').toDate()},
end: {$lte: moment(Session.get("currentDate")).add(2, "week").endOf('isoweek').toDate()}
}).fetch();
SchedulerEvts.forEach(function (evt) {
var event = null;
var color = "";
var oloc = "";
var attendance = null;
var locationName = "";
var id = evt._id;
event = {
id:id,
type : evt.type,
title: evt.name,
start: evt.start,
end: evt.end,
color:color,
resourceId: evt.uid,
locationName:locationName,
};
events.push(event);
});
if (calendar) {
calendar.removeEvents();
calendar.addEventSource(events);
calendar.refetchResources();
}
}

How to add google map and other charts in the gridstack widget using knockout.js

I am using Gridstack with Knockout.js. I am using http://troolee.github.io/gridstack.js/demo/knockout.html to create Gridstack widgets. I added a Google map in one of these widgets. The map appears with a scroll bar. Also, I need to have some kind of heading, as it is in its present state. The main problem is that the dimension of the map is fixed and when I resize the widget, the map does not fit in the widget automatically. Here is my full code:
ko.components.register('dashboard-grid', {
viewModel: {
createViewModel: function (controller, componentInfo) {
var ViewModel = function (controller, componentInfo) {
var grid = null;
this.widgets = controller.widgets;
this.id = controller.id;
this.afterAddWidget = function (items) {
if (grid == null) {
grid = $(componentInfo.element).find('.grid-stack').gridstack({
auto: false,
animate: true
}).data('gridstack');
}
var item = _.find(items, function (i) { return i.nodeType == 1 });
grid.addWidget(item);
ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
grid.removeWidget(item);
});
};
};
return new ViewModel(controller, componentInfo);
}
},
template:
[
'<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
' <div class="grid-stack-item" data-bind="attr: {\'data-gs-x\': $data.x, \'data-gs-y\': $data.y, \'data-gs-width\': $data.width, \'data-gs-height\': $data.height, \'data-gs-auto-position\': $data.auto_position}">',
' <div class="grid-stack-item-content" >',
' <header style="background-color: green;"> ',
' <button data-bind="click: $root.deleteWidget">Delete me</button><br>',
' <label><strong data-bind="text: $root.ids"></strong></label>',
' </header>',
' <div data-bind="attr: {id: $root.ids}">',
' </div>',
' </div>',
' </div>',
'</div> '
].join('')
});
$(function () {
var ids;
var Controller = function () {
var self = this;
this.widgets = ko.observableArray([]);
this.id = ko.observable("google-map");
this.ids = "";
this.addNewWidget = function () {
this.ids = this.id(); // this.ids is used to give id to div elements
this.widgets.push({
x: 0,
y: 0,
width:4,
height:5,
auto_position: true,
});
// calling method to draw map
createWidget(this.ids);
return false;
};
this.deleteWidget = function (item) {
self.widgets.remove(item);
return false;
};
};
ko.applyBindings(new Controller());
});
function createWidget(id) {
var dataArray, latitude, longitude, speed;
// Load the Visualization API and the corechart package.
try {
google.charts.load('current', {'packages':['map', 'gauge']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
}
catch ( err ) {
//console.log(err);
}
function drawChart() {
latitude = Number(12.93213);
longitude = Number(77.695185);
var mapOptions = {
showTooltip: true,
showInfoWindow: true,
zoomLevel: 16, // range: 0-21 for "roadmap" map type
mapType: 'roadmap',
enableScrollWheel: true,
draggable: false,
};
var coordinates = "Latitude : " + latitude + "\nLongitude : "+ longitude;
var mapData = google.visualization.arrayToDataTable([
['Lat', 'Long', 'Name'],
[latitude, longitude, coordinates]
] );
try {
//var chart = new google.visualization.Gauge(document.getElementById('gauge'));
var map = new google.visualization.Map(document.getElementById(id));
map.draw(mapData, mapOptions);
}
catch (err) {
console.log(err);
}
} // drawChart() ends here
} // createWidgets() ends here

label near icon in fusion tables map

I created a map showing some restaurant in a particular area. I used fusion tables as data entry and the code generated to display this map:
here is the link
I tried with no luck to add a text label with the name of the restaurant near the placemark ( icon ) .
Any ideas on how I can do?
I searched a lot in the forums, but I didn't find a solution.
Thank you very much
JT
(here is the code )
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"></meta>
<title>Locali in zona Fiume e Quarnero - Google Fusion Tables</title>
<style type="text/css">
html, body, #googft-mapCanvas { height:100%; margin: 0; padding: 0;}
</style>
<script type="text/javascript" src="https://maps.google.com/maps/api/js? sensor=false&v=3"></script>
<script type="text/javascript">
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) ||
(navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '500px':'100%' ;
mapDiv.style.height = isMobile ? '300px':'100%' ;
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(45.19975321105807, 14.824613028515614),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col6",
from: "1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function() {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function() {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="googft-mapCanvas"></div>
</body>
</html>
One option (for tables with less than a couple hundred rows) would be to query the table for the data using GViz and use that to add labels to the map.
proof of concept fiddle
google.load('visualization', '1', {'packages':['corechart', 'table', 'geomap']});
var tableid ="1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx"
var map;
var labels = [];
function displayLabels() {
//set the query using the current bounds
var queryStr = "SELECT Posizione, Nome FROM "+ tableid;
var queryText = encodeURIComponent(queryStr);
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
// alert(queryStr);
//set the callback function
query.send(displayLabelText);
}
function displayLabelText(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
FTresponse = response;
//for more information on the response object, see the documentation
//http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
// alert(numRows);
// var bounds = new google.maps.LatLngBounds();
for(i = 0; i < numRows; i++) {
var label = response.getDataTable().getValue(i, 1);
var labelStr = label.toString()
var positionStr = response.getDataTable().getValue(i, 0);
var position = positionStr.split(',');
var point = new google.maps.LatLng(
parseFloat(position[0]),
parseFloat(position[1]));
// bounds.extend(point);
labels.push(new InfoBox({
content: labelStr
,boxStyle: {
border: "1px solid black"
,textAlign: "center"
,backgroundColor:"white"
,fontSize: "8pt"
,width: "50px"
}
,disableAutoPan: true
,pixelOffset: new google.maps.Size(-25, 0)
,position: point
,closeBoxURL: ""
,isHidden: false
,enableEventPropagation: true
}));
labels[labels.length-1].open(map);
}
// zoom to the bounds
// map.fitBounds(bounds);
}
google.setOnLoadCallback(displayLabels);
code snippet:
google.load('visualization', '1', {
'packages': ['corechart', 'table', 'geomap']
});
var tableid = "1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx"
var map;
var labels = [];
function displayLabels() {
//set the query using the current bounds
var queryStr = "SELECT Posizione, Nome FROM " + tableid;
var queryText = encodeURIComponent(queryStr);
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
// alert(queryStr);
//set the callback function
query.send(displayLabelText);
}
function displayLabelText(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
FTresponse = response;
//for more information on the response object, see the documentation
//http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
// alert(numRows);
// var bounds = new google.maps.LatLngBounds();
for (i = 0; i < numRows; i++) {
var label = response.getDataTable().getValue(i, 1);
var labelStr = label.toString()
var positionStr = response.getDataTable().getValue(i, 0);
var position = positionStr.split(',');
var point = new google.maps.LatLng(
parseFloat(position[0]),
parseFloat(position[1]));
// bounds.extend(point);
labels.push(new InfoBox({
content: labelStr,
boxStyle: {
border: "1px solid black",
textAlign: "center",
backgroundColor: "white",
fontSize: "8pt",
width: "50px"
},
disableAutoPan: true,
pixelOffset: new google.maps.Size(-25, 0),
position: point,
closeBoxURL: "",
isHidden: false,
enableEventPropagation: true
}));
labels[labels.length - 1].open(map);
}
// zoom to the bounds
// map.fitBounds(bounds);
}
google.setOnLoadCallback(displayLabels);
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) || (navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '500px' : '100%';
mapDiv.style.height = isMobile ? '300px' : '100%';
map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(45.19975321105807, 14.824613028515614),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: {
enabled: false
},
query: {
select: "col6",
from: "1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
google.maps.event.addListenerOnce(map, 'bounds_changed', displayLabels);
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function() {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function() {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#googft-mapCanvas {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&ext=.js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
<script src="http://www.google.com/jsapi"></script>
<div id="googft-mapCanvas"></div>

Resources