| <?php |
| |
| #***************************************************************************** |
| # |
| # index.php |
| # |
| # Author: Wayne Beaton |
| # Date: 2010-06-07 |
| # |
| # Description: Project Tools Landing Page |
| # |
| #**************************************************************************** |
| |
| require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php"); |
| require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php"); |
| require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php"); |
| $App = new App(); |
| $Nav = new Nav(); |
| $Menu = new Menu(); |
| include($App->getProjectCommon()); |
| |
| require_once $_SERVER['DOCUMENT_ROOT'] . '/projects/classes/Project.class.php'; |
| |
| # |
| # Begin: page-specific settings. Change these. |
| $pageTitle = "Eclipse Project KPIs"; |
| $pageKeywords = ""; |
| $pageAuthor = "Wayne Beaton"; |
| |
| ob_start(); |
| |
| function getActivityChartData($age = 5) { |
| global $App; |
| |
| /* |
| * Only query the last five years worth of data. Exclude |
| * the current month. |
| */ |
| $start = date('Ym', strtotime("- $age years")); |
| $end = date('Ym'); |
| |
| $sql = " |
| select |
| period, |
| projects, activeProjects, commits, |
| activeAuthors, |
| committers, monthlyCommitters, participatingCommitters, activeCommitters, activeCompanies |
| from MonthlySummary |
| where period >= $start and period < $end"; |
| |
| $result = $App->dashboard_sql($sql); |
| |
| $contributors = array(); |
| $committers = array(); |
| $projects = array(); |
| while ($row = mysql_fetch_assoc($result)) { |
| if (!preg_match('/(\d\d\d\d)(\d\d)/',$row['period'], $matches)) continue; |
| $date = strtotime($matches[1] . '-' . $matches[2] . '-01'); |
| |
| $period = date('M Y', $date); |
| $projectsCount = (int)$row['projects']; |
| $activeProjects = (int)$row['activeProjects']; |
| $contributorsCount = (int)$row['activeAuthors'] - (int)$row['monthlyCommitters']; |
| $committersCount = (int)$row['committers']; |
| $activeCommitters = (int)$row['activeCommitters']; |
| $participatingCommitters = (int)$row['participatingCommitters']; |
| $companies = (int)$row['activeCompanies']; |
| |
| $contributors[] = array($period, $contributorsCount); |
| $committers[] = array($period, $committersCount, $activeCommitters, $participatingCommitters); |
| $projects[] = array($period, $projectsCount, $activeProjects, $companies); |
| } |
| |
| return array(json_encode($contributors), json_encode($committers), json_encode($projects)); |
| } |
| |
| function renderMonthlyTop10Chart() { |
| global $App; |
| |
| $period = date('Ym', strtotime('-1 month')); |
| |
| $sql = " |
| select project, count |
| from SubprojectCommitActivity |
| where period='$period' |
| order by count desc |
| limit 10;"; |
| |
| $result = $App->dashboard_sql($sql); |
| |
| $rows = array(); |
| while ($row = mysql_fetch_assoc($result)) { |
| $id = $row['project']; |
| $project = get_project_from_pmi($id); |
| $name = $project ? $project->getName() : $id; |
| |
| $count = $row['count']; |
| |
| $rows[] = array($name, $count); |
| } |
| echo "<p>The determination of "Top 10" is based on commits made |
| against the project in $period.</p>"; |
| |
| drawPieChart('Top10Monthly', "Top Ten Projects by Contributor Count ($period)", array('string' => 'Project', 'number' => 'Commits'), $rows); |
| } |
| |
| function renderMonthlyCommitsChart($age = 5) { |
| global $App; |
| |
| $start = date('Ym', strtotime("- $age years")); |
| $end = date('Ym'); |
| |
| $sql = " |
| select |
| period, commits as count |
| from MonthlySummary |
| where period >= $start and period < $end"; |
| |
| $result = $App->dashboard_sql($sql); |
| |
| $rows = array(); |
| while ($row = mysql_fetch_assoc($result)) { |
| $period = $row['period']; |
| $count = $row['count']; |
| |
| if (!preg_match('/(\d\d\d\d)(\d\d)/',$row['period'], $matches)) continue; |
| $date = strtotime($matches[1] . '-' . $matches[2] . '-01'); |
| |
| $period = date('M Y', $date); |
| |
| $rows[] = array($period, $count); |
| } |
| |
| echo "<p>Based on commits between $start and $end.</p>"; |
| |
| drawBarChart('MonthlyCommits', "Commits by Month ($start to $end)", array('string' => 'Project', 'number' => 'Commits'), $rows); |
| } |
| |
| function renderQuarterlyTop10Chart() { |
| global $App; |
| |
| list($quarter, $start, $end) = getLastQuarter(time()); |
| |
| $sql = " |
| select project, count |
| from SubprojectCommitActivity |
| where period between $start and $end |
| group by project |
| order by count desc |
| limit 10;"; |
| |
| $result = $App->dashboard_sql($sql); |
| |
| $rows = array(); |
| while ($row = mysql_fetch_assoc($result)) { |
| $id = $row['project']; |
| $project = get_project_from_pmi($id); |
| $name = $project ? $project->getName() : $id; |
| |
| $count = $row['count']; |
| |
| $rows[] = array($name, $count); |
| } |
| |
| echo "<p>Based on commits between $start and $end.</p>"; |
| |
| drawPieChart('Top10Quarterly', "Top Ten Projects by Contribution Count ($quarter)", array('string' => 'Project', 'number' => 'Commits'), $rows); |
| } |
| |
| function renderQuarterlyTop10ContributorsChart() { |
| global $App; |
| |
| list($quarter, $start, $end) = getLastQuarter(time()); |
| |
| $sql = " |
| select |
| project, Authors-Committers as count |
| from ProjectQuarterlySummary |
| where quarter='$quarter' |
| and Authors-Committers >= ( |
| select Authors-Committers as count |
| from ProjectQuarterlySummary |
| where quarter='$quarter' |
| order by count desc limit 10, 1) |
| order by count desc"; |
| |
| $result = $App->dashboard_sql($sql); |
| |
| $rows = array(); |
| while ($row = mysql_fetch_assoc($result)) { |
| $id = $row['project']; |
| $project = get_project_from_pmi($id); |
| $name = $project ? $project->getName() : $id; |
| |
| $count = $row['count']; |
| |
| $rows[] = array($name, $count); |
| } |
| |
| echo "<p>Based on commits between $start and $end.</p>"; |
| |
| drawPieChart('Top10ContributorsQuarterly', "Top \"Ten\" Projects by Contributor Count ($quarter)", array('string' => 'Project', 'number' => 'Commits'), $rows); |
| } |
| |
| list($contributors, $committers, $activity) = getActivityChartData(); |
| |
| $width = 800; |
| $height = 600; |
| |
| $js = " |
| // Load the Visualization API and the piechart package. |
| google.load('visualization', '1.0', {'packages':['corechart']}); |
| |
| // Set a callback to run when the Google Visualization API is loaded. |
| google.setOnLoadCallback(drawCommitterChart); |
| google.setOnLoadCallback(drawContributorChart); |
| google.setOnLoadCallback(drawActivityChart); |
| |
| // Callback that creates and populates a data table, |
| // instantiates the pie chart, passes in the data and |
| // draws it. |
| function drawActivityChart() { |
| |
| // Create the data table. |
| var data = new google.visualization.DataTable(); |
| data.addColumn('string', 'Period'); |
| data.addColumn('number', 'Total Projects'); |
| data.addColumn('number', 'Active Projects'); |
| data.addColumn('number', 'Active Companies'); |
| data.addRows($activity); |
| |
| // Set chart options |
| var options = { |
| title:'Project Metrics', |
| vAxis: {title: 'Count'}, |
| hAxis: {title: 'Time Period'}, |
| curveType: 'function', |
| width:$width, |
| height:$height |
| }; |
| |
| // Instantiate and draw our chart, passing in some options. |
| var chart = new google.visualization.LineChart(document.getElementById('activity_chart_div')); |
| chart.draw(data, options); |
| |
| document.getElementById('activity_chart_div_png').outerHTML = '<a href=\"' + chart.getImageURI() + '\">Printable version</a>'; |
| } |
| |
| function drawCommitterChart() { |
| |
| // Create the data table. |
| var data = new google.visualization.DataTable(); |
| data.addColumn('string', 'Period'); |
| data.addColumn('number', 'Total Committers'); |
| data.addColumn('number', 'Active Committers'); |
| data.addColumn('number', 'Participating Committers'); |
| data.addRows($committers); |
| |
| // Set chart options |
| var options = { |
| title:'Committers', |
| vAxis: {title: 'Count'}, |
| hAxis: {title: 'Time Period'}, |
| curveType: 'function', |
| width:$width, |
| height:$height |
| }; |
| |
| // Instantiate and draw our chart, passing in some options. |
| var chart = new google.visualization.LineChart(document.getElementById('committer_chart_div')); |
| chart.draw(data, options); |
| |
| document.getElementById('committer_chart_div_png').outerHTML = '<a href=\"' + chart.getImageURI() + '\">Printable version</a>'; |
| } |
| |
| function drawContributorChart() { |
| |
| // Create the data table. |
| var data = new google.visualization.DataTable(); |
| data.addColumn('string', 'Period'); |
| data.addColumn('number', 'Active Contributors'); |
| data.addRows($contributors); |
| |
| // Set chart options |
| var options = { |
| title:'Contributors', |
| vAxis: {title: 'Count'}, |
| hAxis: {title: 'Time Period'}, |
| curveType: 'function', |
| width:$width, |
| height:$height, |
| trendlines: { 0: {} } |
| }; |
| |
| // Instantiate and draw our chart, passing in some options. |
| var chart = new google.visualization.LineChart(document.getElementById('contributor_chart_div')); |
| chart.draw(data, options); |
| |
| document.getElementById('contributor_chart_div_png').outerHTML = '<a href=\"' + chart.getImageURI() + '\">Printable version</a>'; |
| } |
| "; |
| |
| function getLastQuarter($date) { |
| $year = date('Y', $date); |
| $current = ceil(date('n', $date) / 3); |
| $last = $current - 1; |
| if ($last < 1) { |
| $year--; |
| $last = 4; |
| } |
| |
| $start = str_pad($last * 3 - 2, 2, '0', STR_PAD_LEFT); |
| $end = str_pad($last * 3, 2, '0', STR_PAD_LEFT); |
| |
| return array("${year}Q${last}", "${year}${start}", "${year}${end}"); |
| } |
| |
| function drawPieChart($id, $title, $columns, $values, $width=800, $height=600) { |
| global $App; |
| |
| $columnsJS = ''; |
| foreach($columns as $type => $label) { |
| $columnsJS .= "data.addColumn('$type','$label');"; |
| } |
| |
| $valuesJSON = json_encode($values, JSON_NUMERIC_CHECK); |
| |
| $js = " |
| google.setOnLoadCallback(draw${id}Chart); |
| function draw${id}Chart() { |
| // Create the data table. |
| var data = new google.visualization.DataTable(); |
| $columnsJS; |
| data.addRows($valuesJSON); |
| |
| // Set chart options |
| var options = { |
| 'title':'$title', |
| 'pieSliceText': 'label', |
| 'legend.alignment':'center', |
| 'width':$width, |
| 'height':$height |
| }; |
| |
| // Instantiate and draw our chart, passing in some options. |
| var chart = new google.visualization.PieChart(document.getElementById('{$id}_div')); |
| chart.draw(data, options); |
| |
| document.getElementById('{$id}_div_png').outerHTML = '<a href=\"' + chart.getImageURI() + '\">Printable version</a>'; |
| }"; |
| |
| $App->addExtraHtmlHeader("<script type=\"text/javascript\">$js</script>"); |
| |
| echo "<div id=\"${id}_div\"></div>"; |
| echo "<div id=\"${id}_div_png\"></div>"; |
| } |
| |
| function drawBarChart($id, $title, $columns, $values, $width=800, $height=600) { |
| global $App; |
| |
| $columnsJS = ''; |
| foreach($columns as $type => $label) { |
| $columnsJS .= "data.addColumn('$type','$label');"; |
| } |
| |
| $valuesJSON = json_encode($values, JSON_NUMERIC_CHECK); |
| $js = " |
| google.setOnLoadCallback(draw${id}Chart); |
| function draw${id}Chart() { |
| // Create the data table. |
| var data = new google.visualization.DataTable(); |
| $columnsJS; |
| data.addRows($valuesJSON); |
| |
| // Set chart options |
| var options = { |
| title:'$title', |
| vAxis: {title: 'Count'}, |
| hAxis: {title: 'Time Period'}, |
| curveType: 'function', |
| width:$width, |
| height:$height, |
| trendlines: { 0: {} } |
| }; |
| |
| // Instantiate and draw our chart, passing in some options. |
| var chart = new google.visualization.LineChart(document.getElementById('${id}_div')); |
| chart.draw(data, options); |
| |
| document.getElementById('${id}_div_png').outerHTML = '<a href=\"' + chart.getImageURI() + '\">Printable version</a>'; |
| }"; |
| |
| $App->addExtraHtmlHeader("<script type=\"text/javascript\">$js</script>"); |
| |
| echo "<div id=\"${id}_div\"></div>"; |
| echo "<div id=\"${id}_div_png\"></div>"; |
| } |
| |
| $App->addExtraHtmlHeader("<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>"); |
| $App->addExtraHtmlHeader("<script type=\"text/javascript\">$js</script>"); |
| |
| ?> |
| <div id="maincontent"> |
| <div id="midcolumn"> |
| <h1><?= $pageTitle ?></h1> |
| |
| <h3>Committer Activity</h3> |
| |
| <p>Overall committer activity by month based on commits made against |
| project repositories over the last five years. |
| This excludes the current month.</p> |
| |
| <div id="committer_chart_div"></div> |
| <div id='committer_chart_div_png'></div> |
| |
| <h3>Contributor Activity</h3> |
| |
| <p>Overall non-committer contributor activity by month based on commits made against |
| project repositories over the last five years. |
| This excludes the current month.</p> |
| |
| <div id="contributor_chart_div"></div> |
| <div id='contributor_chart_div_png'></div> |
| |
| <h3>Project Activity</h3> |
| |
| <p>Overall project activity by month based on commits made against |
| project repositories over the last five years. |
| This excludes the current month.</p> |
| |
| <div id="activity_chart_div"></div> |
| <div id='activity_chart_div_png'></div> |
| |
| |
| <h3>Commit Activity</h3> |
| <p>Absolute number of commits.</p> |
| |
| <?php renderMonthlyCommitsChart(5); ?> |
| |
| <h3>Top 10 Projects by Commits</h3> |
| |
| <?php renderMonthlyTop10Chart(); ?> |
| |
| <h2>Quarterly Charts</h2> |
| |
| <h3>Top 10 Projects</h3> |
| <p>Based on number of commits.</p> |
| |
| <?php renderQuarterlyTop10Chart(); ?> |
| |
| <h3>Top 10(-ish) Projects by Contributors</h3> |
| <p>Based on number of (non-committer) contributors.</p> |
| |
| <?php renderQuarterlyTop10ContributorsChart(); ?> |
| |
| </div> |
| </div> |
| |
| <?php |
| $html = ob_get_contents(); |
| ob_end_clean(); |
| $App->generatePage($theme, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html); |
| ?> |