summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2014-11-09 17:59:02 -0500
committerFrédéric Guillot <fred@kanboard.net>2014-11-09 17:59:02 -0500
commite89ba5e9e692f33427fedb05a095255f27480a6b (patch)
tree59cbca6ac75a8eff45be14f6ae4ab487e0a427b1 /app
parent3df63e051fac84cec98c912668722f87d6e8183e (diff)
Analytics: add the first graph (task repartition)
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Analytic.php56
-rw-r--r--app/Controller/Base.php1
-rw-r--r--app/Locale/da_DK/translations.php6
-rw-r--r--app/Locale/de_DE/translations.php6
-rw-r--r--app/Locale/es_ES/translations.php6
-rw-r--r--app/Locale/fi_FI/translations.php6
-rw-r--r--app/Locale/fr_FR/translations.php6
-rw-r--r--app/Locale/it_IT/translations.php6
-rw-r--r--app/Locale/ja_JP/translations.php6
-rw-r--r--app/Locale/pl_PL/translations.php6
-rw-r--r--app/Locale/pt_BR/translations.php6
-rw-r--r--app/Locale/ru_RU/translations.php6
-rw-r--r--app/Locale/sv_SE/translations.php6
-rw-r--r--app/Locale/th_TH/translations.php6
-rw-r--r--app/Locale/zh_CN/translations.php6
-rw-r--r--app/Model/Acl.php1
-rw-r--r--app/Model/ProjectAnalytic.php43
-rw-r--r--app/Template/analytic/layout.php18
-rw-r--r--app/Template/analytic/repartition.php29
-rw-r--r--app/Template/analytic/sidebar.php8
-rw-r--r--app/Template/app_notfound.php4
-rw-r--r--app/Template/board_index.php4
22 files changed, 238 insertions, 4 deletions
diff --git a/app/Controller/Analytic.php b/app/Controller/Analytic.php
new file mode 100644
index 00000000..68177c83
--- /dev/null
+++ b/app/Controller/Analytic.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Controller;
+
+/**
+ * Project Anaytic controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class Analytic extends Base
+{
+ /**
+ * Common layout for analytic views
+ *
+ * @access private
+ * @param string $template Template name
+ * @param array $params Template parameters
+ * @return string
+ */
+ private function layout($template, array $params)
+ {
+ $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
+ $params['analytic_content_for_layout'] = $this->template->load($template, $params);
+
+ return $this->template->layout('analytic/layout', $params);
+ }
+
+ /**
+ * Show task distribution graph
+ *
+ * @access public
+ */
+ public function repartition()
+ {
+ $project = $this->getProject();
+ $metrics = $this->projectAnalytic->getTaskRepartition($project['id']);
+
+ if ($this->request->isAjax()) {
+ $this->response->json(array(
+ 'metrics' => $metrics,
+ 'labels' => array(
+ 'column_title' => t('Column'),
+ 'nb_tasks' => t('Number of tasks'),
+ )
+ ));
+ }
+ else {
+ $this->response->html($this->layout('analytic/repartition', array(
+ 'project' => $project,
+ 'metrics' => $metrics,
+ 'title' => t('Task repartition for "%s"', $project['name']),
+ )));
+ }
+ }
+}
diff --git a/app/Controller/Base.php b/app/Controller/Base.php
index c0483aa1..7eb75b07 100644
--- a/app/Controller/Base.php
+++ b/app/Controller/Base.php
@@ -26,6 +26,7 @@ use Model\LastLogin;
* @property \Model\Notification $notification
* @property \Model\Project $project
* @property \Model\ProjectPermission $projectPermission
+ * @property \Model\ProjectAnalytic $projectAnalytic
* @property \Model\SubTask $subTask
* @property \Model\Task $task
* @property \Model\TaskHistory $taskHistory
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 8701cf3d..590f2512 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index e47e55c1..807118d8 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 72c2e32f..25df8acf 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index 7711773b..517430ea 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index 05756a93..3afa53ce 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -565,4 +565,10 @@ return array(
'Columns' => 'Colonnes',
'Task' => 'Tâche',
'Your are not member of any project.' => 'Vous n\'êtes membre d\'aucun projet.',
+ 'Percentage' => 'Pourcentage',
+ 'Number of tasks' => 'Nombre de tâches',
+ 'Task distribution' => 'Répartition des tâches',
+ 'Reportings' => 'Rapports',
+ 'Task repartition for "%s"' => 'Répartition des tâches pour « %s »',
+ 'Analytics' => 'Analytique',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index 64beacab..81ccbd86 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 3d9c8440..2fdfb3d6 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 19befac7..45253fe1 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index 62744783..778bfd3a 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index b5c73a8f..f2eaca63 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 39cbff16..4f9d815a 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index eefbdcf3..8a1c8b35 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index 7db09c59..3d45532a 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -565,4 +565,10 @@ return array(
// 'Columns' => '',
// 'Task' => '',
// 'Your are not member of any project.' => '',
+ // 'Percentage' => '',
+ // 'Number of tasks' => '',
+ // 'Task distribution' => '',
+ // 'Reportings' => '',
+ // 'Task repartition for "%s"' => '',
+ // 'Analytics' => '',
);
diff --git a/app/Model/Acl.php b/app/Model/Acl.php
index 9a6866d3..52957130 100644
--- a/app/Model/Acl.php
+++ b/app/Model/Acl.php
@@ -41,6 +41,7 @@ class Acl extends Base
'task' => array('show', 'create', 'save', 'edit', 'update', 'close', 'open', 'duplicate', 'remove', 'description', 'move', 'copy', 'time'),
'category' => array('index', 'save', 'edit', 'update', 'confirm', 'remove'),
'action' => array('index', 'event', 'params', 'create', 'confirm', 'remove'),
+ 'analytic' => array('repartition'),
);
/**
diff --git a/app/Model/ProjectAnalytic.php b/app/Model/ProjectAnalytic.php
new file mode 100644
index 00000000..ccd2c4c9
--- /dev/null
+++ b/app/Model/ProjectAnalytic.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Model;
+
+/**
+ * Project analytic model
+ *
+ * @package model
+ * @author Frederic Guillot
+ */
+class ProjectAnalytic extends Base
+{
+ /**
+ * Get task repartition
+ *
+ * @access public
+ * @param integer $project_id Project id
+ * @return array
+ */
+ public function getTaskRepartition($project_id)
+ {
+ $metrics = array();
+ $total = 0;
+ $columns = $this->board->getColumns($project_id);
+
+ foreach ($columns as $column) {
+
+ $nb_tasks = $this->taskFinder->countByColumnId($project_id, $column['id']);
+ $total += $nb_tasks;
+
+ $metrics[] = array(
+ 'column_title' => $column['title'],
+ 'nb_tasks' => $nb_tasks,
+ );
+ }
+
+ foreach ($metrics as &$metric) {
+ $metric['percentage'] = round(($metric['nb_tasks'] * 100) / $total, 2);
+ }
+
+ return $metrics;
+ }
+}
diff --git a/app/Template/analytic/layout.php b/app/Template/analytic/layout.php
new file mode 100644
index 00000000..2dd7a4f5
--- /dev/null
+++ b/app/Template/analytic/layout.php
@@ -0,0 +1,18 @@
+<?= Helper\js('assets/js/d3.v3.4.8.min.js') ?>
+<?= Helper\js('assets/js/dimple.v2.1.0.min.js') ?>
+
+<section id="main">
+ <div class="page-header">
+ <ul>
+ <li><i class="fa fa-table fa-fw"></i><?= Helper\a(t('Back to the board'), 'board', 'show', array('project_id' => $project['id'])) ?></li>
+ </ul>
+ </div>
+ <section class="sidebar-container" id="analytic-section">
+
+ <?= Helper\template('analytic/sidebar', array('project' => $project)) ?>
+
+ <div class="sidebar-content">
+ <?= $analytic_content_for_layout ?>
+ </div>
+ </section>
+</section> \ No newline at end of file
diff --git a/app/Template/analytic/repartition.php b/app/Template/analytic/repartition.php
new file mode 100644
index 00000000..f20b6a0c
--- /dev/null
+++ b/app/Template/analytic/repartition.php
@@ -0,0 +1,29 @@
+<div class="page-header">
+ <h2><?= t('Task distribution') ?></h2>
+</div>
+<section id="analytic-repartition">
+
+<div id="chart" data-url="<?= Helper\u('analytic', 'repartition', array('project_id' => $project['id'])) ?>"></div>
+
+<table>
+ <tr>
+ <th><?= t('Column') ?></th>
+ <th><?= t('Number of tasks') ?></th>
+ <th><?= t('Percentage') ?></th>
+ </tr>
+ <?php foreach ($metrics as $metric): ?>
+ <tr>
+ <td>
+ <?= Helper\escape($metric['column_title']) ?>
+ </td>
+ <td>
+ <?= $metric['nb_tasks'] ?>
+ </td>
+ <td>
+ <?= n($metric['percentage']) ?>%
+ </td>
+ </tr>
+ <?php endforeach ?>
+</table>
+
+</section>
diff --git a/app/Template/analytic/sidebar.php b/app/Template/analytic/sidebar.php
new file mode 100644
index 00000000..df6835ee
--- /dev/null
+++ b/app/Template/analytic/sidebar.php
@@ -0,0 +1,8 @@
+<div class="sidebar">
+ <h2><?= t('Reportings') ?></h2>
+ <ul>
+ <li>
+ <?= Helper\a(t('Task distribution'), 'analytic', 'repartition', array('project_id' => $project['id'])) ?>
+ </li>
+ </ul>
+</div> \ No newline at end of file
diff --git a/app/Template/app_notfound.php b/app/Template/app_notfound.php
index 734d16a4..686f1fa0 100644
--- a/app/Template/app_notfound.php
+++ b/app/Template/app_notfound.php
@@ -1,8 +1,4 @@
<section id="main">
- <div class="page-header">
- <h2><?= t('Page not found') ?></h2>
- </div>
-
<p class="alert alert-error">
<?= t('Sorry, I didn\'t found this information in my database!') ?>
</p>
diff --git a/app/Template/board_index.php b/app/Template/board_index.php
index d15d455f..e478680f 100644
--- a/app/Template/board_index.php
+++ b/app/Template/board_index.php
@@ -24,6 +24,10 @@
<i class="fa fa-dashboard fa-fw"></i>
<?= Helper\a(t('Activity'), 'project', 'activity', array('project_id' => $current_project_id)) ?>
</li>
+ <li>
+ <i class="fa fa-line-chart fa-fw"></i>
+ <?= Helper\a(t('Analytics'), 'analytic', 'repartition', array('project_id' => $current_project_id)) ?>
+ </li>
<?php if (Helper\is_admin()): ?>
<li><i class="fa fa-cog fa-fw"></i>
<?= Helper\a(t('Configure'), 'project', 'show', array('project_id' => $current_project_id)) ?>