update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
296343bf3b
commit
d885a4baa9
5833 changed files with 418860 additions and 226988 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* Real time visitors map
|
||||
* Using Kartograph.js http://kartograph.org/
|
||||
|
|
@ -51,17 +51,20 @@
|
|||
$('.RealTimeMap_map', $element).attr('id', this.uniqueId);
|
||||
|
||||
// create the map
|
||||
this.map = Kartograph.map('#' + this.uniqueId);
|
||||
this.map = $K.map('#' + this.uniqueId);
|
||||
|
||||
$element.focus();
|
||||
},
|
||||
|
||||
_initStandaloneMap: function () {
|
||||
$('.top_controls').hide();
|
||||
$('.Menu--dashboard').on('piwikSwitchPage', function (event, item) {
|
||||
var clickedMenuIsNotMap = ($(item).attr('href').indexOf('module=UserCountryMap&action=realtimeWorldMap') == -1);
|
||||
$('#periodString').hide();
|
||||
initTopControls();
|
||||
$('#secondNavBar').on('piwikSwitchPage', function (event, item) {
|
||||
var href = $(item).attr('href');
|
||||
var clickedMenuIsNotMap = !href || (href.indexOf('module=UserCountryMap&action=realtimeWorldMap') == -1);
|
||||
if (clickedMenuIsNotMap) {
|
||||
$('.top_controls').show();
|
||||
$('#periodString').show();
|
||||
initTopControls();
|
||||
}
|
||||
});
|
||||
$('.realTimeMap_overlay').css('top', '0px');
|
||||
|
|
@ -99,7 +102,7 @@
|
|||
colorManager = piwik.ColorManager,
|
||||
colors = colorManager.getColors('realtime-map', ['white-bg', 'white-fill', 'black-bg', 'black-fill', 'visit-stroke',
|
||||
'website-referrer-color', 'direct-referrer-color', 'search-referrer-color',
|
||||
'live-widget-highlight', 'live-widget-unhighlight', 'symbol-animate-fill']),
|
||||
'live-widget-highlight', 'live-widget-unhighlight', 'symbol-animate-fill', 'region-stroke-color']),
|
||||
currentTheme = 'white',
|
||||
colorTheme = {
|
||||
white: {
|
||||
|
|
@ -142,7 +145,7 @@
|
|||
'visitLocalTime', 'city', 'country', 'referrerType', 'referrerName',
|
||||
'referrerTypeName', 'browserIcon', 'operatingSystemIcon',
|
||||
'countryFlag', 'idVisit', 'actionDetails', 'continentCode',
|
||||
'actions', 'searches', 'goalConversions', 'visitorId'].join(','),
|
||||
'actions', 'searches', 'goalConversions', 'visitorId', 'userId'].join(','),
|
||||
minTimestamp: firstRun ? -1 : lastTimestamp
|
||||
});
|
||||
}
|
||||
|
|
@ -214,6 +217,8 @@
|
|||
return '<h3>' + (r.city ? r.city + ' / ' : '') + r.country + '</h3>' +
|
||||
// icons
|
||||
ico(r.countryFlag) + ico(r.browserIcon) + ico(r.operatingSystemIcon) + '<br/>' +
|
||||
// User ID
|
||||
(r.userId ? _pk_translate('General_UserId') + ': ' + r.userId + '<br/>' : '') +
|
||||
// last action
|
||||
(ad && ad.length && ad[ad.length - 1].pageTitle ? '<em>' + ad[ad.length - 1].pageTitle + '</em><br/>' : '') +
|
||||
// time of visit
|
||||
|
|
@ -357,7 +362,7 @@
|
|||
*/
|
||||
function gotNewReport(report) {
|
||||
// if the map has been destroyed, do nothing
|
||||
if (!self.map) {
|
||||
if (!self.map || !self.$element.length || !$.contains(document, self.$element[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +379,7 @@
|
|||
if (firstRun) { // if we run this the first time, we initialiize the map symbols
|
||||
visitSymbols = map.addSymbols({
|
||||
data: [],
|
||||
type: Kartograph.Bubble,
|
||||
type: $K.Bubble,
|
||||
/*title: function(d) {
|
||||
return visitRadius(d) > 15 && d.actions > 1 ? d.actions : '';
|
||||
},
|
||||
|
|
@ -476,6 +481,8 @@
|
|||
if (firstRun && lastVisits.length) {
|
||||
// zoom changed, use cached report data
|
||||
gotNewReport(lastVisits.slice());
|
||||
} else if (Visibility.hidden()) {
|
||||
nextReqTimer = setTimeout(refreshVisits, config.liveRefreshAfterMs);
|
||||
} else {
|
||||
// request API for new data
|
||||
$('.realTimeMap_overlay img').show();
|
||||
|
|
@ -490,7 +497,7 @@
|
|||
*/
|
||||
function initMap() {
|
||||
$('#widgetRealTimeMapliveMap .loadingPiwik, .RealTimeMap .loadingPiwik').hide();
|
||||
map.addLayer('countries', {
|
||||
map.addLayer(currentMap.length == 3 ? 'context' : 'countries', {
|
||||
styles: {
|
||||
fill: colorTheme[currentTheme].fill,
|
||||
stroke: colorTheme[currentTheme].bg,
|
||||
|
|
@ -498,7 +505,9 @@
|
|||
},
|
||||
click: function (d, p, evt) {
|
||||
evt.stopPropagation();
|
||||
if (currentMap != 'world') { // zoom out if zoomed in
|
||||
if (currentMap.length == 2){ // zoom to country
|
||||
updateMap(d.iso);
|
||||
} else if (currentMap != 'world') { // zoom out if zoomed in
|
||||
updateMap('world');
|
||||
} else { // or zoom to continent view otherwise
|
||||
updateMap(UserCountryMap.ISO3toCONT[d.iso]);
|
||||
|
|
@ -509,7 +518,13 @@
|
|||
return d.name;
|
||||
}
|
||||
});
|
||||
|
||||
if (currentMap.length == 3){
|
||||
map.addLayer('regions', {
|
||||
styles: {
|
||||
stroke: colors['region-stroke-color']
|
||||
}
|
||||
});
|
||||
}
|
||||
var lastVisitId = -1,
|
||||
lastReport = [];
|
||||
refreshVisits(true);
|
||||
|
|
@ -539,7 +554,7 @@
|
|||
storeSettings();
|
||||
}
|
||||
|
||||
updateMap(location.hash && (location.hash == '#world' || location.hash.match(/^#[A-Z][A-Z]$/)) ? location.hash.substr(1) : 'world'); // TODO: restore last state
|
||||
updateMap(location.hash && (location.hash == '#world' || location.hash.match(/^#[A-Z]{2,3}$/)) ? location.hash.substr(1) : 'world'); // TODO: restore last state
|
||||
|
||||
// clicking on map background zooms out
|
||||
$('.RealTimeMap_map', this.$element).off('click').click(function () {
|
||||
|
|
@ -637,4 +652,4 @@
|
|||
|
||||
});
|
||||
|
||||
}());
|
||||
}());
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* Visitors Map with zoom in continents / countries. Cities + Region view.
|
||||
* Using Kartograph.js http://kartograph.org/
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
}
|
||||
|
||||
var mapContainer = $$('.UserCountryMap_map').get(0),
|
||||
map = self.map = Kartograph.map(mapContainer),
|
||||
map = self.map = $K.map(mapContainer),
|
||||
main = $$('.UserCountryMap_container'),
|
||||
worldTotalVisits = 0,
|
||||
width = main.width(),
|
||||
|
|
@ -96,7 +96,9 @@
|
|||
apiModule: module,
|
||||
apiAction: action,
|
||||
filter_limit: -1,
|
||||
limit: -1
|
||||
limit: -1,
|
||||
format_metrics: 0,
|
||||
showRawMetrics: 1
|
||||
});
|
||||
if (countryFilter) {
|
||||
$.extend(params, {
|
||||
|
|
@ -152,13 +154,21 @@
|
|||
//
|
||||
function formatValueForTooltips(data, metric, id) {
|
||||
|
||||
var val = data[metric] % 1 === 0 || Number(data[metric]) != data[metric] ? data[metric] : data[metric].toFixed(1),
|
||||
v = _[metric].replace('%s', '<strong>' + val + '</strong>');
|
||||
var val = data[metric] % 1 === 0 || Number(data[metric]) != data[metric] ? data[metric] : data[metric].toFixed(1);
|
||||
if (metric == 'bounce_rate') {
|
||||
val = NumberFormatter.formatPercent(val);
|
||||
} else if (metric == 'avg_time_on_site') {
|
||||
val = new Date(0, 0, 0, val / 3600, val % 3600 / 60, val % 60)
|
||||
.toTimeString()
|
||||
.replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
|
||||
} else {
|
||||
val = NumberFormatter.formatNumber(val);
|
||||
}
|
||||
|
||||
var v = _[metric].replace('%s', '<strong>' + val + '</strong>');
|
||||
|
||||
if (val == 1 && metric == 'nb_visits') v = _.one_visit;
|
||||
|
||||
function avgTime(d) { return d['sum_visit_length'] / d['nb_visits']; }
|
||||
|
||||
if (metric.substr(0, 3) == 'nb_' && metric != 'nb_actions_per_visit') {
|
||||
var total;
|
||||
if (id.length == 3) total = UserCountryMap.countriesByIso[id][metric];
|
||||
|
|
@ -187,7 +197,14 @@
|
|||
function addLegendItem(val, first) {
|
||||
var d = $('<div>'), r = $('<div>'), l = $('<div>'),
|
||||
metric = $$('.userCountryMapSelectMetrics').val(),
|
||||
v = formatNumber(Math.round(val)) + (metric == 'avg_time_on_site' ? first ? ' sec' : 's' : '');
|
||||
v = formatNumber(Math.round(val));
|
||||
|
||||
if (metric == 'avg_time_on_site') {
|
||||
v += first ? ' sec' : 's';
|
||||
} else if (metric == 'bounce_rate') {
|
||||
v += '%';
|
||||
}
|
||||
|
||||
d.css({ width: 17, height: 17, float: 'left', background: colscale(val) });
|
||||
l.css({ 'margin-left': 20, 'line-height': '20px', 'text-align': 'right' }).html(v);
|
||||
r.css({ clear: 'both', height: 19 });
|
||||
|
|
@ -195,7 +212,7 @@
|
|||
$('.UserCountryMap-legend .content').append(r);
|
||||
}
|
||||
|
||||
var stats, values = [], id = self.lastSelected, c;
|
||||
var stats, values = [], id = self.lastSelected, c, showLegend;
|
||||
|
||||
$.each(rows, function (i, r) {
|
||||
if (!$.isFunction(filter) || filter(r)) {
|
||||
|
|
@ -205,12 +222,15 @@
|
|||
});
|
||||
|
||||
stats = minmax(values);
|
||||
showLegend = values.length > 0;
|
||||
|
||||
if (stats.min == stats.max) {
|
||||
colscale = function () { return chroma.hex(oneCountryColor); };
|
||||
if (choropleth) {
|
||||
$('.UserCountryMap-legend .content').html('').show();
|
||||
addLegendItem(stats.min, true);
|
||||
if (showLegend) {
|
||||
addLegendItem(stats.min, true);
|
||||
}
|
||||
}
|
||||
return colscale;
|
||||
}
|
||||
|
|
@ -231,7 +251,7 @@
|
|||
}
|
||||
|
||||
// a good place to update the legend, isn't it?
|
||||
if (choropleth) {
|
||||
if (choropleth && showLegend) {
|
||||
$('.UserCountryMap-legend .content').html('').show();
|
||||
var itemExists = {};
|
||||
$.each(chroma.limits(values, 'k', 3), function (i, v) {
|
||||
|
|
@ -247,10 +267,11 @@
|
|||
return colscale;
|
||||
}
|
||||
|
||||
|
||||
function formatPercentage(val) {
|
||||
if (val < 0.001) return '< 0.1%';
|
||||
return Math.round(1000 * val) / 10 + '%';
|
||||
if (val < 0.001) {
|
||||
return '< ' + NumberFormatter.formatPercent(0.1);
|
||||
}
|
||||
return NumberFormatter.formatPercent(Math.round(1000 * val) / 10);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -334,7 +355,6 @@
|
|||
$('.UserCountryMap-tooltip').hide();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* updateState, called whenever the view changes
|
||||
*/
|
||||
|
|
@ -520,7 +540,14 @@
|
|||
return UserCountryMap.countriesByIso[pd.iso] === undefined;
|
||||
},
|
||||
tooltips: function (pd) {
|
||||
return '<h3>' + pd.name + '</h3>' + _.no_visit;
|
||||
var countryName = pd.name;
|
||||
for (var iso in self.config.countryNames) {
|
||||
if (UserCountryMap.ISO2toISO3[iso.toUpperCase()] == pd.iso) {
|
||||
countryName = self.config.countryNames[iso];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return '<h3>' + countryName + '</h3>' + _.no_visit;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -561,7 +588,6 @@
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* updateMap is called by renderCountryMap() and renderWorldMap()
|
||||
*/
|
||||
|
|
@ -595,10 +621,6 @@
|
|||
function quantify(d, metric) {
|
||||
if (!metric) metric = $$('.userCountryMapSelectMetrics').val();
|
||||
switch (metric) {
|
||||
case 'avg_time_on_site':
|
||||
return d.sum_visit_length / d.nb_visits;
|
||||
case 'bounce_rate':
|
||||
return d.bounce_count / d.nb_visits;
|
||||
default:
|
||||
return d[metric];
|
||||
}
|
||||
|
|
@ -637,7 +659,7 @@
|
|||
$.each(groups, function (g_id, group) {
|
||||
var apv = group.nb_actions / group.nb_visits,
|
||||
ats = group.sum_visit_length / group.nb_visits,
|
||||
br = (group.bounce_count * 100 / group.bounce_count);
|
||||
br = group.bounce_count / group.nb_visits;
|
||||
group['nb_actions_per_visit'] = apv;
|
||||
group['avg_time_on_site'] = new Date(0, 0, 0, ats / 3600, ats % 3600 / 60, ats % 60).toLocaleTimeString();
|
||||
group['bounce_rate'] = (br % 1 !== 0 ? br.toFixed(1) : br) + "%";
|
||||
|
|
@ -646,7 +668,7 @@
|
|||
return groupBy ? groups : groups.X;
|
||||
}
|
||||
|
||||
function displayUnlocatableCount(unlocated, total) {
|
||||
function displayUnlocatableCount(unlocated, total, regionOrCity) {
|
||||
$('.unlocated-stats').html(
|
||||
$('.unlocated-stats').data('tpl')
|
||||
.replace('%s', unlocated)
|
||||
|
|
@ -654,6 +676,21 @@
|
|||
.replace('%c', UserCountryMap.countriesByIso[self.lastSelected].name)
|
||||
);
|
||||
$('.UserCountryMap-info-btn').show();
|
||||
|
||||
var zoomTitle = '';
|
||||
if (regionOrCity == 'region') {
|
||||
zoomTitle = ' ' + _pk_translate('UserCountryMap_WithUnknownRegion', [unlocated]);
|
||||
} else if (regionOrCity == 'city') {
|
||||
zoomTitle = ' ' + _pk_translate('UserCountryMap_WithUnknownCity', [unlocated]);
|
||||
}
|
||||
|
||||
if (unlocated && zoomTitle) {
|
||||
if ($('.map-stats .unlocatableCount').length) {
|
||||
$('.map-stats .unlocatableCount').html(zoomTitle);
|
||||
} else {
|
||||
$('.map-stats').append('<small class="unlocatableCount">' + zoomTitle + '</small>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -677,6 +714,7 @@
|
|||
// load data from Piwik API
|
||||
ajax(_reportParams('UserCountry', 'getRegion', UserCountryMap.countriesByIso[iso].iso2))
|
||||
.done(function (data) {
|
||||
convertBounceRatesToPercents(data);
|
||||
|
||||
loadingComplete();
|
||||
|
||||
|
|
@ -727,7 +765,7 @@
|
|||
$.each(regionDict, function (key, region) {
|
||||
if (regionExistsInMap(key)) unlocated -= region.nb_visits;
|
||||
});
|
||||
displayUnlocatableCount(unlocated, totalCountryVisits);
|
||||
displayUnlocatableCount(unlocated, totalCountryVisits, 'region');
|
||||
|
||||
// create color scale
|
||||
colscale = getColorScale(regionDict, 'curMetric', null, true);
|
||||
|
|
@ -799,13 +837,15 @@
|
|||
*/
|
||||
function updateCitySymbols() {
|
||||
// color regions in white as background for symbols
|
||||
if (map.getLayer('regions')) map.getLayer('regions').style('fill', invisibleRegionBackgroundColor);
|
||||
var layerName = self.mode != "region" ? "regions2" : "regions";
|
||||
if (map.getLayer(layerName)) map.getLayer(layerName).style('fill', invisibleRegionBackgroundColor);
|
||||
|
||||
indicateLoading();
|
||||
|
||||
// get visits per city from API
|
||||
ajax(_reportParams('UserCountry', 'getCity', UserCountryMap.countriesByIso[iso].iso2))
|
||||
.done(function (data) {
|
||||
convertBounceRatesToPercents(data);
|
||||
|
||||
loadingComplete();
|
||||
|
||||
|
|
@ -823,7 +863,7 @@
|
|||
}));
|
||||
});
|
||||
|
||||
displayUnlocatableCount(unlocated, totalCountryVisits);
|
||||
displayUnlocatableCount(unlocated, totalCountryVisits, 'city');
|
||||
|
||||
// sort by current metric
|
||||
cities.sort(function (a, b) { return b.curMetric - a.curMetric; });
|
||||
|
|
@ -854,7 +894,7 @@
|
|||
var is_rate = metric.substr(0, 3) != 'nb_' || metric == 'nb_actions_per_visit';
|
||||
|
||||
var citySymbols = map.addSymbols({
|
||||
type: Kartograph.LabeledBubble,
|
||||
type: $K.LabeledBubble,
|
||||
data: cities,
|
||||
clustering: 'noverlap',
|
||||
clusteringOpts: {
|
||||
|
|
@ -942,7 +982,6 @@
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
_updateMap(iso + '.svg', function () {
|
||||
|
||||
// add background
|
||||
|
|
@ -1099,6 +1138,8 @@
|
|||
// now load the metrics for all countries
|
||||
ajax(_reportParams('UserCountry', 'getCountry'))
|
||||
.done(function (report) {
|
||||
convertBounceRatesToPercents(report);
|
||||
|
||||
var metrics = $$('.userCountryMapSelectMetrics option');
|
||||
var countryData = [], countrySelect = $$('.userCountryMapSelectCountry'),
|
||||
countriesByIso = {};
|
||||
|
|
@ -1148,7 +1189,9 @@
|
|||
|
||||
// populate country select
|
||||
$.each(countryData, function (i, country) {
|
||||
countrySelect.append('<option value="' + country.iso + '">' + country.name + '</option>');
|
||||
if (!!country.iso) {
|
||||
countrySelect.append('<option value="' + country.iso + '">' + country.name + '</option>');
|
||||
}
|
||||
});
|
||||
|
||||
initUserInterface();
|
||||
|
|
@ -1198,20 +1241,33 @@
|
|||
$$('.widgetUserCountryMapvisitorMap .widgetName span').remove();
|
||||
$$('.widgetUserCountryMapvisitorMap .widgetName').append('<span class="map-title"></span>');
|
||||
|
||||
// converts bounce rate quotients to numeric percents, eg, .12 => 12
|
||||
function convertBounceRatesToPercents(report) {
|
||||
$.each(report.reportData, function (i, row) {
|
||||
if (row['bounce_rate']) {
|
||||
row['bounce_rate'] = parseFloat(row['bounce_rate']) * 100;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* resizes the map
|
||||
*/
|
||||
resize: function () {
|
||||
var ratio, w, h,
|
||||
map = this.map,
|
||||
maxHeight = $(window).height() - (this.theWidget && this.theWidget.isMaximised ? 150 : 79);
|
||||
map = this.map;
|
||||
|
||||
ratio = map.viewAB.width / map.viewAB.height;
|
||||
w = map.container.width();
|
||||
h = w / ratio;
|
||||
h = Math.min(maxHeight, h);
|
||||
|
||||
// special handling for widgetize mode
|
||||
if (!this.theWidget && map.container.parents('.widget').length) {
|
||||
var maxHeight = $(window).height() - ($('html').height() - map.container.height());
|
||||
h = Math.min(maxHeight, h);
|
||||
}
|
||||
|
||||
map.container.height(h - 2);
|
||||
map.resize(w, h);
|
||||
|
||||
|
|
@ -1231,7 +1287,6 @@
|
|||
|
||||
}());
|
||||
|
||||
|
||||
/*
|
||||
* Some static data used both by VisitorMap and RealtimeMap
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue