// vim: et:ts=4:sw=4:sts=4:ft=javascript 'use strict'; pandora.ui.statisticsDialog = function() { var colors = { system: { 'Android': [0, 255, 0], 'BlackBerry': [64, 64, 64], 'BSD': [255, 0, 0], 'iOS': [0, 128, 255], 'Java': [128, 128, 128], 'Linux': [255, 128, 0], 'Mac OS X': [0, 255, 255], 'Nokia': [255, 0, 255], 'PlayStation': [192, 192, 192], 'RIM Tablet OS': [64, 64, 64], 'Unix': [255, 255, 0], 'Wii': [192, 192, 192], 'Windows Phone': [0, 0, 128], // has to be before 'Windows' 'Windows': [0, 0, 255] }, browser: { 'Camino': [192, 192, 192], 'Chrome Frame': [255, 255, 0], // has to be before 'Chrome' 'Chrome': [0, 255, 0], 'Chromium': [128, 255, 0], 'Epiphany': [128, 128, 128], 'Firefox': [255, 128, 0], 'Internet Explorer': [0, 0, 255], 'Konqueror': [64, 64, 64], 'Nokia Browser': [255, 0, 255], 'Opera': [255, 0, 0], 'Safari': [0, 255, 255], 'WebKit': [0, 255, 128] } }, dialogHeight = Math.round((window.innerHeight - 48) * 0.9), dialogWidth = Math.round(window.innerWidth * 0.9), tabs = [ {id: 'seen', title: Ox._('First Seen & Last Seen'), selected: true}, {id: 'locations', title: Ox._('Locations')}, {id: 'platforms', title: Ox._('Platforms & Browsers')} ], $dialog = Ox.Dialog({ buttons: [ Ox.Button({ id: 'manageUsers', title: Ox._('Manage Users...') }).bindEvent({ click: function() { $dialog.close(); pandora.$ui.usersDialog = pandora.ui.usersDialog().open(); } }), {}, Ox.Button({ id: 'close', title: Ox._('Close') }).bindEvent({ click: function() { $dialog.close(); } }) ], closeButton: true, content: Ox.LoadingScreen().start(), height: dialogHeight, maximizeButton: true, minHeight: 256, minWidth: 512, removeOnClose: true, title: Ox._('Statistics'), width: dialogWidth }) .bindEvent({ resizeend: function(data) { dialogWidth = data.width; $tabPanel.reloadPanel(); } }), $tabPanel; pandora.api.statistics(function(result) { var data = result.data, flagCountry = {}, $guestsCheckbox; ['all', 'registered'].forEach(function(mode) { var keys, firstKey, lastKey; keys = Object.keys(data[mode].month).map(function(key) { return key.slice(0, 7); }).sort(); firstKey = keys[0].split('-').map(function(str) { return parseInt(str, 10); }); lastKey = Ox.formatDate(new Date(), '%F').split('-').map(function(str) { return parseInt(str, 10); }); Ox.loop(firstKey[0], lastKey[0] + 1, function(year) { ['firstseen', 'lastseen'].forEach(function(key) { var key = [year, key].join('-'); data[mode].year[key] = data[mode].year[key] || {}; }); Ox.loop( year == firstKey[0] ? firstKey[1] : 1, year == lastKey[0] ? lastKey[1] + 1 : 13, function(month) { ['firstseen', 'lastseen'].forEach(function(key) { var key = [year, Ox.pad(month, 2), key].join('-'); data[mode].month[key] = data[mode].month[key] || 0; }); } ); }); keys = Object.keys(data[mode].day).sort(); firstKey = keys[0].split('-').map(function(str) { return parseInt(str, 10); }); Ox.loop(firstKey[0], lastKey[0] + 1, function(year) { Ox.loop( year == firstKey[0] ? firstKey[1] : 1, year == lastKey[0] ? lastKey[1] + 1 : 13, function(month) { Ox.loop( year == firstKey[0] && month == firstKey[1] ? firstKey[2] : 1, year == lastKey[0] && month == lastKey[1] ? lastKey[2] + 1 : Ox.getDaysInMonth(year, month) + 1, function(day) { var key = [year, Ox.pad(month, 2), Ox.pad(day, 2)].join('-'); data[mode].day[key] = data[mode].day[key] || {}; } ); } ); }); flagCountry[mode] = {}; ['continent', 'region'].forEach(function(key) { flagCountry[mode][key] = {}; Ox.forEach(data[mode][key], function(regionValue, regionKey) { regionKey = regionKey.split(', ').pop(); var max = 0; Ox.forEach(data[mode].country, function(countryValue, countryKey) { countryKey = countryKey.split(', ').pop(); if ( (Ox.getCountryByName(countryKey) || {})[key] == regionKey && countryValue > max ) { flagCountry[mode][key][regionKey] = countryKey; max = countryValue; } }); }); }); }); $guestsCheckbox = Ox.Checkbox({ title: Ox._('Include Guests'), value: false }) .css({float: 'left', margin: '4px'}) .bindEvent({ change: function() { $tabPanel.reloadPanel(); } }); $tabPanel = Ox.TabPanel({ content: function(id) { var chartWidth = dialogWidth - 32 - Ox.UI.SCROLLBAR_SIZE, mode = $guestsCheckbox.options('value') ? 'all' : 'registered', top = 16, $content = Ox.Element() .css({ padding: '16px', overflowY: 'auto', background: pandora.user.ui.theme == 'oxlight' ? 'rgb(240, 240, 240)' : pandora.user.ui.theme == 'oxmedium' ? 'rgb(160, 160, 160)' : 'rgb(16, 16, 16)' }); if (id == 'seen') { ['year', 'month', 'lastdays', 'topdays', 'weekday', 'hour'].forEach(function(key) { var isDate = ['year', 'month'].indexOf(key) > -1, isDay = ['lastdays', 'topdays'].indexOf(key) > -1; Ox.Chart({ color: function(value) { var split = value.split('-'), color = isDate ? Ox.rgb( Ox.mod(8 - parseInt(split[1], 10), 12) * 30, 1, 0.5 ) : Ox.rgb( (Math.abs(11.5 - parseInt(split[0], 10)) - 0.5) * -11, 1, 0.5 ); if (pandora.user.ui.theme == 'oxlight') { color = getColor(color); } return color; }, data: data[mode][isDay ? 'day' : key], formatKey: function(value) { var ret, split; if (isDate) { split = value.split('-'); ret = (split.pop() == 'firstseen' ? 'First' : 'Last') + ': ' + (key == 'year' ? '' : Ox.MONTHS[parseInt(split[1], 10) - 1]) + ' ' + split[0]; } else if (isDay) { split = value.split('-'); ret = Ox.SHORT_WEEKDAYS[parseInt(Ox.formatDate(value, '%u')) - 1] + ', ' + Ox.SHORT_MONTHS[parseInt(split[1], 10) - 1] + ' ' + parseInt(split[2], 10) + ', ' + split[0]; } else { ret = key == 'weekday' ? Ox.WEEKDAYS[parseInt(value, 10) - 1] : value + ':00'; } return ret; }, keyAlign: 'right', keyWidth: 128, limit: isDay ? 30 : 0, rows: isDate ? 2 : 1, sort: { key: key == 'topdays' ? 'value' : 'key', operator: isDate || isDay ? '-' : '+' }, title: key == 'lastdays' ? Ox._('Last 30 Days') : key == 'topdays' ? Ox._('Top 30 Days') : Ox._(Ox.toTitleCase(key) + 's'), width: chartWidth }) .css({ position: 'absolute', left: '16px', top: top + 'px' }) .appendTo($content); top += (isDay ? Math.min(Ox.len(data[mode].day), 30) : Ox.len(data[mode][key])) * 16 + 32; }); } else if (id == 'locations') { ['continent', 'region', 'country', 'city'].forEach(function(key) { Ox.Chart({ color: function(value) { var color = Ox.getGeoColor( key == 'continent' ? value : value.split(', ')[1] ); if (pandora.user.ui.theme == 'oxlight') { color = getColor(color); } return color; }, data: data[mode][key], formatKey: function(value) { var city, country, split = value.split(', '); if (key == 'continent' || key == 'region') { country = flagCountry[mode][key][Ox.last(split)]; } else { country = split[2]; city = key == 'city' ? split[3] : '' } return $('