users weekly stats as bar-chart in dashboard (#847)
This commit is contained in:
@@ -35,13 +35,8 @@
|
||||
{% set currency = activity.project.customer.currency %}
|
||||
{% endif %}
|
||||
|
||||
{% if activity.budget > 0 %}
|
||||
{{ progress.progressbar(activity.budget, stats.recordRate, 'label.budget'|trans, stats.recordRate|money(currency) ~ ' / ' ~ activity.budget|money(currency) ) }}
|
||||
{% endif %}
|
||||
|
||||
{% if activity.timeBudget > 0 %}
|
||||
{{ progress.progressbar(activity.timeBudget, stats.recordDuration, 'label.timeBudget'|trans, stats.recordDuration|duration ~ ' / ' ~ activity.timeBudget|duration ) }}
|
||||
{% endif %}
|
||||
{{ progress.progressbar(activity.budget, stats.recordRate, 'label.budget'|trans, stats.recordRate|money(currency) ~ ' / ' ~ activity.budget|money(currency) ) }}
|
||||
{{ progress.progressbar(activity.timeBudget, stats.recordDuration, 'label.timeBudget'|trans, stats.recordDuration|duration ~ ' / ' ~ activity.timeBudget|duration ) }}
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
|
||||
|
||||
@@ -24,13 +24,8 @@
|
||||
{{ 'admin_customer.short_stats'|trans(params)|raw }}
|
||||
</p>
|
||||
|
||||
{% if customer.budget > 0 %}
|
||||
{{ progress.progressbar(customer.budget, stats.recordRate, 'label.budget'|trans, stats.recordRate|money(customer.currency) ~ ' / ' ~ customer.budget|money(customer.currency) ) }}
|
||||
{% endif %}
|
||||
|
||||
{% if customer.timeBudget > 0 %}
|
||||
{{ progress.progressbar(customer.timeBudget, stats.recordDuration, 'label.timeBudget'|trans, stats.recordDuration|duration ~ ' / ' ~ customer.timeBudget|duration ) }}
|
||||
{% endif %}
|
||||
{{ progress.progressbar(customer.budget, stats.recordRate, 'label.budget'|trans, stats.recordRate|money(customer.currency) ~ ' / ' ~ customer.budget|money(customer.currency) ) }}
|
||||
{{ progress.progressbar(customer.timeBudget, stats.recordDuration, 'label.timeBudget'|trans, stats.recordDuration|duration ~ ' / ' ~ customer.timeBudget|duration ) }}
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
|
||||
|
||||
@@ -18,12 +18,8 @@
|
||||
|
||||
{% block main %}
|
||||
|
||||
{% for row in widget_rows %}
|
||||
{% if row.type == constant('App\\Model\\DashboardSection::TYPE_CHART') %}
|
||||
{% embed 'dashboard/section-chart.html.twig' with { section: row } %}{% endembed %}
|
||||
{% else %}
|
||||
{% embed 'dashboard/section-simple.html.twig' with { section: row } %}{% endembed %}
|
||||
{% endif %}
|
||||
{% for row in widgets %}
|
||||
{{ render_widget(row) }}
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
|
||||
{% if section.title %}
|
||||
{{ widgets.page_header(section.title) }}
|
||||
{% endif %}
|
||||
|
||||
{% set width = section.widgets|length %}
|
||||
{% set rawWidth = 12 / width %}
|
||||
{% set columnWidth = rawWidth|round(0, 'floor') %}
|
||||
<div class="row">
|
||||
{% for widget in section.widgets %}
|
||||
{% set columnSize = columnWidth %}
|
||||
{% if width == 5 and (loop.first or loop.last) %}
|
||||
{% set columnSize = columnWidth + 1 %}
|
||||
{% endif %}
|
||||
<div class="col-md-{{ columnSize }} col-sm-{{ columnSize * 2 }} col-xs-{{ columnSize * 4 }}">
|
||||
|
||||
{% set data = widget.data %}
|
||||
{% if widget.dataType == constant('App\\Model\\Widget::DATA_TYPE_DURATION') %}
|
||||
{% set data = widget.data|duration %}
|
||||
{% elseif widget.dataType == constant('App\\Model\\Widget::DATA_TYPE_MONEY') %}
|
||||
{% set data = widget.data|money %}
|
||||
{% endif %}
|
||||
|
||||
{% set url = null %}
|
||||
{% if widget.route %}
|
||||
{% set url = path(widget.route, widget.routeOptions) %}
|
||||
{% endif %}
|
||||
|
||||
{% set embedOptions = {data: data, title: widget.title, icon: widget.icon, color: widget.color, url: url} %}
|
||||
{% embed 'embeds/widget-'~widget.type~'.html.twig' with embedOptions %}{% endembed %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -1,10 +0,0 @@
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-{{ color|default('green') }}"><i class="{{ icon|icon(icon) }}"></i></span>
|
||||
|
||||
<div class="info-box-content">
|
||||
{% if url %}<a href="{{ url }}" class="small-box-footer">{% endif %}
|
||||
<span class="info-box-text">{{ title|trans }}</span>
|
||||
<span class="info-box-number">{{ data }}</span>
|
||||
{% if url %}</a>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,14 +0,0 @@
|
||||
<div class="small-box bg-{{ color|default('green') }}">
|
||||
<div class="inner">
|
||||
<h3>{{ data }}<sup style="font-size: 20px">{{ unit|default('') }}</sup></h3>
|
||||
<p>{{ title|trans }}</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="{{ icon|icon(icon) }}"></i>
|
||||
</div>
|
||||
{% if url %}
|
||||
<a href="{{ url }}" class="small-box-footer">
|
||||
{{ 'more.info.link'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -1,5 +1,8 @@
|
||||
{% macro progressbar(max, current, title, subTitle) %}
|
||||
{% set percentReached = (current / (max / 100)) %}
|
||||
{% set percentReached = 0 %}
|
||||
{% if max > 0 %}
|
||||
{% set percentReached = (current / (max / 100)) %}
|
||||
{% endif %}
|
||||
{% set class = "progress-bar-info" %}
|
||||
{% set width = percentReached|number_format(1, '.', '') %}
|
||||
|
||||
@@ -18,7 +21,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="progress-group">
|
||||
<span class="progress-text">{{ title }} – {{ percentReached|number_format(2) }}%</span>
|
||||
<span class="progress-text">{{ title }}{% if percentReached > 0 %} – {{ percentReached|number_format(2) }}%{% endif %}</span>
|
||||
<span class="progress-number">{{ subTitle }}</span>
|
||||
|
||||
<div class="progress">
|
||||
|
||||
@@ -254,29 +254,17 @@
|
||||
{% endif %}
|
||||
|
||||
<a class="{{ class | trim }}" href="{{ url }}"
|
||||
{%- if disabled is same as (true) -%}
|
||||
disabled="disabled"
|
||||
{%- endif -%}
|
||||
{%- if id is not empty -%}
|
||||
id="{{ id }}"
|
||||
{%- endif -%}
|
||||
{%- if toggle is not empty -%}
|
||||
data-toggle="{{ toggle }}"
|
||||
{%- endif -%}
|
||||
{%- if modal is not empty -%}
|
||||
data-toggle="modal" data-target="{{ modal }}"
|
||||
{%- endif -%}
|
||||
{%- if onclick is not empty -%}
|
||||
onclick="{{ onclick }}"
|
||||
{%- endif -%}
|
||||
{%- if target is not empty -%}
|
||||
target="{{ target }}"
|
||||
{%- endif -%}
|
||||
{%- if attr is not empty -%}
|
||||
{%- for name, value in attr %}
|
||||
{{- ' ' ~ name }}={% if '"' in value %}'{{ value|raw }}'{% else %}"{{ value|raw }}"{% endif %}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- if disabled is same as (true) %} disabled="disabled"{% endif %}
|
||||
{%- if id is not empty %} id="{{ id }}"{% endif %}
|
||||
{%- if toggle is not empty %} data-toggle="{{ toggle }}"{% endif %}
|
||||
{%- if modal is not empty %} data-toggle="modal" data-target="{{ modal }}"{% endif %}
|
||||
{%- if onclick is not empty %} onclick="{{ onclick }}"{% endif %}
|
||||
{%- if target is not empty %} target="{{ target }}"{% endif %}
|
||||
{%- if attr is not empty %}
|
||||
{% for name, value in attr %}
|
||||
{{ ' ' ~ name }}={% if '"' in value %}'{{ value|raw }}'{% else %}"{{ value|raw }}"{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
>{% if title is not null %}{{ title }}{% else %}{{ macro.icon(icon) }}{% endif %}</a>
|
||||
{% endapply %}
|
||||
{% endmacro %}
|
||||
|
||||
@@ -23,13 +23,8 @@
|
||||
{{ 'admin_project.short_stats'|trans(params)|raw }}
|
||||
</p>
|
||||
|
||||
{% if project.budget > 0 %}
|
||||
{{ progress.progressbar(project.budget, stats.recordRate, 'label.budget'|trans, stats.recordRate|money(project.customer.currency) ~ ' / ' ~ project.budget|money(project.customer.currency) ) }}
|
||||
{% endif %}
|
||||
|
||||
{% if project.timeBudget > 0 %}
|
||||
{{ progress.progressbar(project.timeBudget, stats.recordDuration, 'label.timeBudget'|trans, stats.recordDuration|duration ~ ' / ' ~ project.timeBudget|duration ) }}
|
||||
{% endif %}
|
||||
{{ progress.progressbar(project.budget, stats.recordRate, 'label.budget'|trans, stats.recordRate|money(project.customer.currency) ~ ' / ' ~ project.budget|money(project.customer.currency) ) }}
|
||||
{{ progress.progressbar(project.timeBudget, stats.recordDuration, 'label.timeBudget'|trans, stats.recordDuration|duration ~ ' / ' ~ project.timeBudget|duration ) }}
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
|
||||
|
||||
@@ -33,12 +33,22 @@
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
gridLines: {
|
||||
display: true,
|
||||
color: 'rgba(0,0,0,.05)',
|
||||
color: '{{ kimai_context.chart.grid_color }}',
|
||||
lineWidth: 1
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItem, data) {
|
||||
return data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -51,7 +61,7 @@
|
||||
{% block box_body %}
|
||||
|
||||
<div class="chart">
|
||||
<canvas id="userProfileChart{{ year }}" style="height: 200px;"></canvas>
|
||||
<canvas id="userProfileChart{{ year }}" style="height: {{ kimai_context.chart.height }}px;"></canvas>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('kimai.initialized', function() {
|
||||
@@ -60,11 +70,17 @@
|
||||
datasets: [
|
||||
{
|
||||
label: '{{ year }}',
|
||||
backgroundColor : '#00a65a',
|
||||
borderColor : '#00a65a',
|
||||
backgroundColor: '{{ kimai_context.chart.background_color }}',
|
||||
borderColor: '{{ kimai_context.chart.border_color }}',
|
||||
data: [
|
||||
{% for month in yearStat.months %}
|
||||
{{ (month.totalDuration / 3600)|round }}
|
||||
{{ (month.totalDuration / 3600)|number_format(2, '.', '') }}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
],
|
||||
realData : [
|
||||
{% for month in yearStat.months %}
|
||||
'{{ month.totalDuration|duration }}'
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
{% set chartWidget = section.widgets.0 %}
|
||||
{% set colors = chartWidget.color|split(';') %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
{#
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ section.title|trans }}</h3>
|
||||
<h3 class="box-title">{{ title|trans }}</h3>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
|
||||
</button>
|
||||
@@ -27,25 +25,7 @@
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{#
|
||||
<p class="text-center">
|
||||
<strong>
|
||||
{% for yearName, year in chartWidget.data|sort %}
|
||||
{% if loop.first or loop.last %}
|
||||
{% for id, month in year.months %}
|
||||
{% if loop.first %}
|
||||
moment.months({{ loop.index }}) {{ yearName }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if loop.first %} - {% endif %}
|
||||
{% endfor %}
|
||||
</strong>
|
||||
</p>
|
||||
#}
|
||||
<div class="chart">
|
||||
<canvas id="timeChart" style="height: 180px;"></canvas>
|
||||
</div>
|
||||
{{ render_widget(widgets.0) }}
|
||||
</div>
|
||||
{#
|
||||
<div class="col-md-4">
|
||||
@@ -85,17 +65,17 @@
|
||||
#}
|
||||
</div>
|
||||
</div>
|
||||
{% if section.widgets|length > 1 %}
|
||||
{% if widgets|length > 1 %}
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
{% set width = (section.widgets|length) - 1 %}
|
||||
{% set width = (widgets|length) - 1 %}
|
||||
{% set rawWidth = 12 / width %}
|
||||
{% set columnWidth = rawWidth|round(0, 'floor') %}
|
||||
{% for widget in section.widgets|slice(1, width) %}
|
||||
{% for widget in widgets|slice(1, width) %}
|
||||
{% set data = widget.data %}
|
||||
{% if widget.dataType == constant('App\\Model\\Widget::DATA_TYPE_DURATION') %}
|
||||
{% if widget.option('dataType') == 'duration' %}
|
||||
{% set data = widget.data|duration %}
|
||||
{% elseif widget.dataType == constant('App\\Model\\Widget::DATA_TYPE_MONEY') %}
|
||||
{% elseif widget.option('dataType') == 'money' %}
|
||||
{% set data = widget.data|money %}
|
||||
{% endif %}
|
||||
<div class="col-sm-{{ columnWidth }} col-xs-{{ columnWidth * 2 }}">
|
||||
@@ -113,63 +93,5 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<script>
|
||||
$(function () {
|
||||
'use strict';
|
||||
var timeChartData = {
|
||||
labels: moment.months(),
|
||||
datasets: [
|
||||
{% for yearName, year in chartWidget.data %}
|
||||
{% set yearColors = colors[loop.index-1]|split('|') %}
|
||||
{
|
||||
label : '{{ yearName }}',
|
||||
backgroundColor : '{{ yearColors.1 }}',
|
||||
borderColor : '{{ yearColors.0 }}',
|
||||
pointRadius : 2,
|
||||
borderWidth : 1,
|
||||
pointHitRadius : 10,
|
||||
lineTension : 0.3,
|
||||
data : [
|
||||
{% for month in year.months %}
|
||||
{{ (month.totalDuration / 3600)|round }}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
};
|
||||
|
||||
var timeChartOptions = {
|
||||
maintainAspectRatio : true,
|
||||
responsive : true,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
display: false
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
display: true,
|
||||
color: 'rgba(0,0,0,.05)',
|
||||
lineWidth: 1
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var timeChartCanvas = $('#timeChart').get(0).getContext('2d');
|
||||
|
||||
var timeChart = new Chart(
|
||||
timeChartCanvas, {
|
||||
type: 'line',
|
||||
data: timeChartData,
|
||||
options: timeChartOptions
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
20
templates/widget/section-simple.html.twig
Normal file
20
templates/widget/section-simple.html.twig
Normal file
@@ -0,0 +1,20 @@
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
|
||||
{% if not title is empty %}
|
||||
{{ widgets.page_header(title) }}
|
||||
{% endif %}
|
||||
|
||||
{% set width = widgets|length %}
|
||||
{% set rawWidth = 12 / width %}
|
||||
{% set columnWidth = rawWidth|round(0, 'floor') %}
|
||||
<div class="row">
|
||||
{% for widget in widgets %}
|
||||
{% set columnSize = columnWidth %}
|
||||
{% if width == 5 and (loop.first or loop.last) %}
|
||||
{% set columnSize = columnWidth + 1 %}
|
||||
{% endif %}
|
||||
<div class="col-md-{{ columnSize }} col-sm-{{ columnSize * 2 }} col-xs-{{ columnSize * 4 }}">
|
||||
{{ render_widget(widget) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
28
templates/widget/widget-counter.html.twig
Normal file
28
templates/widget/widget-counter.html.twig
Normal file
@@ -0,0 +1,28 @@
|
||||
{% set url = null %}
|
||||
{% if options.route is defined %}
|
||||
{% set url = path(options.route, options.routeOptions|default([])) %}
|
||||
{% endif %}
|
||||
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-{{ options.color|default('green') }}"><i class="{{ options.icon|icon(options.icon) }}"></i></span>
|
||||
|
||||
<div class="info-box-content">
|
||||
{% if not url is empty %}<a href="{{ url }}" class="small-box-footer">{% endif %}
|
||||
<span class="info-box-text">{{ title|trans }}</span>
|
||||
<span class="info-box-number">
|
||||
{% if data is iterable %}
|
||||
{{ 'Invalid data' }}
|
||||
{% else %}
|
||||
{% block widget_data %}
|
||||
{% if options.dataType == 'duration' %}
|
||||
{% set data = data|duration %}
|
||||
{% elseif options.dataType == 'money' %}
|
||||
{% set data = data|money %}
|
||||
{% endif %}
|
||||
{{ data }}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if not url is empty %}</a>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
95
templates/widget/widget-dailyworkingtimechart.html.twig
Normal file
95
templates/widget/widget-dailyworkingtimechart.html.twig
Normal file
@@ -0,0 +1,95 @@
|
||||
{% set type = options.type|default('bar') %}
|
||||
{% set chart_id = options.id %}
|
||||
{% set backgroundColor = kimai_context.chart.background_color %}
|
||||
{% set borderColor = kimai_context.chart.border_color %}
|
||||
{% set gridColor = kimai_context.chart.grid_color %}
|
||||
{% set colors = options.color|default('')|split(';') %}
|
||||
{% if colors.0 is defined and not colors.0 is empty %}
|
||||
{% 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 %}
|
||||
|
||||
{{ encore_entry_link_tags('chart') }}
|
||||
{{ encore_entry_script_tags('chart') }}
|
||||
|
||||
{% if not title is empty %}
|
||||
<p class="text-center">
|
||||
<strong>
|
||||
{{ title|trans }}
|
||||
</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="chart">
|
||||
<canvas id="{{ chart_id }}" style="height: {{ kimai_context.chart.height }}px;"></canvas>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('kimai.initialized', function() {
|
||||
new Chart(
|
||||
document.getElementById('{{ chart_id }}').getContext('2d'), {
|
||||
type: '{{ type }}',
|
||||
data: {
|
||||
labels: [
|
||||
{% for day in data -%}
|
||||
moment('{{ day.day|date_format(constant('\DateTime::ISO8601')) }}').format('ll')
|
||||
{% if not loop.last %},{% endif -%}
|
||||
{%- endfor %}
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
backgroundColor: '{{ backgroundColor }}',
|
||||
borderColor: '{{ borderColor }}',
|
||||
data: [
|
||||
{% for day in data -%}
|
||||
{{ (day.totalDuration / 3600)|number_format(2, '.', '') }}
|
||||
{%- if not loop.last %},{% endif -%}
|
||||
{%- endfor %}
|
||||
],
|
||||
realData: [
|
||||
{% for day in data -%}
|
||||
'{{ day.totalDuration|duration }}'
|
||||
{%- if not loop.last %},{% endif -%}
|
||||
{%- endfor %}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: true,
|
||||
responsive: true,
|
||||
legend: false,
|
||||
barPercentage: 0.5,
|
||||
categoryPercentage: 0.9,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
display: false
|
||||
},
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
gridLines: {
|
||||
display: true,
|
||||
color: '{{ gridColor }}',
|
||||
lineWidth: 1
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItem, data) {
|
||||
return data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
33
templates/widget/widget-more.html.twig
Normal file
33
templates/widget/widget-more.html.twig
Normal file
@@ -0,0 +1,33 @@
|
||||
{% set url = null %}
|
||||
{% if options.route is defined %}
|
||||
{% set url = path(options.route, options.routeOptions|default([])) %}
|
||||
{% endif %}
|
||||
|
||||
<div class="small-box bg-{{ options.color|default('green') }}">
|
||||
<div class="inner">
|
||||
<h3>
|
||||
{% if data is iterable %}
|
||||
{{ 'Invalid data' }}
|
||||
{% else %}
|
||||
{% block widget_data %}
|
||||
{% if options.dataType == 'duration' %}
|
||||
{% set data = data|duration %}
|
||||
{% elseif options.dataType == 'money' %}
|
||||
{% set data = data|money %}
|
||||
{% endif %}
|
||||
{{ data }}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
<sup style="font-size: 20px">{{ unit|default('') }}</sup>
|
||||
</h3>
|
||||
<p>{{ title|trans }}</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="{{ options.icon|icon(options.icon) }}"></i>
|
||||
</div>
|
||||
{% if not url is empty %}
|
||||
<a href="{{ url }}" class="small-box-footer">
|
||||
{{ 'more.info.link'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
98
templates/widget/widget-yearchart.html.twig
Normal file
98
templates/widget/widget-yearchart.html.twig
Normal file
@@ -0,0 +1,98 @@
|
||||
{% set backgroundColor = kimai_context.chart.background_color %}
|
||||
{% set borderColor = kimai_context.chart.border_color %}
|
||||
{% set gridColor = kimai_context.chart.grid_color %}
|
||||
{% set colors = options.color|default('')|split(';') %}
|
||||
{% set type = options.type|default('line') %}
|
||||
{% if type not in ['line', 'bar'] %}
|
||||
{% set type = 'line' %}
|
||||
{% endif %}
|
||||
|
||||
{% if not title is empty %}
|
||||
<p class="text-center">
|
||||
<strong>
|
||||
{{ title|trans }}
|
||||
</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="chart">
|
||||
<canvas id="timeChart" style="height: {{ kimai_context.chart.height }}px;"></canvas>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('kimai.initialized', function() {
|
||||
new Chart(
|
||||
document.getElementById('timeChart').getContext('2d'), {
|
||||
type: '{{ type }}',
|
||||
data: {
|
||||
labels: moment.months(),
|
||||
datasets: [
|
||||
{% for yearName, year in data %}
|
||||
{% set yearBackgroundColor = backgroundColor %}
|
||||
{% set yearBorderColor = borderColor %}
|
||||
|
||||
{% if colors[loop.index-1] is defined %}
|
||||
{% set yearColors = colors[loop.index-1]|split('|') %}
|
||||
{% if yearColors.0 is defined and not yearColors.0 is empty %}
|
||||
{% set yearBackgroundColor = yearColors.0 %}
|
||||
{% set yearBorderColor = yearColors.0 %}
|
||||
{% if yearColors.1 is defined and not yearColors.1 is empty %}
|
||||
{% set yearBorderColor = yearColors.1 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{
|
||||
label : '{{ yearName }}',
|
||||
backgroundColor : '{{ yearBackgroundColor }}',
|
||||
borderColor : '{{ yearBorderColor }}',
|
||||
pointRadius : 2,
|
||||
borderWidth : 1,
|
||||
pointHitRadius : 10,
|
||||
lineTension : 0.3,
|
||||
data : [
|
||||
{% for month in year.months %}
|
||||
{{ (month.totalDuration / 3600)|number_format(2, '.', '') }}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
],
|
||||
realData : [
|
||||
{% for month in year.months %}
|
||||
'{{ month.totalDuration|duration }}'
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: true,
|
||||
responsive: true,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
display: false
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
display: true,
|
||||
color: '{{ gridColor }}',
|
||||
lineWidth: 1
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItem, data) {
|
||||
return data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user