Simple Machines Community Forum

Simple Machines => SMF Developers' Blog => Topic started by: Thantos on November 16, 2007, 01:41:59 PM

Title: SMF Growth
Post by: Thantos on November 16, 2007, 01:41:59 PM
I started playing around with JPGraph the other day and decided to create a few graphs the shows the growth of the Community Forum as well as our bug reporting and closing rates.

The first graph is the number of new topics and posts per month.  Posts are in blue and uses the left scale while topics are in red and uses the right scale.  Releases are denoted by vertical lines with important ones being purple.
(https://www.simplemachines.org/images/PostTopics.png) (http://www.simplemachines.org/images/PostTopics.png)
One thing to note is that some of the releases were done towards the end of a month so the spike might actually occur in the month after.

The second graph is the number of bugs opened in a given month and the number of bugs that were resolved or closed in that month.
(https://www.simplemachines.org/images/BugReport.png) (http://www.simplemachines.org/images/BugReport.png)
I'm not sure what caused the February spike.  The August spike was caused by the release of 2.0 Beta 1.

I hope to see some spikes after the MotM :P
Title: Re: SMF Growth
Post by: Deaks on November 18, 2007, 06:34:46 AM
what about during?
Title: Re: SMF Growth
Post by: Aaron on November 18, 2007, 06:36:16 AM
It would be interesting to see a lines of code-graph as well. :)
Title: Re: SMF Growth
Post by: H on November 19, 2007, 05:29:40 PM
Quote from: Aäron on November 18, 2007, 06:36:16 AM
It would be interesting to see a lines of code-graph as well. :)

There is one in CVS. Seems to be a little outdated though. Perhaps there is a cron that hasn't run
Title: Re: SMF Growth
Post by: Thantos on November 19, 2007, 08:07:46 PM
Actually I just updated that graph a couple days ago.
Title: Re: SMF Growth
Post by: H on November 20, 2007, 01:04:16 PM
My mistake. Saw the date and assumed it was old. Realise now that is just hasn't reached the next 'dateline'
Title: Re: SMF Growth
Post by: Thantos on November 20, 2007, 01:18:08 PM
I was confused the first time also.  Took me a bit to realize it was in DD/MM/YY format.
Title: Re: SMF Growth
Post by: Gary on November 20, 2007, 10:24:34 PM
Its about time something uses that format. :P

Anyway, some intresting graphs.
Title: Re: SMF Growth
Post by: Daniel15 on December 26, 2007, 01:54:39 AM
Nice graphs, Thantos :D
Any chance you could post the code you used (I know you used JPGraph, but your code you used for these graphs)? :D

I was going to run StatSVN (http://www.statsvn.org/) on the SVN repository to get a nice lines of code graph (among other useful statistics), but I guess it would take way too long to run :P
Examples:
http://entercalc.us.to/svnstats/
http://smfshop.dev.dansoftaustralia.net/stats/
:)

Quote from: Thantos on November 20, 2007, 01:18:08 PM
I was confused the first time also.  Took me a bit to realize it was in DD/MM/YY format.
Confused? That's a perfectly normal date format. :D
I mean, seriously, MM/DD/YYYY makes no sense whatsoever. :P
Title: Re: SMF Growth
Post by: Thantos on December 26, 2007, 10:24:37 AM
Quote from: Daniel15 on December 26, 2007, 01:54:39 AM
Nice graphs, Thantos :D
Any chance you could post the code you used (I know you used JPGraph, but your code you used for these graphs)? :D

Here is the code for the number of posts and topics.  The other graph follows a similar method.
<?php
require ("graph/jpgraph.php");
require (
"graph/jpgraph_line.php");
require (
'../community/SSI.php');

$graphfile 'graphs/PostTopics.png';

$releases = array(
'2007-09' => 'SMF 1.1.4 , 1.0.12',
'2007-06' => 'SMF 1.1.3 , 1.0.11',
'2007-02' => 'SMF 1.1.2',
'2006-10' => 'SMF 1.0.9, patch 1.1 RC3',
'2006-08' => 'SMF 1.0.8, 1.1 RC3',
'2006-03' => 'SMF 1.0.7, patch 1.1 RC2',
'2005-12' => 'SMF 1.1 RC2',
'2006-01' => 'SMF 1.0.6',
'2005-05' => 'SMF 1.1 Beta 2',
'2005-06' => 'SMF 1.0.4, 1.0.5, 1.1 Beta 3',
'2005-09' => 'SMF 1.1 RC1',
'2005-02' => 'SMF 1.0.2',
'2005-01' => 'SMF 1.0.1',
'2004-10' => 'SMF 1.0 RC2',
'2004-08' => 'SMF 1.0 RC1',
'2004-06' => 'SMF 1.0 Beta 6',
'2004-03' => 'SMF 1.0 Beta 4.1',
'2003-09' => 'SMF 1.0 Beta 1',
);

$major_releases = array(
'2007-08' => 'SMF 2.0 Beta 1',
'2006-12' => 'SMF 1.1, 1.0.10',
'2005-03' => 'SMF 1.0.3, SMF 1.1 Beta Charter',
'2004-12' => 'SMF 1.0 Final',
);

ksort($releases);
ksort($major_releases);

$result $smfFunc['db_query'](''"
SELECT date, posts, topics
FROM 
{$db_prefix}log_activity
ORDER BY date ASC"
__FILE____LINE__);

$data = array();
$topics = array();
$labels = array();

$months = array(=> 'January''February''March''April''May''June''July''August''September''October''November''December');

while (
$row $smfFunc['db_fetch_assoc']($result))
{
$datearr explode('-'$row['date']);
$date $datearr[0] . '-' $datearr[1];
$data[$date] += $row['posts'];
$topics[$date] += $row['topics'];
$labels[$date] = $months[(int)$datearr[1]] . ' ' $datearr[0];
}


$smfFunc['db_free_result']($result);

$vlines = array();
$i 0;

foreach(
$data AS $date => $dummy)
{
if (isset($releases[$date]))
{
$vline = new PlotLine(VERTICAL$i+0.5'green'1);
$labels[$date] = $releases[$date];
$vlines[] = $vline;
}
elseif(isset($major_releases[$date]))
{
$vline = new PlotLine(VERTICAL$i+0.5'purple'1);
$labels[$date] = $major_releases[$date];
$vlines[] = $vline;
}
$i++;
}


$data array_values($data);
$labels array_values($labels);
$topics array_values($topics);

$margins = array(45,110,10,200);
$imgsize = array(max(400,count($data) * 20), 350);
$graph = new Graph($imgsize[0] + $margins[0] + $margins[1], $imgsize[1] + $margins[2] + $margins[3],"auto");
$graph->SetScale("textlin");
$graph->SetY2Scale("lin");

$graph->yaxis->SetColor('blue');
$graph->y2axis->SetColor('red');

$graph->SetMargin($margins[0], $margins[1], $margins[2], $margins[3]);

$graph->img->SetAntiAliasing();

$graph->yscale->SetGrace(5,0);
$graph->xaxis->SetTickLabels($labels);
$graph->xaxis->SetLabelAngle(90);

$graph->legend->SetAbsPos(3,$imgsize[1] + $margins[2] + 10,"right","top");

$p = new LinePlot($data);
$p->SetColor("blue");
$p->SetCenter();
$p->SetLegend("New Posts");

$t = new LinePlot($topics);
$t->SetColor("red");
$t->SetCenter();
$t->SetLegend("New Topics");

$graph->Add($p);
$graph->AddY2($t);

foreach(
$vlines AS $vline)
$graph->AddLine($vline);

$graph->Stroke($graphfile);

echo 
'<img src="'$graphfile'" />';
?>


And for those that want/need comments:


<?php
require ("graph/jpgraph.php");
require (
"graph/jpgraph_line.php");
require (
'../community/SSI.php');

This includes SMF and the JP graph files that we need.


$graphfile = 'graphs/PostTopics.png';

What file do we want to store the results in?  This is going to be relative to our current file's path.


$releases = array(
'2007-09' => 'SMF 1.1.4 , 1.0.12',
'2007-06' => 'SMF 1.1.3 , 1.0.11',
'2007-02' => 'SMF 1.1.2',
'2006-10' => 'SMF 1.0.9, patch 1.1 RC3',
'2006-08' => 'SMF 1.0.8, 1.1 RC3',
'2006-03' => 'SMF 1.0.7, patch 1.1 RC2',
'2005-12' => 'SMF 1.1 RC2',
'2006-01' => 'SMF 1.0.6',
'2005-05' => 'SMF 1.1 Beta 2',
'2005-06' => 'SMF 1.0.4, 1.0.5, 1.1 Beta 3',
'2005-09' => 'SMF 1.1 RC1',
'2005-02' => 'SMF 1.0.2',
'2005-01' => 'SMF 1.0.1',
'2004-10' => 'SMF 1.0 RC2',
'2004-08' => 'SMF 1.0 RC1',
'2004-06' => 'SMF 1.0 Beta 6',
'2004-03' => 'SMF 1.0 Beta 4.1',
'2003-09' => 'SMF 1.0 Beta 1',
);

$major_releases = array(
'2007-08' => 'SMF 2.0 Beta 1',
'2006-12' => 'SMF 1.1, 1.0.10',
'2005-03' => 'SMF 1.0.3, SMF 1.1 Beta Charter',
'2004-12' => 'SMF 1.0 Final',
);

A list of releases that I could find the month and year for.  I split off what I thought were the major ones so I could easily give them a different color.


ksort($releases);
ksort($major_releases);

Just in case I didn't put them into ascending order this will make it so.  Good to use if you were dynamically loading those two arrays.


$result = $smfFunc['db_query']('', "
SELECT date, posts, topics
FROM {$db_prefix}log_activity
ORDER BY date ASC", __FILE__, __LINE__);

log_activity is the one that stores how the stats for each day.  So we want to get all days and then run through them.


$data = array();
$topics = array();
$labels = array();

Just some place to store the results.


$months = array(1 => 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

while ($row = $smfFunc['db_fetch_assoc']($result))
{
$datearr = explode('-', $row['date']);
$date = $datearr[0] . '-' . $datearr[1];
$data[$date] += $row['posts'];
$topics[$date] += $row['topics'];
$labels[$date] = $months[(int)$datearr[1]] . ' ' . $datearr[0];
}

$smfFunc['db_free_result']($result);

Ok for each day we need to get only the month and year because we are doing monthly totals and not daily totals.  After reconstructing the date add that day's posts and topics to the running sum.  Also make sure the label is set for that month.


$vlines = array();
$i = 0;

foreach($data AS $date => $dummy)
{
if (isset($releases[$date]))
{
$vline = new PlotLine(VERTICAL, $i+0.5, 'green', 1);
$labels[$date] = $releases[$date];
$vlines[] = $vline;
}
elseif(isset($major_releases[$date]))
{
$vline = new PlotLine(VERTICAL, $i+0.5, 'purple', 1);
$labels[$date] = $major_releases[$date];
$vlines[] = $vline;
}
$i++;
}

Go through each release and set a vertical line at that month and change the label to show the release instead of the month/year


$data = array_values($data);
$labels = array_values($labels);
$topics = array_values($topics);

JPgraph expects the arrays to be normal arrays and not associative arrays.


$margins = array(45,110,10,200);
$imgsize = array(max(400,count($data) * 20), 350);
$graph = new Graph($imgsize[0] + $margins[0] + $margins[1], $imgsize[1] + $margins[2] + $margins[3],"auto");
$graph->SetScale("textlin");
$graph->SetY2Scale("lin");
$graph->SetMargin($margins[0], $margins[1], $margins[2], $margins[3]);
$graph->img->SetAntiAliasing();


This just sets up the graph and the size of the image.


$graph->yaxis->SetColor('blue');
$graph->y2axis->SetColor('red');

Set the axis colors


$graph->yscale->SetGrace(5,0);
$graph->xaxis->SetTickLabels($labels);
$graph->xaxis->SetLabelAngle(90);

This gives the Y scale a little play room.  It also sets the X axis labels and turns the labels so that they are vertical.


$graph->legend->SetAbsPos(3,$imgsize[1] + $margins[2] + 10,"right","top");

Moves the graph's legend into the right spot.


$p = new LinePlot($data);
$p->SetColor("blue");
$p->SetCenter();
$p->SetLegend("New Posts");

This creates the line plot for posts, sets the color to blue, and labels the plot.


$t = new LinePlot($topics);
$t->SetColor("red");
$t->SetCenter();
$t->SetLegend("New Topics");

This creates the line plot for topics, sets the color to red, and labels the plot.


$graph->Add($p);
$graph->AddY2($t);

This adds the posts graph to the first Y axis and the topics graph to the second Y axis.


foreach($vlines AS $vline)
$graph->AddLine($vline);

This adds all the release lines to the graph.


$graph->Stroke($graphfile);

echo '<img src="', $graphfile, '" />';
?>

This says to go and actually create the final image.  Since I gave it a filename it'll output the image to that file instead of the screen which is why I echo an image tag so I can see the results also.