summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Controller/Analytic.php34
-rw-r--r--app/Locale/da_DK/translations.php2
-rw-r--r--app/Locale/de_DE/translations.php2
-rw-r--r--app/Locale/es_ES/translations.php2
-rw-r--r--app/Locale/fi_FI/translations.php2
-rw-r--r--app/Locale/fr_FR/translations.php2
-rw-r--r--app/Locale/it_IT/translations.php2
-rw-r--r--app/Locale/ja_JP/translations.php2
-rw-r--r--app/Locale/pl_PL/translations.php2
-rw-r--r--app/Locale/pt_BR/translations.php2
-rw-r--r--app/Locale/ru_RU/translations.php2
-rw-r--r--app/Locale/sv_SE/translations.php2
-rw-r--r--app/Locale/th_TH/translations.php2
-rw-r--r--app/Locale/zh_CN/translations.php2
-rw-r--r--app/Model/Acl.php2
-rw-r--r--app/Model/ProjectAnalytic.php39
-rw-r--r--app/Template/analytic/sidebar.php5
-rw-r--r--app/Template/analytic/tasks.php (renamed from app/Template/analytic/repartition.php)4
-rw-r--r--app/Template/analytic/users.php29
-rw-r--r--app/Template/board/filters.php2
-rw-r--r--assets/js/analytic.js54
-rw-r--r--assets/js/app.js54
22 files changed, 234 insertions, 15 deletions
diff --git a/app/Controller/Analytic.php b/app/Controller/Analytic.php
index 68177c83..7d112e6a 100644
--- a/app/Controller/Analytic.php
+++ b/app/Controller/Analytic.php
@@ -27,11 +27,11 @@ class Analytic extends Base
}
/**
- * Show task distribution graph
+ * Show tasks distribution graph
*
* @access public
*/
- public function repartition()
+ public function tasks()
{
$project = $this->getProject();
$metrics = $this->projectAnalytic->getTaskRepartition($project['id']);
@@ -46,11 +46,39 @@ class Analytic extends Base
));
}
else {
- $this->response->html($this->layout('analytic/repartition', array(
+ $this->response->html($this->layout('analytic/tasks', array(
'project' => $project,
'metrics' => $metrics,
'title' => t('Task repartition for "%s"', $project['name']),
)));
}
}
+
+ /**
+ * Show users repartition
+ *
+ * @access public
+ */
+ public function users()
+ {
+ $project = $this->getProject();
+ $metrics = $this->projectAnalytic->getUserRepartition($project['id']);
+
+ if ($this->request->isAjax()) {
+ $this->response->json(array(
+ 'metrics' => $metrics,
+ 'labels' => array(
+ 'user' => t('User'),
+ 'nb_tasks' => t('Number of tasks'),
+ )
+ ));
+ }
+ else {
+ $this->response->html($this->layout('analytic/users', array(
+ 'project' => $project,
+ 'metrics' => $metrics,
+ 'title' => t('User repartition for "%s"', $project['name']),
+ )));
+ }
+ }
}
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 2cb77240..6e355f51 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index fb03b616..1a8109c1 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index c54267ff..e0b47923 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index 59cea9f7..200b74e7 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index d36b0e93..e4edb433 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -573,4 +573,6 @@ return array(
'Analytics' => 'Analytique',
'Subtask' => 'Sous-tâche',
'My subtasks' => 'Mes sous-tâches',
+ 'User repartition' => 'Répartition des utilisateurs',
+ 'User repartition for "%s"' => 'Répartition des utilisateurs pour « %s »',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index e4f9fc8b..7ef579a7 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 0e75fc23..c1625c48 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index f0277429..0c7b4834 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index fd1fc1cf..e0969b6d 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 9c486ff4..27f9644e 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index a56c7db5..f5f4f080 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index f2e51d12..7099891f 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index 4b86a7e1..2490709b 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -573,4 +573,6 @@ return array(
// 'Analytics' => '',
// 'Subtask' => '',
// 'My subtasks' => '',
+ // 'User repartition' => '',
+ // 'User repartition for "%s"' => '',
);
diff --git a/app/Model/Acl.php b/app/Model/Acl.php
index 52957130..25e98850 100644
--- a/app/Model/Acl.php
+++ b/app/Model/Acl.php
@@ -41,7 +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'),
+ 'analytic' => array('tasks', 'users'),
);
/**
diff --git a/app/Model/ProjectAnalytic.php b/app/Model/ProjectAnalytic.php
index ccd2c4c9..8ecbf1f0 100644
--- a/app/Model/ProjectAnalytic.php
+++ b/app/Model/ProjectAnalytic.php
@@ -11,7 +11,7 @@ namespace Model;
class ProjectAnalytic extends Base
{
/**
- * Get task repartition
+ * Get tasks repartition
*
* @access public
* @param integer $project_id Project id
@@ -40,4 +40,41 @@ class ProjectAnalytic extends Base
return $metrics;
}
+
+ /**
+ * Get users repartition
+ *
+ * @access public
+ * @param integer $project_id Project id
+ * @return array
+ */
+ public function getUserRepartition($project_id)
+ {
+ $metrics = array();
+ $total = 0;
+ $tasks = $this->taskFinder->getAll($project_id);
+ $users = $this->projectPermission->getMemberList($project_id);
+
+ foreach ($tasks as $task) {
+
+ $user = $users[$task['owner_id']];
+ $total++;
+
+ if (! isset($metrics[$user])) {
+ $metrics[$user] = array(
+ 'nb_tasks' => 0,
+ 'percentage' => 0,
+ 'user' => $user,
+ );
+ }
+
+ $metrics[$user]['nb_tasks']++;
+ }
+
+ foreach ($metrics as &$metric) {
+ $metric['percentage'] = round(($metric['nb_tasks'] * 100) / $total, 2);
+ }
+
+ return array_values($metrics);
+ }
}
diff --git a/app/Template/analytic/sidebar.php b/app/Template/analytic/sidebar.php
index df6835ee..dded245a 100644
--- a/app/Template/analytic/sidebar.php
+++ b/app/Template/analytic/sidebar.php
@@ -2,7 +2,10 @@
<h2><?= t('Reportings') ?></h2>
<ul>
<li>
- <?= Helper\a(t('Task distribution'), 'analytic', 'repartition', array('project_id' => $project['id'])) ?>
+ <?= Helper\a(t('Task distribution'), 'analytic', 'tasks', array('project_id' => $project['id'])) ?>
+ </li>
+ <li>
+ <?= Helper\a(t('User repartition'), 'analytic', 'users', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div> \ No newline at end of file
diff --git a/app/Template/analytic/repartition.php b/app/Template/analytic/tasks.php
index f20b6a0c..7ae9c254 100644
--- a/app/Template/analytic/repartition.php
+++ b/app/Template/analytic/tasks.php
@@ -1,9 +1,9 @@
<div class="page-header">
<h2><?= t('Task distribution') ?></h2>
</div>
-<section id="analytic-repartition">
+<section id="analytic-task-repartition">
-<div id="chart" data-url="<?= Helper\u('analytic', 'repartition', array('project_id' => $project['id'])) ?>"></div>
+<div id="chart" data-url="<?= Helper\u('analytic', 'tasks', array('project_id' => $project['id'])) ?>"></div>
<table>
<tr>
diff --git a/app/Template/analytic/users.php b/app/Template/analytic/users.php
new file mode 100644
index 00000000..89f00686
--- /dev/null
+++ b/app/Template/analytic/users.php
@@ -0,0 +1,29 @@
+<div class="page-header">
+ <h2><?= t('User repartition') ?></h2>
+</div>
+<section id="analytic-user-repartition">
+
+<div id="chart" data-url="<?= Helper\u('analytic', 'users', array('project_id' => $project['id'])) ?>"></div>
+
+<table>
+ <tr>
+ <th><?= t('User') ?></th>
+ <th><?= t('Number of tasks') ?></th>
+ <th><?= t('Percentage') ?></th>
+ </tr>
+ <?php foreach ($metrics as $metric): ?>
+ <tr>
+ <td>
+ <?= Helper\escape($metric['user']) ?>
+ </td>
+ <td>
+ <?= $metric['nb_tasks'] ?>
+ </td>
+ <td>
+ <?= n($metric['percentage']) ?>%
+ </td>
+ </tr>
+ <?php endforeach ?>
+</table>
+
+</section>
diff --git a/app/Template/board/filters.php b/app/Template/board/filters.php
index 21e51d98..76cbca2d 100644
--- a/app/Template/board/filters.php
+++ b/app/Template/board/filters.php
@@ -25,7 +25,7 @@
</li>
<li>
<i class="fa fa-line-chart fa-fw"></i>
- <?= Helper\a(t('Analytics'), 'analytic', 'repartition', array('project_id' => $project['id'])) ?>
+ <?= Helper\a(t('Analytics'), 'analytic', 'tasks', array('project_id' => $project['id'])) ?>
</li>
<?php if (Helper\is_admin()): ?>
<li><i class="fa fa-cog fa-fw"></i>
diff --git a/assets/js/analytic.js b/assets/js/analytic.js
index 32d3037a..22fb672e 100644
--- a/assets/js/analytic.js
+++ b/assets/js/analytic.js
@@ -4,15 +4,18 @@ Kanboard.Analytic = (function() {
return {
Init: function() {
- if (Kanboard.Exists("analytic-repartition")) {
- Kanboard.Analytic.Repartition.Init();
+ if (Kanboard.Exists("analytic-task-repartition")) {
+ Kanboard.Analytic.TaskRepartition.Init();
+ }
+ else if (Kanboard.Exists("analytic-user-repartition")) {
+ Kanboard.Analytic.UserRepartition.Init();
}
}
};
})();
-Kanboard.Analytic.Repartition = (function() {
+Kanboard.Analytic.TaskRepartition = (function() {
function fetchData()
{
@@ -56,3 +59,48 @@ Kanboard.Analytic.Repartition = (function() {
};
})();
+
+Kanboard.Analytic.UserRepartition = (function() {
+
+ function fetchData()
+ {
+ jQuery.getJSON($("#chart").attr("data-url"), function(data) {
+ drawGraph(data.metrics, data.labels);
+ });
+ }
+
+ function drawGraph(metrics, labels)
+ {
+ var series = prepareSeries(metrics, labels);
+
+ var svg = dimple.newSvg("#chart", 700, 350);
+
+ var chart = new dimple.chart(svg, series);
+ chart.addMeasureAxis("p", labels["nb_tasks"]);
+ var ring = chart.addSeries(labels["user"], dimple.plot.pie);
+ ring.innerRadius = "50%";
+ chart.addLegend(0, 0, 100, 100, "left");
+ chart.draw();
+ }
+
+ function prepareSeries(metrics, labels)
+ {
+ var series = [];
+
+ for (var i = 0; i < metrics.length; i++) {
+
+ var serie = {};
+ serie[labels["nb_tasks"]] = metrics[i]["nb_tasks"];
+ serie[labels["user"]] = metrics[i]["user"];
+
+ series.push(serie);
+ }
+
+ return series;
+ }
+
+ return {
+ Init: fetchData
+ };
+
+})();
diff --git a/assets/js/app.js b/assets/js/app.js
index 55bc4039..ed017b0b 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -273,15 +273,18 @@ Kanboard.Analytic = (function() {
return {
Init: function() {
- if (Kanboard.Exists("analytic-repartition")) {
- Kanboard.Analytic.Repartition.Init();
+ if (Kanboard.Exists("analytic-task-repartition")) {
+ Kanboard.Analytic.TaskRepartition.Init();
+ }
+ else if (Kanboard.Exists("analytic-user-repartition")) {
+ Kanboard.Analytic.UserRepartition.Init();
}
}
};
})();
-Kanboard.Analytic.Repartition = (function() {
+Kanboard.Analytic.TaskRepartition = (function() {
function fetchData()
{
@@ -325,6 +328,51 @@ Kanboard.Analytic.Repartition = (function() {
};
})();
+
+Kanboard.Analytic.UserRepartition = (function() {
+
+ function fetchData()
+ {
+ jQuery.getJSON($("#chart").attr("data-url"), function(data) {
+ drawGraph(data.metrics, data.labels);
+ });
+ }
+
+ function drawGraph(metrics, labels)
+ {
+ var series = prepareSeries(metrics, labels);
+
+ var svg = dimple.newSvg("#chart", 700, 350);
+
+ var chart = new dimple.chart(svg, series);
+ chart.addMeasureAxis("p", labels["nb_tasks"]);
+ var ring = chart.addSeries(labels["user"], dimple.plot.pie);
+ ring.innerRadius = "50%";
+ chart.addLegend(0, 0, 100, 100, "left");
+ chart.draw();
+ }
+
+ function prepareSeries(metrics, labels)
+ {
+ var series = [];
+
+ for (var i = 0; i < metrics.length; i++) {
+
+ var serie = {};
+ serie[labels["nb_tasks"]] = metrics[i]["nb_tasks"];
+ serie[labels["user"]] = metrics[i]["user"];
+
+ series.push(serie);
+ }
+
+ return series;
+ }
+
+ return {
+ Init: fetchData
+ };
+
+})();
// Initialization
$(function() {