use stacked bars in dashboard to show different working tasks per day

This commit is contained in:
Kevin Papst
2020-08-16 01:43:38 +02:00
parent 2449a1e8bf
commit bb4233ddfe
2 changed files with 94 additions and 25 deletions

View File

@@ -9,6 +9,8 @@
namespace App\Widget\Type; namespace App\Widget\Type;
use App\Entity\Activity;
use App\Entity\Project;
use App\Repository\TimesheetRepository; use App\Repository\TimesheetRepository;
use App\Security\CurrentUser; use App\Security\CurrentUser;
use App\Timesheet\UserDateTimeFactory; use App\Timesheet\UserDateTimeFactory;
@@ -75,6 +77,28 @@ class DailyWorkingTimeChart extends SimpleWidget
$end = new DateTime($options['end'], $this->dateTimeFactory->getTimezone()); $end = new DateTime($options['end'], $this->dateTimeFactory->getTimezone());
} }
return $this->repository->getDailyStats($user, $begin, $end); $activities = [];
$statistics = $this->repository->getDailyStats($user, $begin, $end);
foreach ($statistics as $day) {
foreach ($day->getDetails() as $entry) {
/** @var Activity $activity */
$activity = $entry['activity'];
/** @var Project $project */
$project = $entry['project'];
$id = $project->getId() . '_' . $activity->getId();
$activities[$id] = [
'activity' => $activity,
'project' => $project,
];
}
}
return [
'activities' => $activities,
'data' => $statistics,
];
} }
} }

View File

@@ -1,16 +1,9 @@
{% set type = options.type|default('bar') %} {% set type = options.type|default('bar') %}
{% set chart_id = options.id %} {% set chart_id = options.id %}
{% set backgroundColor = kimai_context.chart.background_color %} {% set backgroundColor = kimai_context.chart.background_color %}
{% set borderColor = kimai_context.chart.border_color %}
{% set gridColor = kimai_context.chart.grid_color %} {% set gridColor = kimai_context.chart.grid_color %}
{% set colors = options.color|default('')|split(';') %} {% set activities = data.activities %}
{% if colors.0 is defined and not colors.0 is empty %} {% set data = data.data %}
{% set backgroundColor = colors.0 %}
{% set borderColor = colors.0 %}
{% if colors.1 is defined and not colors.1 is empty %}
{% set borderColor = colors.1 %}
{% endif %}
{% endif %}
<div class="chart"> <div class="chart">
<canvas id="{{ chart_id }}" style="height: {{ kimai_context.chart.height }}px;"></canvas> <canvas id="{{ chart_id }}" style="height: {{ kimai_context.chart.height }}px;"></canvas>
@@ -31,22 +24,50 @@
{%- endfor %} {%- endfor %}
], ],
datasets: [ datasets: [
{% for activityId, activity in activities -%}
{% set activityColor = activity.activity|color|default(activity.project|color|default(backgroundColor)) %}
{% set activityName = activity.activity.name %}
{ {
backgroundColor: '{{ backgroundColor }}', label: '{{ activityName }}',
borderColor: '{{ borderColor }}', backgroundColor: '{{ activityColor }}',
borderColor: '#fff',
borderWidth: 1,
data: [ data: [
{% for day in data -%} {%- for day in data -%}
{{ (day.totalDuration / 3600)|number_format(2, '.', '') }} {% set realDayData = null %}
{%- for entry in day.details -%}
{% set loopId = (entry.project.id ~ '_' ~ entry.activity.id) %}
{%- if loopId == activityId -%}
{% set realDayData = (entry.duration / 3600)|number_format(2, '.', '') %}
{%- endif -%}
{%- endfor -%}
{%- if realDayData is not null -%}
'{{ realDayData }}'
{%- else -%}
0
{%- endif -%}
{%- if not loop.last %},{% endif -%} {%- if not loop.last %},{% endif -%}
{%- endfor %} {%- endfor -%}
], ],
realData: [ realData: [
{% for day in data -%} {%- for day in data -%}
'{{ day.totalDuration|duration }}' {% set realDayData = null %}
{%- for entry in day.details -%}
{% set loopId = (entry.project.id ~ '_' ~ entry.activity.id) %}
{%- if loopId == activityId -%}
{% set realDayData = {duration: entry.duration|duration, project: entry.project.name, customer: entry.project.customer.name, activity: entry.activity.name, total: day.totalDuration|duration} %}
{%- endif -%}
{%- endfor -%}
{%- if realDayData is not null -%}
{{ realDayData|json_encode|raw }}
{%- else -%}
0
{%- endif -%}
{%- if not loop.last %},{% endif -%} {%- if not loop.last %},{% endif -%}
{%- endfor %} {%- endfor -%}
] ]
} },
{%- endfor %}
] ]
}, },
options: { options: {
@@ -57,11 +78,13 @@
categoryPercentage: 0.9, categoryPercentage: 0.9,
scales: { scales: {
xAxes: [{ xAxes: [{
stacked: true,
gridLines: { gridLines: {
display: false display: false
}, },
}], }],
yAxes: [{ yAxes: [{
stacked: true,
ticks: { ticks: {
beginAtZero: true beginAtZero: true
}, },
@@ -70,14 +93,36 @@
color: '{{ gridColor }}', color: '{{ gridColor }}',
lineWidth: 1 lineWidth: 1
} }
}] }],
}, },
tooltips: { tooltips: {
callbacks: { callbacks: {
label: function(tooltipItem, data) { label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index]; var tooltipData = data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
} return ' ' + tooltipData.duration + ': ' + tooltipData.activity;
} },
beforeTitle: function(tooltipItems, data) {
var tooltipItem = tooltipItems[0];
var tooltipData = data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
return tooltipData.customer;
},
title: function(tooltipItems, data) {
var tooltipItem = tooltipItems[0];
var tooltipData = data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
return tooltipData.project;
},
afterTitle: function(tooltipItems, data) {
return ' ';
},
footer: function(tooltipItems, data) {
var tooltipItem = tooltipItems[0];
var tooltipData = data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
return '{{ 'stats.durationTotal'|trans }}: ' + tooltipData.total;
},
beforeFooter: function(tooltipItems, data) {
return ' ';
},
},
} }
} }
} }