Convert time comparison chart to Vue.js component
This commit is contained in:
@@ -41,8 +41,8 @@ class EstimatedTimeComparisonAnalytic extends Base
|
|||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$key = $row['is_active'] == TaskModel::STATUS_OPEN ? 'open' : 'closed';
|
$key = $row['is_active'] == TaskModel::STATUS_OPEN ? 'open' : 'closed';
|
||||||
$metrics[$key]['time_spent'] = $row['time_spent'];
|
$metrics[$key]['time_spent'] = (float) $row['time_spent'];
|
||||||
$metrics[$key]['time_estimated'] = $row['time_estimated'];
|
$metrics[$key]['time_estimated'] = (float) $row['time_estimated'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $metrics;
|
return $metrics;
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ class AnalyticController extends BaseController
|
|||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
public function compareHours()
|
public function timeComparison()
|
||||||
{
|
{
|
||||||
$project = $this->getProject();
|
$project = $this->getProject();
|
||||||
|
|
||||||
$paginator = $this->paginator
|
$paginator = $this->paginator
|
||||||
->setUrl('AnalyticController', 'compareHours', array('project_id' => $project['id']))
|
->setUrl('AnalyticController', 'timeComparison', array('project_id' => $project['id']))
|
||||||
->setMax(30)
|
->setMax(30)
|
||||||
->setOrder(TaskModel::TABLE.'.id')
|
->setOrder(TaskModel::TABLE.'.id')
|
||||||
->setQuery($this->taskQuery
|
->setQuery($this->taskQuery
|
||||||
@@ -54,7 +54,7 @@ class AnalyticController extends BaseController
|
|||||||
)
|
)
|
||||||
->calculate();
|
->calculate();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->analytic('analytic/compare_hours', array(
|
$this->response->html($this->helper->layout->analytic('analytic/time_comparison', array(
|
||||||
'project' => $project,
|
'project' => $project,
|
||||||
'paginator' => $paginator,
|
'paginator' => $paginator,
|
||||||
'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']),
|
'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']),
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
<li <?= $this->app->checkMenuSelection('AnalyticController', 'leadAndCycleTime') ?>>
|
<li <?= $this->app->checkMenuSelection('AnalyticController', 'leadAndCycleTime') ?>>
|
||||||
<?= $this->url->link(t('Lead and cycle time'), 'AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>
|
<?= $this->url->link(t('Lead and cycle time'), 'AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>
|
||||||
</li>
|
</li>
|
||||||
<li <?= $this->app->checkMenuSelection('AnalyticController', 'compareHours') ?>>
|
<li <?= $this->app->checkMenuSelection('AnalyticController', 'timeComparison') ?>>
|
||||||
<?= $this->url->link(t('Estimated vs actual time'), 'AnalyticController', 'compareHours', array('project_id' => $project['id'])) ?>
|
<?= $this->url->link(t('Estimated vs actual time'), 'AnalyticController', 'timeComparison', array('project_id' => $project['id'])) ?>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<?= $this->hook->render('template:analytic:sidebar', array('project' => $project)) ?>
|
<?= $this->hook->render('template:analytic:sidebar', array('project' => $project)) ?>
|
||||||
|
|||||||
@@ -12,17 +12,17 @@
|
|||||||
<?php if (empty($metrics)): ?>
|
<?php if (empty($metrics)): ?>
|
||||||
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
|
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<section id="analytic-compare-hours">
|
|
||||||
<div id="chart"
|
|
||||||
data-metrics='<?= json_encode($metrics, JSON_HEX_APOS)?>'
|
|
||||||
data-label-spent="<?= t('Hours Spent') ?>"
|
|
||||||
data-label-estimated="<?= t('Hours Estimated') ?>"
|
|
||||||
data-label-closed="<?= t('Closed') ?>"
|
|
||||||
data-label-open="<?= t('Open') ?>"></div>
|
|
||||||
|
|
||||||
<?php if ($paginator->isEmpty()): ?>
|
<?php if ($paginator->isEmpty()): ?>
|
||||||
<p class="alert"><?= t('No tasks found.') ?></p>
|
<p class="alert"><?= t('No tasks found.') ?></p>
|
||||||
<?php elseif (! $paginator->isEmpty()): ?>
|
<?php elseif (! $paginator->isEmpty()): ?>
|
||||||
|
<chart-project-time-comparison
|
||||||
|
:metrics='<?= json_encode($metrics, JSON_HEX_APOS)?>'
|
||||||
|
label-spent="<?= t('Hours Spent') ?>"
|
||||||
|
label-estimated="<?= t('Hours Estimated') ?>"
|
||||||
|
label-closed="<?= t('Closed') ?>"
|
||||||
|
label-open="<?= t('Open') ?>">
|
||||||
|
</chart-project-time-comparison>
|
||||||
|
|
||||||
<table class="table-fixed table-small table-scrolling">
|
<table class="table-fixed table-small table-scrolling">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
||||||
@@ -58,5 +58,4 @@
|
|||||||
|
|
||||||
<?= $paginator ?>
|
<?= $paginator ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</section>
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
4
assets/js/app.min.js
vendored
4
assets/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
36
assets/js/components/chart-project-time-comparison.js
Normal file
36
assets/js/components/chart-project-time-comparison.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
Vue.component('chart-project-time-comparison', {
|
||||||
|
props: ['metrics', 'labelSpent', 'labelEstimated', 'labelClosed', 'labelOpen'],
|
||||||
|
template: '<div id="chart"></div>',
|
||||||
|
ready: function () {
|
||||||
|
var spent = [this.labelSpent];
|
||||||
|
var estimated = [this.labelEstimated];
|
||||||
|
var categories = [];
|
||||||
|
|
||||||
|
for (var status in this.metrics) {
|
||||||
|
spent.push(this.metrics[status].time_spent);
|
||||||
|
estimated.push(this.metrics[status].time_estimated);
|
||||||
|
categories.push(status === 'open' ? this.labelOpen : this.labelClosed);
|
||||||
|
}
|
||||||
|
|
||||||
|
c3.generate({
|
||||||
|
data: {
|
||||||
|
columns: [spent, estimated],
|
||||||
|
type: 'bar'
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
width: {
|
||||||
|
ratio: 0.2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: {
|
||||||
|
type: 'category',
|
||||||
|
categories: categories
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
Kanboard.CompareHoursColumnChart = function(app) {
|
|
||||||
this.app = app;
|
|
||||||
};
|
|
||||||
|
|
||||||
Kanboard.CompareHoursColumnChart.prototype.execute = function() {
|
|
||||||
if (this.app.hasId("analytic-compare-hours")) {
|
|
||||||
this.show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Kanboard.CompareHoursColumnChart.prototype.show = function() {
|
|
||||||
var chart = $("#chart");
|
|
||||||
var metrics = chart.data("metrics");
|
|
||||||
var labelOpen = chart.data("label-open");
|
|
||||||
var labelClosed = chart.data("label-closed");
|
|
||||||
var spent = [chart.data("label-spent")];
|
|
||||||
var estimated = [chart.data("label-estimated")];
|
|
||||||
var categories = [];
|
|
||||||
|
|
||||||
for (var status in metrics) {
|
|
||||||
spent.push(parseFloat(metrics[status].time_spent));
|
|
||||||
estimated.push(parseFloat(metrics[status].time_estimated));
|
|
||||||
categories.push(status == 'open' ? labelOpen : labelClosed);
|
|
||||||
}
|
|
||||||
|
|
||||||
c3.generate({
|
|
||||||
data: {
|
|
||||||
columns: [spent, estimated],
|
|
||||||
type: 'bar'
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
width: {
|
|
||||||
ratio: 0.2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axis: {
|
|
||||||
x: {
|
|
||||||
type: 'category',
|
|
||||||
categories: categories
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
show: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user