Permalink
Browse files

Added 'At this growth rate, you'll have X followers in Y weeks' to fo…

…llower count graphs

On Main Dashboard and Follower Count page
  • Loading branch information...
ginatrapani committed Mar 16, 2011
1 parent 8ca135c commit 4efa0c69aefdc3c6ef7e46f95db4078c51256380
@@ -69,7 +69,8 @@ public function testGetDayHistoryNoGaps() {
$dao = new FollowerCountMySQLDAO();
$result = $dao->getHistory(930061, 'twitter', 'DAY', 3);
- $this->assertEqual(sizeof($result), 4, '4 sets of data returned--history, percentages, Y axis, trend');
+ $this->assertEqual(sizeof($result), 5, '5 sets of data returned--history, percentages, Y axis, trend, '.
+ 'milestone');
$this->debug(Utils::varDumpToString($result));
//check history
@@ -100,6 +101,96 @@ public function testGetDayHistoryNoGaps() {
//check trend
$this->assertEqual($result['trend'], 7);
+
+ //check milestone
+ //latest follower count is 140, next milestone is 1,000 followers
+ //with a 7+/day trend, this should take 123 days
+ $this->assertEqual($result['milestone']['next_milestone'], 1000);
+ $this->assertEqual($result['milestone']['will_take'], 123);
+ $this->assertEqual($result['milestone']['units_of_time'], 'DAY');
+ }
+
+ public function testGetDayHistoryWeekNoGaps() {
+ $format = 'n/j';
+ $date = date ( $format );
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-1d', 'count'=>140);
+ $builder1 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-2d', 'count'=>139);
+ $builder2 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-3d', 'count'=>138);
+ $builder3 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-4d', 'count'=>137);
+ $builder4 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-5d', 'count'=>136);
+ $builder5 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-6d', 'count'=>135);
+ $builder6 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-7d', 'count'=>134);
+ $builder7 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-8d', 'count'=>133);
+ $builder8 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-9d', 'count'=>132);
+ $builder9 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-10d', 'count'=>131);
+ $builder10 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-11d', 'count'=>130);
+ $builder11 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-12d', 'count'=>129);
+ $builder12 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-13d', 'count'=>128);
+ $builder13 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-14d', 'count'=>127);
+ $builder14 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $dao = new FollowerCountMySQLDAO();
+ $result = $dao->getHistory(930061, 'twitter', 'WEEK', 3);
+ $this->assertEqual(sizeof($result), 5, '5 sets of data returned--history, percentages, Y axis, trend, '.
+ 'milestone');
+
+ $this->debug(Utils::varDumpToString($result));
+ //check history
+ $this->assertEqual(sizeof($result['history']), 3, '3 counts returned');
+
+ $date_ago = date ($format, strtotime('-1 day'.$date));
+ $this->assertEqual($result['history'][$date_ago], 140);
+
+ //check percentages
+ $this->assertEqual(sizeof($result['percentages']), 3, '3 percentages returned');
+ $this->assertEqual($result['percentages'][0], 0);
+ $this->assertEqual($result['percentages'][1], 78);
+ $this->assertEqual($result['percentages'][2], 100);
+
+ //check Y-axis
+ $this->assertEqual(sizeof($result['y_axis']), 5, '5 Y axis points returned');
+ $this->assertEqual($result['y_axis'][0], 131);
+ $this->assertEqual($result['y_axis'][1], 133.25);
+ $this->assertEqual($result['y_axis'][2], 135.5);
+ $this->assertEqual($result['y_axis'][3], 137.75);
+ $this->assertEqual($result['y_axis'][4], 140);
+
+ //check trend
+ $this->assertEqual($result['trend'], 3);
+
+ //check milestone
+ //latest follower count is 140, next milestone is 1,000 followers
+ //with a 7+/day trend, this should take 123 days
+ $this->assertEqual($result['milestone']['next_milestone'], 1000);
+ $this->assertEqual($result['milestone']['will_take'], 287);
+ $this->assertEqual($result['milestone']['units_of_time'], 'WEEK');
}
public function testGetDayHistoryWithGaps() {
@@ -117,7 +208,8 @@ public function testGetDayHistoryWithGaps() {
$dao = new FollowerCountMySQLDAO();
$result = $dao->getHistory(930061, 'twitter', 'DAY', 5);
- $this->assertEqual(sizeof($result), 4, '4 sets of data returned--history, percentages, Y axis, trend');
+ $this->assertEqual(sizeof($result), 5, '5 sets of data returned--history, percentages, Y axis, trend, '.
+ 'milestone');
//check history
$this->assertEqual(sizeof($result['history']), 5, '5 counts returned');
@@ -157,5 +249,70 @@ public function testGetDayHistoryWithGaps() {
//check trend
$this->assertFalse($result['trend']);
+
+ //check milestone
+ $this->assertFalse($result['milestone']);
+ }
+
+ public function testTrendMillionPlusFollowers() {
+ $format = 'n/j';
+ $date = date ( $format );
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-1d', 'count'=>1772643);
+ $builder1 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-2d', 'count'=>1771684);
+ $builder2 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-3d', 'count'=>1771500);
+ $builder3 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-4d', 'count'=>1761500);
+ $builder4 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $dao = new FollowerCountMySQLDAO();
+ $result = $dao->getHistory(930061, 'twitter', 'DAY', 4);
+ $this->assertEqual(sizeof($result), 5, '5 sets of data returned--history, percentages, Y axis, trend, '.
+ 'milestone');
+
+ $this->debug(Utils::varDumpToString($result));
+
+ //check milestone
+ //latest follower count is 1.7M, next milestone is 2M
+ //with a 2786+/day trend, this should take 82 days
+ $this->assertEqual($result['milestone']['next_milestone'], 2000000);
+ $this->assertEqual($result['milestone']['will_take'], 82);
+ $this->assertEqual($result['milestone']['units_of_time'], 'DAY');
+ }
+
+ public function testTrendMillionPlusFollowers2() {
+ $format = 'n/j';
+ $date = date ( $format );
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-1d', 'count'=>1272643);
+ $builder1 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-2d', 'count'=>1271684);
+ $builder2 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-3d', 'count'=>1271500);
+ $builder3 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $follower_count = array('network_user_id'=>930061, 'network'=>'twitter', 'date'=>'-4d', 'count'=>1261500);
+ $builder4 = FixtureBuilder::build('follower_count', $follower_count);
+
+ $dao = new FollowerCountMySQLDAO();
+ $result = $dao->getHistory(930061, 'twitter', 'DAY', 4);
+ $this->assertEqual(sizeof($result), 5, '5 sets of data returned--history, percentages, Y axis, trend, '.
+ 'milestone');
+
+ $this->debug(Utils::varDumpToString($result));
+
+ //check milestone
+ //latest follower count is 1.7M, next milestone is 2M
+ //with a 2786+/day trend, this should take 82 days
+ $this->assertEqual($result['milestone']['next_milestone'], 1500000);
+ $this->assertEqual($result['milestone']['will_take'], 82);
+ $this->assertEqual($result['milestone']['units_of_time'], 'DAY');
}
}
@@ -42,19 +42,22 @@ public function insert($network_user_id, $network, $count){
return $this->getInsertCount($ps);
}
- public function getHistory($network_user_id, $network, $group_by, $limit=10) {
- if ($group_by != "DAY" && $group_by != 'WEEK' && $group_by != 'MONTH') {
- $group_by = 'DAY';
+ public function getHistory($network_user_id, $network, $units, $limit=10) {
+ if ($units != "DAY" && $units != 'WEEK' && $units != 'MONTH') {
+ $units = 'DAY';
}
- if ($group_by == 'DAY') {
+ $query_date_format = "%c/%e";
+ if ($units == 'DAY') {
$group_by = 'fc.date';
- } else if ($group_by == 'WEEK') {
+ } else if ($units == 'WEEK') {
$group_by = 'YEAR(fc.date), WEEK(fc.date)';
- } else if ($group_by == 'MONTH') {
+ } else if ($units == 'MONTH') {
$group_by = 'YEAR(fc.date), MONTH(fc.date)';
+ $query_date_format = "%c/%Y";
}
$q = "SELECT network_user_id, network, count, date, full_date FROM ";
- $q .= "(SELECT network_user_id, network, count, DATE_FORMAT(date, '%c/%e') as date, date as full_date ";
+ $q .= "(SELECT network_user_id, network, count, DATE_FORMAT(date, '".$query_date_format.
+ "') as date, date as full_date ";
$q .= "FROM #prefix#follower_count AS fc ";
$q .= "WHERE fc.network_user_id = :network_user_id AND fc.network=:network ";
$q .= "GROUP BY ".$group_by." ORDER BY full_date DESC LIMIT :limit ) as history_counts ";
@@ -80,7 +83,7 @@ public function getHistory($network_user_id, $network, $group_by, $limit=10) {
$first_follower_count = reset($simplified_history);
$last_follower_count = end($simplified_history);
$trend = ($last_follower_count - $first_follower_count)/sizeof($simplified_history);
- $trend = round($trend);
+ $trend = intval(round($trend));
//complete data set
$history = $simplified_history;
} else { //there are dates with missing data
@@ -90,7 +93,13 @@ public function getHistory($network_user_id, $network, $group_by, $limit=10) {
$date = date ( $format );
$i = $limit;
while ($i > 0 ) {
- $date_ago = date ($format, strtotime('-'.$i.' day'.$date));
+ if ($units != "MONTH") {
+ $date_ago = date ($format, strtotime('-'.$i.' '.$units.$date));
+ } else {
+ $first_day_of_this_month = date('n/1');
+ $format = 'n/Y';
+ $date_ago = date ($format, strtotime('-'.$i.' '.$units.$first_day_of_this_month));
+ }
$dates_to_display[$date_ago] = "no data";
$i--;
}
@@ -126,12 +135,65 @@ public function getHistory($network_user_id, $network, $group_by, $limit=10) {
$i = $i+1;
}
$y_axis[$num_y_axis_points] = $max_count;
+ $milestone = $this->predictNextMilestoneDate(intval($history_rows[sizeof($history_rows)-1]['count']),
+ $trend);
+ if (isset($milestone)) {
+ $milestone['units_of_time'] = $units;
+ }
} else {
$history = false;
$y_axis = false;
$trend = false;
$percentages = false;
+ $milestone = false;
+ }
+ return array('history'=>$history, 'percentages'=>$percentages, 'y_axis'=>$y_axis, 'trend'=>$trend,
+ 'milestone'=> $milestone);
+ }
+
+ /**
+ * Calculate the number of time units it will take to reach the next follower count milestone given
+ * an upward trend.
+ * @param int $follower_count
+ * @param int $trend
+ * @return array 'next_milestone'=> int, 'will_take'=>int
+ */
+ private function predictNextMilestoneDate($follower_count, $trend) {
+ if ($trend > 0 ) {
+ $milestones = array(
+ 1000000,
+ 750000,
+ 500000,
+ 300000,
+ 250000,
+ 200000,
+ 150000,
+ 100000,
+ 50000,
+ 25000,
+ 10000,
+ 5000,
+ 1000
+ );
+
+ $goal_count = 0;
+ foreach ($milestones as $milestone) {
+ if ($follower_count < $milestone) {
+ $goal_count = $milestone;
+ }
+ }
+ if ($goal_count == 0) { //follower count is over a million
+ $float_val = $follower_count/10000000;
+ $goal_count = round($float_val, 1);
+ $goal_count = $goal_count * 10000000;
+ if ($follower_count > $goal_count) {
+ $goal_count = $goal_count + 500000;
+ }
+ }
+ $prediction = intval(round(($goal_count - $follower_count)/$trend));
+ return array('next_milestone'=>$goal_count, 'will_take'=>$prediction);
+ } else {
+ return null;
}
- return array('history'=>$history, 'percentages'=>$percentages, 'y_axis'=>$y_axis, 'trend'=>$trend);
}
}
@@ -76,14 +76,18 @@
{/foreach}
{/if}
- <div style="float : left; padding-right : 20px;">
+ <div style="float : left; padding-right : 20px;">
<h2>Follower Count By Day{if !$follower_count_history_by_day.history OR $follower_count_history_by_day.history|@count < 2}<br /><i>Not enough data to display chart</i>{else} {if $follower_count_history_by_day.trend}({if $follower_count_history_by_day.trend > 0}<span style="color:green">+{else}<span style="color:red">{/if}{$follower_count_history_by_day.trend|number_format}</span>/day){/if}</h2>
<img width="360" height="200" src="http://chart.apis.google.com/chart?chs=360x200&chxt=x,y&chxl=0:|{foreach from=$follower_count_history_by_day.history key=tid item=t name=foo}{$tid}{if $t eq "no data"} (no data){/if}|{/foreach}1:|{foreach from=$follower_count_history_by_day.y_axis key=tid item=t name=foo}{$t|number_format}{if !$smarty.foreach.foo.last}|{/if}{/foreach}&cht=ls&chco=007733&chd=t:{foreach from=$follower_count_history_by_day.percentages key=tid item=t name=foo}{$t}{if !$smarty.foreach.foo.last},{/if}{/foreach}&chm=B,cccccc,0,0,0" />
{/if}
</div>
<h2>Follower Count By Week{if !$follower_count_history_by_week.history OR $follower_count_history_by_week.history|@count < 2}<br /><i>Not enough data to display chart</i><br clear="all"/>{else} {if $follower_count_history_by_week.trend != 0}({if $follower_count_history_by_week.trend > 0}<span style="color:green">+{else}<span style="color:red">{/if}{$follower_count_history_by_week.trend|number_format}</span>/week){/if}</h2>
<img width="360" height="200" src="http://chart.apis.google.com/chart?chs=360x200&chxt=x,y&chxl=0:|{foreach from=$follower_count_history_by_week.history key=tid item=t name=foo}{if $t eq "no data"}no data{else}{$tid}{/if}|{/foreach}1:|{foreach from=$follower_count_history_by_week.y_axis key=tid item=t name=foo}{$t|number_format}{if !$smarty.foreach.foo.last}|{/if}{/foreach}&cht=ls&chco=007733&chd=t:{foreach from=$follower_count_history_by_week.percentages key=tid item=t name=foo}{$t}{if !$smarty.foreach.foo.last},{/if}{/foreach}&chm=B,cccccc,0,0,0" />
+{if $follower_count_history_by_week.milestone}
+<br /><small style="color:gray">NEXT MILESTONE: <span style="background-color:#FFFF80;color:black">{$follower_count_history_by_week.milestone.will_take} weeks</span> till you reach <span style="background-color:#FFFF80;color:black">{$follower_count_history_by_week.milestone.next_milestone|number_format} followers</span> at this rate.
+<a href="{$site_root_path}index.php?v=followers-history&u={$instance->network_username}&n={$instance->network}">More...</a></small>
+{/if}
{/if}
<br />
@@ -92,9 +96,14 @@
<h2 >Most Discerning Followers</h2>
{foreach from=$least_likely_followers key=uid item=u name=foo}
<div class="avatar-container" style="float:left;margin:7px;">
+ {if !$smarty.foreach.foo.last}
<a href="http://twitter.com/{$u.user_name}" title="{$u.user_name}"><img src="{$u.avatar}" class="avatar2"/><img src="{$site_root_path}plugins/{$u.network}/assets/img/favicon.ico" class="service-icon2"/></a>
- </div>
+ {else}
+ <br /><a href="{$site_root_path}index.php?v=followers-leastlikely&u={$instance->network_username}&n={$instance->network}">More...</a>
+ {/if}
+ </div>
{/foreach}
+
<div style="clear:all;"><br /><br /><br /></div>
{/if}
@@ -270,7 +270,7 @@ public function getDashboardMenuItems($instance) {
array($instance->network_user_id, 'twitter', 'WEEK', 15));
$trendtab->addDataset($trendtabweekds);
$trendtabmonthds = new Dataset("follower_count_history_by_month", 'FollowerCountDAO', 'getHistory',
- array($instance->network_user_id, 'twitter', 'MONTH', 15));
+ array($instance->network_user_id, 'twitter', 'MONTH', 11));
$trendtab->addDataset($trendtabmonthds);
$menus['followers-history'] = $trendtab;
Oops, something went wrong.

0 comments on commit 4efa0c6

Please sign in to comment.