Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Messy commit: more summary info. Added map. Make everything "monthly"…

… (affects: followers/following/hosts)
  • Loading branch information...
commit d8a6e9badf8bfdf85df789424dd62b45145ec754 1 parent 83cd138
Chimo authored
2  SocialAnalyticsPlugin.php
View
@@ -171,7 +171,7 @@ function onEndPersonalGroupNav($action)
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'Social Analytics',
- 'version' => '0.1.1',
+ 'version' => '0.2.0',
'author' => 'Stéphane Bérubé',
'homepage' => 'http://status.net/wiki/Plugin:SocialAnalytics',
'rawdescription' =>
40 Social_analytics.php
View
@@ -57,23 +57,26 @@ class Social_analytics extends Memcached_DataObject
/**
* TODO: Document
*/
- static function init($user_id, $target_month=NULL)
+ static function init($user_id, $target_month=NULL, $edate=NULL)
{
$sa = new Social_analytics();
+
$sa->user_id = $user_id;
$sa->month = (!$target_month) ? new DateTime('first day of this month') : new DateTime($target_month . '-01');
$sa->ttl_notices = 0;
+ $sa->ttl_replies = 0;
// The list of graphs we'll be generating
$sa->graphs = array(
'trends' => array(),
- 'hosts_you_are_following' => array(),
- 'hosts_who_follow_you' => array(),
+ 'hosts_you_started_to_follow' => array(),
+ 'hosts_who_started_to_follow_you' => array(),
'clients' => array(),
'people_you_replied_to' => array(),
'people_who_mentioned_you' => array()
);
+ $sa->map = array();
// Initialize 'trends' table. We do this now since we know which rows we need in advance (all non-future days of month)
$i_date = clone($sa->month);
@@ -102,6 +105,7 @@ static function init($user_id, $target_month=NULL)
$reply_to = Notice::staticGet('id', $notice->reply_to);
$repliee = Profile::staticGet('id', $reply_to->profile_id);
$sa->graphs['people_you_replied_to'][$repliee->nickname]++;
+ $sa->ttl_replies++;
}
$sa->graphs['trends'][$date_created->format('Y-m-d')]['notices']++;
@@ -140,6 +144,7 @@ static function init($user_id, $target_month=NULL)
}
}
+
// Hosts you are following
$sa->ttl_following = 0;
$arr_following = Memcached_DataObject::listGet('Subscription', 'subscriber', array($user_id));
@@ -155,13 +160,19 @@ static function init($user_id, $target_month=NULL)
$sa->graphs['trends'][$date_created->format('Y-m-d')]['following']++;
$profile = Profile::staticGet('id', $following->subscribed);
- $sa->graphs['hosts_you_are_following'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
+ if(!is_null($profile->lat) && !is_null($profile->lon)) {
+ $sa->map['following'][$profile->nickname] = array('lat' => $profile->lat, 'lon' => $profile->lon);
+ }
+
+ $sa->graphs['hosts_you_started_to_follow'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
$sa->ttl_following++;
}
- elseif($date_created->format('Y-m') < $sa->month->format('Y-m')) {
+ // TODO: Commented because it isn't 'monthly'. Should go with 'all times' graphs. Blocked by #1
+ /* elseif($date_created->format('Y-m') < $sa->month->format('Y-m')) {
$profile = Profile::staticGet('id', $following->subscribed);
- $sa->graphs['hosts_you_are_following'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
- }
+ $sa->graphs['hosts_you_started_to_follow'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
+ $sa->ttl_following++;
+ } */
}
// Hosts who follow you
@@ -179,15 +190,22 @@ static function init($user_id, $target_month=NULL)
$sa->graphs['trends'][$date_created->format('Y-m-d')]['followers']++;
$profile = Profile::staticGet('id', $follower->subscriber);
- $sa->graphs['hosts_who_follow_you'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
+ if(!is_null($profile->lat) && !is_null($profile->lon)) {
+ $sa->map['followers'][$profile->nickname] = array('lat' => $profile->lat, 'lon' => $profile->lon);
+ }
+
+ $sa->graphs['hosts_who_started_to_follow_you'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
$sa->ttl_followers++;
}
- elseif($date_created->format('Y-m') < $sa->month->format('Y-m')) {
+ // TODO: Commented because it isn't 'monthly'. Should go with 'all times' graphs. Blocked by #1
+ /* elseif($date_created->format('Y-m') < $sa->month->format('Y-m')) {
$profile = Profile::staticGet('id', $follower->subscriber);
- $sa->graphs['hosts_who_follow_you'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
- }
+ $sa->graphs['hosts_who_started_to_follow_you'][parse_url($profile->profileurl, PHP_URL_HOST)]++;
+ $sa->ttl_followers++;
+ } */
}
+// TODO: Commented because it isn't 'monthly'. Should go with 'all times' graphs. Blocked by #1
/* foreach($sa->graphs['trends'] as &$day) {
$day['followers'] += $ttl_followers;
$ttl_followers = $day['followers'];
22 js/visualize.jQuery.js
View
@@ -485,11 +485,11 @@ $(document).ready(function(){
$(this).wrapInner($link);
});
- $('.hosts_you_are_following_table').visualize({type: 'pie', width: 700, height: 300, colors: ['#00A0B0','#6A4A3C','#CC333F','#EB6841','#EDC951','#CFF09E','#79BD9A','#0B486B','#000000','#40434A','red','blue','green']})
- .appendTo('.hosts_you_are_following_graph');
+ $('.hosts_you_started_to_follow_table').visualize({type: 'pie', width: 700, height: 300, colors: ['#00A0B0','#6A4A3C','#CC333F','#EB6841','#EDC951','#CFF09E','#79BD9A','#0B486B','#000000','#40434A','red','blue','green']})
+ .appendTo('.hosts_you_started_to_follow_graph');
- $('.hosts_who_follow_you_table').visualize({type: 'pie', width: 700, height: 300, colors: ['#00A0B0','#6A4A3C','#CC333F','#EB6841','#EDC951','#CFF09E','#79BD9A','#0B486B','#000000','#40434A','red','blue','green']})
- .appendTo('.hosts_who_follow_you_graph');
+ $('.hosts_who_started_to_follow_you_table').visualize({type: 'pie', width: 700, height: 300, colors: ['#00A0B0','#6A4A3C','#CC333F','#EB6841','#EDC951','#CFF09E','#79BD9A','#0B486B','#000000','#40434A','red','blue','green']})
+ .appendTo('.hosts_who_started_to_follow_you_graph');
$('.clients_table').visualize({type: 'pie', width: 700, height: 300, colors: ['#00A0B0','#6A4A3C','#CC333F','#EB6841','#EDC951','#CFF09E','#79BD9A','#0B486B','#000000','#40434A','red','blue','green']})
.appendTo('.clients_graph');
@@ -512,4 +512,18 @@ $(document).ready(function(){
$(this).next('table').fadeToggle();
});
+ // Show/hide custom date form
+ $('.social_nav .cust a').click(function(e) {
+ e.preventDefault();
+ e.stopPropagation;
+ $('.social_date_picker').fadeToggle();
+ });
+
+ // Bind datepickers
+ $('#social_start_date, #social_end_date').datepicker({
+ showOn: "button",
+ buttonImage: "/plugins/SocialAnalytics/images/calendar.png", // FIXME: This won't work on instances installed in a subdir
+ buttonImageOnly: true,
+ maxDate: new Date()
+ });
});
96 social.php
View
@@ -66,7 +66,15 @@ function prepare($args)
$this->user = common_current_user();
- if (!empty($this->user)) {
+ // Custom date range
+ if($_REQUEST['sdate']) {
+ if(is_null($_REQUEST['edate'])) { // If only a start date was provided, make 'end date' today's date.
+ $edate = new DateTime();
+ $edate = $edate->format('Y-m-d');
+ }
+ $this->sa = Social_analytics::init($this->user->id, $_REQUEST['sdate'], $edate);
+ }
+ else { // Monthly view
$this->sa = Social_analytics::init($this->user->id, $_REQUEST['month']);
}
@@ -108,11 +116,30 @@ function printNavigation($current_month) {
$month = clone($current_month);
$url = common_local_url('social');
+ // Prev month
$this->elementStart('ul', array('class' => 'social_nav'));
$this->elementStart('li', array('class' => 'prev'));
$this->element('a', array('href' => $url . '?month=' . $month->modify('-1 month')->format('Y-m')), _m('Previous Month'));
$this->elementEnd('li');
+ // Custom date range link
+/* $this->elementStart('li', array('class' => 'cust'));
+ $this->element('a', array('href' => '#'), 'Custom date range');
+
+ // Custom date range datepickers
+ $this->elementStart('form', array('class' => 'social_date_picker', 'method' => 'get', 'action' => $url));
+ $this->elementStart('fieldset');
+ $this->element('label', array('for' => 'social_start_date'), 'Start date:');
+ $this->element('input', array('id' => 'social_start_date', 'name' => 'sdate'));
+ $this->element('br');
+ $this->element('label', array('for' => 'social_end_date'), 'End date:');
+ $this->element('input', array('id' => 'social_end_date', 'name' => 'edate'));
+ $this->element('input', array('type' => 'submit', 'id' => 'social_submit_date'));
+ $this->elementEnd('fieldset');
+ $this->elementEnd('form');
+
+ $this->elementEnd('li'); */
+
// Don't generate a 'next' link if the next month is in the future
$today = new DateTime();
if($today >= $month->modify('+2 month')) {
@@ -124,6 +151,10 @@ function printNavigation($current_month) {
}
function printGraph($name, $rows) {
+ if(count($rows) <= 1) { // Skip empty tables
+ return;
+ }
+
// Title
$this->element('h3', null, ucfirst(str_replace('_', ' ', _m($name))));
@@ -239,9 +270,13 @@ function showContent()
$this->elementEnd('li');
$this->elementStart('li');
- $this->text('were mentioned ' . $this->sa->ttl_mentions . ' times');
+ $this->text('were mentioned ' . $this->sa->ttl_mentions . ' times, by ' . count($this->sa->graphs['people_who_mentioned_you']) . ' different people');
$this->elementEnd('li');
+ $this->elementStart('li');
+ $this->text('replied to ' . count($this->sa->graphs['people_you_replied_to']) . ' people, for a total of ' . $this->sa->ttl_replies . ' replies');
+ $this->elementEnd('li');
+
$this->elementEnd('ul');
// Graphs
@@ -249,10 +284,67 @@ function showContent()
$this->printGraph($title, $graph);
}
+ // If we have map data
+ if(count($this->sa->map['following'])) {
+ // Print Map title
+ $this->element('h3', null, 'Location of new subscriptions');
+ $this->element('p', null, 'Blue: you started following, red: started to follow you');
+
+ // Print map
+ $this->element('div', array('id' => 'mapdiv'));
+ $this->script('http://www.openlayers.org/api/OpenLayers.js');
+ $this->inlineScript('
+ map = new OpenLayers.Map("mapdiv");
+ map.addLayer(new OpenLayers.Layer.OSM());
+ var zoom=2;
+
+ var markers = new OpenLayers.Layer.Markers( "Markers" );
+ map.addLayer(markers);
+
+ var coords = ' . $this->getCoords('following') . '
+ for(var i=0; i<coords.length; i++) {
+ var lonLat = new OpenLayers.LonLat( coords[i].lon, coords[i].lat )
+ .transform(
+ new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
+ map.getProjectionObject() // to Spherical Mercator Projection
+ );
+ markers.addMarker(new OpenLayers.Marker(lonLat));
+ }
+
+ var size = new OpenLayers.Size(21,25);
+ var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
+ var icon = new OpenLayers.Icon("http://www.openlayers.org/dev/img/marker-blue.png", size, offset);
+
+ var coords = ' . $this->getCoords('followers') . '
+ for(var i=0; i<coords.length; i++) {
+ var lonLat = new OpenLayers.LonLat( coords[i].lon, coords[i].lat )
+ .transform(
+ new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
+ map.getProjectionObject() // to Spherical Mercator Projection
+ );
+ markers.addMarker(new OpenLayers.Marker(lonLat, icon.clone()));
+ }
+
+ map.setCenter (lonLat, zoom);
+ ');
+ }
+
// Navigation
$this->printNavigation($this->sa->month);
}
+ function getCoords($name) {
+ $markers = '[';
+
+ // FIXME: Just store this in JS notation in $this->sa->map['following']['nickname'] to being with
+ foreach($this->sa->map[$name] as $nickname => $coords) {
+ $markers .= '{ lon: "' . $coords['lon'] . '", lat: "' . $coords['lat'] . '"},';
+ }
+
+ $markers = rtrim($markers, ',');
+ return $markers . ']';
+ }
+
/**
* Return true if read only.
*
41 visualize-light.css
View
@@ -1,35 +1,46 @@
-/* page styles */
-/*body { font-size:62.5%; }
-
-/*demo styles*/
-/* table.social_stats {width: 500px; height: 200px; margin-left: 30px; }
-table.accessHide { position: absolute; left: -999999px; }
-table.social_stats td, table.social_stats th { padding: 2px; width: 13%; }
-table.social_stats th { background-color:#f4f4f4; } */
-
.visualize-labels-x {display: none;}
body .visualize {margin: 0 30px 10px 30px; padding: 0;}
.social_table {width: 100%; display: none;}
.social_table, .social_table th, .social_table td {border: 1px solid #333;}
.social_table th, .social_table td {padding: 3px;}
.social_table td {text-align: right;}
-.social_nav {margin-bottom: 5px; padding: 0; list-style-type: none; overflow: hidden;}
-.social_nav .prev {float: left;}
-.social_nav .next {float: right;}
+
+/* Date picker form */
+.social_date_picker {display: none; position: absolute; top: 100%; left: 0; text-align: left; border: 1px solid #000; border-radius: 5px; padding: 10px; margin-top: 5px;}
+#social_start_date, #social_end_date {margin-bottom: 5px;}
+#social_submit_date {margin: auto; display: block;}
+#social .ui-datepicker-trigger {margin-left: 5px;}
+/* /Date picker */
+
+/* Date Navitation */
+.social_nav {margin-bottom: 5px; padding: 0; list-style-type: none; height: 22px;}
+.social_nav .prev {float: left; width: 33%;}
+.social_nav .cust {float: left; text-align: center; width: 33%; position: relative;}
+.social_nav .next {float: right; text-align: right; width: 33%;}
.social_nav a {
- background-image: url("/theme/base/images/icons/icons-01.gif");
+ background-image: url(/theme/base/images/icons/icons-01.gif);
background-repeat: no-repeat;
padding-top: 9px;
-
}
.social_nav .next a {
- background-position: 115% -253px;
+ background-position: 114% -253px;
padding-right: 25px;
}
+.social_nav .cust a {background: none;}
.social_nav .prev a {
background-position: 0 -188px;
padding-left: 25px;
}
+/* /Date Navigation */
+
+/* Map */
+#mapdiv {
+ height: 300px;
+ margin: 0 30px 12px 30px !important;
+ width: 700px;
+}
+div.olControlAttribution {bottom: 0;}
+/* /Map */
div.social_graph ul.visualize-key li {float: none;}
div.trends_graph ul.visualize-key li {float: left;}
1  visualize.css
View
@@ -1,6 +1,5 @@
/* SocialAnalytics additons */
#social #content {width: 758px;}
-/*#social #content h1 {display: none;}*/
#social #content_wrapper {border-right: none;}
#social #aside_primary {display: none;}
#social #aside_primary_wrapper {background-color: #FFF;}
Please sign in to comment.
Something went wrong with that request. Please try again.