templates/statistiques/resources.html.twig line 1
{% extends 'base.html.twig' %}
{% block title %}WFO Stat{% endblock %}
{% block body %}
<div class="row" id="divStats" style="display:none">
<div class="row margin-bottom-3">
<div class="col-md-2">
<div class="container-resa float-left">
<div class="div-bordred">
<div class="d-flex title-box">
<img src="{{ asset('assets/img/paper.svg') }}" class="img-fluid">
<h4>{{ 'Booking'|trans }}</h4>
</div>
<span id="nbrReservation">
<div class="loader"></div>
</span>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="col-md-6">
<div class="box-shart">
<div class="pieChart display-center" id="statusChart">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="box-shart">
<div class="pieChart display-center" id="immediateChart">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="box-shart">
<div class="pieChart display-center" id="originChart">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="box-shart">
<div class="pieChart display-center" id="resourceByTypeChart">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{"by Site"|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="resourceBySite">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{"by Stage"|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="resourceByStage">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{"by Zone"|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="resourceByZone">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{"by Resource Type"|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="resourceByStackingDiagram">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3 align-items-center">
<div class="title-block row align-items-center">
<div class="col-md-2"><h5>{{ 'Occupancy rate'|trans }}</h5></div>
<div class="col-md-10"><hr></div>
</div>
<div class="col-md-8">
<div class="box-shart">
<div class="pieChart display-center" id="tauxOccupation">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="box-shart-2">
<span id="tauxOccupationTotal">
<div class="loader"></div>
</span>
<h4>{{ 'Occupancy rate'|trans }}</h4>
</div>
</div>
</div>
<div class="row margin-bottom-3 align-items-center">
<div class="title-block row align-items-center">
<div class="col-md-4"><h5>{{ 'Occupancy rate'|trans }} 9h-12h 14h-17h</h5></div>
<div class="col-md-8"><hr></div>
</div>
<div class="col-md-8">
<div class="box-shart">
<div class="pieChart display-center" id="tauxOccupationReal">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="box-shart-2">
<span id="tauxOccupationRealTotal">
<div class="loader"></div>
</span>
<h4>{{ 'Occupancy rate'|trans }}</h4>
</div>
</div>
</div>
<div class="row margin-bottom-3 align-items-center">
<div class="title-block row align-items-center">
<div class="col-md-4"><h5>{{ 'Daily occupancy rate'|trans }}</h5></div>
<div class="col-md-8"><hr></div>
</div>
<div class="col-md-8">
<div class="box-shart">
<div class="pieChart display-center" id="tauxOccupationByWeekDay">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="box-shart-2">
<span id="tauxOccupationByWeekDayTotal">
<div class="loader"></div>
</span>
<h4>{{ 'Occupancy rate'|trans }} </h4>
</div>
</div>
</div>
<div class="row margin-bottom-3 align-items-center">
<div class="title-block row align-items-center">
<div class="col-md-4"><h5>{{ 'Peak_occupancy_rate_per_day'|trans }} </h5></div>
<div class="col-md-8"><hr></div>
</div>
<div class="col-md-8">
<div class="box-shart">
<div class="pieChart display-center" id="tauxOccupationDesPickByDate">
<div class="loader"></div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="box-shart-2">
<span id="tauxOccupationDesPickByDateTotal">
<div class="loader"></div>
</span>
<h4>{{ 'Occupancy rate'|trans }} </h4>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{"per time slot"|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="chartCreneau">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{'Reservation per day'|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="reservationByDay">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{'Top 5 resources'|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="topRessources">
<div class="loader"></div>
</div>
</div>
</div>
</div>
<div class="row margin-bottom-3">
<div class="title-block row align-items-center">
<div class="col-md-3"><h5>{{'Top 10 users'|trans}}</h5></div>
<div class="col-md-9"><hr></div>
</div>
<div class="col-md-12">
<div class="box-shart">
<div class="pieChart display-center" id="topUsers">
<div class="loader"></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
var topResources = [];
var reservationByDay = [];
var tauxOccupation = [];
var tauxOccupationReal = [];
var resourceTypeSelected = [
{% for item in typeResources %}
{{ item.id }}
{% if loop.last == false %},{% endif %}
{% endfor %}
]
var localisationSelected = [
{% for item in localisations %}
{{ item.id }}
{% if loop.last == false %},{% endif %}
{% endfor %}
]
$(document).ready(function() {
const treeResourcesTree = new Treeselect({
parentHtmlContainer: document.querySelector('#typeResourcesTree'),
value: resourceTypeSelected,
options: JSON.parse(`{{ typeResourcesTree|json_encode|raw }}`),
});
treeResourcesTree.srcElement.addEventListener('input', (e) => {
resourceTypeSelected = e.detail;
})
const treeLocalisation = new Treeselect({
parentHtmlContainer: document.querySelector('#localisationsTree'),
value: localisationSelected,
options: JSON.parse(`{{ localisationsTree|json_encode|raw }}`),
})
treeLocalisation.srcElement.addEventListener('input', (e) => {
localisationSelected = e.detail;
})
})
function getReservation() {
if (!!!$('#startDate').val() || !!!$('#endDate').val()) {
toastr.error("{{'Please select the start and end dates.'|trans}}");
return;
}
const status = $('[data-type="status"]').map(function () {
if ($(this).is(':checked'))
return $(this).val();
}).get();
if (status.length == 0 ) {
toastr.error("{{'Please select at least one status.'|trans}}");
return;
}
if (localisationSelected.length == 0 ) {
toastr.error("{{'Please select at least one location.'|trans}}");
return;
}
if (resourceTypeSelected.length == 0 ) {
toastr.error("{{'Please select at least one type of resource.'|trans}}");
return;
}
const resource = $('#txtResource').val() != '' ? $('#txtResource').val() : null;
initCharts()
getTotalReservation(localisationSelected,resourceTypeSelected,status,resource);
}
function getTotalReservation(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getReservation') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
document.getElementById('nbrReservation').innerHTML = response['totalReservations'];
getStatus(localisationSelected,resourceTypeSelected,status,resource);
if (response['totalReservations']) {
$('#divStats').css('display', '');
}
}
});
}
function getStatus(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getStatus') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
getOrigin(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'statusChart',response['reservationStatus']),
)
}
});
}
function getOrigin(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getOrigin') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
getImmediate(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'originChart',response['reservationOrigin']),
)
}
});
}
function getImmediate(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getImmediate') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
getTypeSite(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'immediateChart',response['immediateReservation']),
)
}
});
}
function getTypeSite(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getTypeSite') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
$('#divStats').css('display', '');
getByStage(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'resourceBySite',response['resourceBySite']),
)
}
});
}
function getByStage(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getByStage') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
$('#divStats').css('display', '');
getWithoutSite(localisationSelected,resourceTypeSelected,status,resource);
const seriesLabel = {'{{ "Confirmed"|trans }}':0,'{{ "Refused"|trans }}':0,'{{ "Pending"|trans }}':0,'{{ "Cancelled"|trans }}':0};
am5.ready(
getStacksDiagram(am5,"resourceByStage",response['resourceByStage'],seriesLabel, false),
)
}
});
}
function getWithoutSite(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getWithoutSite') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
$('#divStats').css('display', '');
getByZone(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getStacksDiagram(am5,"resourceByStackingDiagram",response['resourceByStackingDiagram'],response['resourceWithoutSite'],false)
)
}
});
}
function getByZone(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getByZone') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
$('#divStats').css('display', '');
getStatsCreneau(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'resourceByZone',response['resourceByZone'],true),
)
}
});
}
function getByZone(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getByZone') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
$('#divStats').css('display', '');
getByType(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'resourceByZone',response['resourceByZone'],true),
)
}
});
}
function getByType(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getByType') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
$('#divStats').css('display', '');
getStatsCreneau(localisationSelected,resourceTypeSelected,status,resource);
am5.ready(
getDataByHistograme(am5,'resourceByTypeChart',response['resourceByType']),
)
}
});
}
function getStatsCreneau(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('getCreneau') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
reservationByDay = response['reservationByDay'];
topResources = response['topResources'];
tauxOccupation = response['tauxOccupation'];
tauxOccupationReal = response['tauxOccupationReal'];
document.getElementById('tauxOccupationTotal').innerHTML = response['tauxOccupationTotal'] + '%';
document.getElementById('tauxOccupationByWeekDayTotal').innerHTML = response['tauxOccupationTotal'] + '%';
document.getElementById('tauxOccupationDesPickByDateTotal').innerHTML = response['tauxOccupationDesPickByDateTotal'] + '%';
document.getElementById('tauxOccupationRealTotal').innerHTML = response['tauxOccupationRealTotal'] + '%';
getTopUsers(localisation,resourceType,status,resource);
const seriesLabel = {'{{ "Confirmed"|trans }}':0,'{{ "Refused"|trans }}':0,'{{ "Pending"|trans }}':0,'{{ "Cancelled"|trans }}':0};
am5.ready(
getStacksDiagram(am5,"topRessources",response['topResources'],seriesLabel, true),
getChartCreneau(am5),
getTauxOccupation(am5,"tauxOccupation",tauxOccupation,"hour"),
getTauxOccupation(am5,"tauxOccupationReal",tauxOccupationReal,"hour"),
getTauxOccupation(am5,"tauxOccupationByWeekDay",response['tauxOccupationByWeekDay'],"day"),
getTauxOccupation(am5,"tauxOccupationDesPickByDate",response['tauxOccupationDesPickByDate'],"date"),
getReservationByDay(am5),
)
}
});
}
function getTopUsers(localisation,resourceType,status,resource) {
$.ajax({
type: "POST",
url: "{{ path('top_users') }}",
data: {
localisation: localisation.join(),
resourceType: resourceType.join(),
status: status.join(),
resource: resource,
user: $('#txtUser').val() ?? null,
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
success: function(response) {
getDataByHistograme(am5,'topUsers',response['topUsers']);
}
});
}
function initCharts() {
document.getElementById("nbrReservation").outerHTML = '<span id="nbrReservation">~</span>'
document.getElementById("topRessources").outerHTML = '<div class="pieChart display-center" id="topRessources"><div class="loader"></div></div>'
document.getElementById("reservationByDay").outerHTML = '<div class="pieChart display-center" id="reservationByDay"><div class="loader"></div></div>'
document.getElementById("chartCreneau").outerHTML = '<div class="pieChart display-center" id="chartCreneau"><div class="loader"></div></div>'
document.getElementById("tauxOccupationTotal").outerHTML = '<span class="display-center" id="tauxOccupationTotal"><div class="loader"></div></span>'
document.getElementById("tauxOccupation").outerHTML = '<div class="pieChart display-center" id="tauxOccupation"><div class="loader"></div></div>'
document.getElementById("tauxOccupationReal").outerHTML = '<div class="pieChart display-center" id="tauxOccupationReal"><div class="loader"></div></div>'
document.getElementById("tauxOccupationByWeekDay").outerHTML = '<div class="pieChart display-center" id="tauxOccupationByWeekDay"><div class="loader"></div></div>'
document.getElementById("tauxOccupationByWeekDayTotal").outerHTML = '<span class="display-center" id="tauxOccupationByWeekDayTotal"><div class="loader"></div></span>'
document.getElementById("tauxOccupationDesPickByDate").outerHTML = '<div class="pieChart display-center" id="tauxOccupationDesPickByDate"><div class="loader"></div></div>'
document.getElementById("tauxOccupationDesPickByDateTotal").outerHTML = '<span class="display-center" id="tauxOccupationDesPickByDateTotal"><div class="loader"></div></span>'
document.getElementById("resourceBySite").outerHTML = '<div class="pieChart display-center" id="resourceBySite"><div class="loader"></div></div> '
document.getElementById("resourceByStage").outerHTML = '<div class="pieChart display-center" id="resourceByStage"><div class="loader"></div></div> '
document.getElementById("resourceByZone").outerHTML = '<div class="pieChart display-center" id="resourceByZone"><div class="loader"></div></div> '
document.getElementById("resourceByTypeChart").outerHTML = '<div class="pieChart display-center" id="resourceByTypeChart"><div class="loader"></div></div>'
document.getElementById("originChart").outerHTML = '<div class="pieChart display-center" id="originChart"><div class="loader"></div></div>'
document.getElementById("immediateChart").outerHTML = '<div class="pieChart display-center" id="immediateChart"><div class="loader"></div></div>'
document.getElementById("statusChart").outerHTML = '<div class="pieChart display-center" id="statusChart"><div class="loader"></div></div>'
document.getElementById("resourceByStackingDiagram").outerHTML = '<div class="pieChart display-center" id="resourceByStackingDiagram"><div class="loader"></div></div>'
}
function camembertChart(am5,component,data) {
document.getElementById(component).outerHTML = '<div class="pieChart" id="' + component + '"></div>';
if(data && data.length===0) {
const no_result = '{{'no_results'|trans}}';
document.getElementById(component).outerHTML= '<div class="pieChart" id="' + component + '"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
}
var myChart = am5.Root.new(component);
myChart._logo.dispose();
myChart.setThemes([
am5themes_Animated.new(myChart)
]);
var chart = myChart.container.children.push(am5percent.PieChart.new(myChart, {
layout: myChart.verticalLayout,
innerRadius: am5.percent(70)
}));
var series = chart.series.push(am5percent.PieSeries.new(myChart, {
valueField: "value",
categoryField: "item",
tooltip: am5.Tooltip.new(myChart, {pointerOrientation: "left",
labelText: "{category}: {valuePercentTotal.formatNumber('0.00')}%[/] [bold]({value})"}),
legendValueText: "[bold]{value}",
}));
series.labels.template.set("text", "{category}: [bold]{value}");
series.labels.template.setAll({
textType: "circular",
centerX: 0,
centerY: 0,
fontSize: 14
});
series.data.setAll(data);
var legend = chart.children.push(am5.Legend.new(myChart, {
centerX: am5.percent(50),
x: am5.percent(50),
marginTop: 15,
marginBottom: 15
}));
legend.data.setAll(series.dataItems);
legend.labels.template.setAll({
fontSize: 14
});
legend.valueLabels.template.setAll({
fontSize: 14
});
// legend.itemContainers.template.togglable = false;
series.appear(100, 1000);
}
function getDataByHistograme(am5,component,data,withScroll=false) {
document.getElementById(component).outerHTML = '<div class="pieChart box-shart" id="' + component + '"></div>';
if(data && data.length===0) {
const no_result = '{{'no_results'|trans}}';
document.getElementById(component).outerHTML = '<div class="pieChart box-shart" id="' + component + '"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
}
$( "#"+ component ).parent().attr("class", "col-md-12")
// originChart
var root = am5.Root.new(component);
root._logo.dispose();
// Set themes
root.setThemes([
am5themes_Animated.new(root)
]);
// Create chart
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
layout: root.verticalLayout
}));
// We don't want zoom-out button to appear while animating, so we hide it
chart.zoomOutButton.set("forceHidden", true);
if(withScroll){
const scrollableContainer = chart.chartContainer.children.unshift(am5.Container.new(root, {
width: am5.p100, height: am5.p100, verticalScrollbar: am5.Scrollbar.new(root, {
orientation: "vertical",
dx: 20
})
}));
{# chart.yAxesAndPlotContainer.set("height", 500);
chart.yAxesAndPlotContainer.set("paddingBottom", 3) #}
scrollableContainer.children.push(chart.yAxesAndPlotContainer);
}
// Create axes
var yRenderer = am5xy.AxisRendererY.new(root, {
minGridDistance: 10
});
yRenderer.grid.template.set("location", 1);
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
maxDeviation: 0,
categoryField: "item",
renderer: yRenderer,
tooltip: am5.Tooltip.new(root, { themeTags: ["axis"] })
}));
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
maxDeviation: 0,
min: 0,
extraMax: 1,
renderer: am5xy.AxisRendererX.new(root, {
strokeOpacity: 0.1
})
}));
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: "Series 1",
xAxis: xAxis,
yAxis: yAxis,
valueXField: "value",
categoryYField: "item",
tooltip: am5.Tooltip.new(root, {
pointerOrientation: "left",
labelText: "{valueX}"
})
}));
// Rounded corners for columns
series.columns.template.setAll({
cornerRadiusTR: 1,
cornerRadiusBR: 1,
strokeOpacity: 0
});
// Make each column to be of a different color
series.columns.template.adapters.add("fill", function(fill, target) {
return chart.get("colors").getIndex(series.columns.indexOf(target));
});
series.columns.template.adapters.add("stroke", function(stroke, target) {
return chart.get("colors").getIndex(series.columns.indexOf(target));
});
yAxis.data.setAll(data);
series.data.setAll(data);
sortCategoryAxiss();
// Get series item by category
function getSeriesItem(category) {
for (var i = 0; i < series.dataItems.length; i++) {
let dataItem = series.dataItems[i];
if (dataItem.get("categoryY") == category) {
return dataItem;
}
}
}
chart.set("cursor", am5xy.XYCursor.new(root, {
behavior: "none",
xAxis: xAxis,
yAxis: yAxis
}));
// Axis sorting
function sortCategoryAxiss() {
// Sort by value
series.dataItems.sort(function(x, y) {
return x.get("valueX") - y.get("valueX"); // descending
//return y.get("valueY") - x.get("valueX"); // ascending
})
// Go through each axis item
am5.array.each(yAxis.dataItems, function(dataItem) {
// get corresponding series item
let seriesDataItem = getSeriesItem(dataItem.get("category"));
if (seriesDataItem) {
// get index of series data item
let index = series.dataItems.indexOf(seriesDataItem);
// calculate delta position
let deltaPosition = (index - dataItem.get("index", 0)) / series.dataItems.length;
// set index to be the same as series data item index
dataItem.set("index", index);
// set deltaPosition instanlty
dataItem.set("deltaPosition", -deltaPosition);
// animate delta position to 0
dataItem.animate({
key: "deltaPosition",
to: 0,
duration: 1000,
easing: am5.ease.out(am5.ease.cubic)
})
}
});
// Sort axis items by index.
// This changes the order instantly, but as deltaPosition is set,
// they keep in the same places and then animate to true positions.
yAxis.dataItems.sort(function(x, y) {
return x.get("index") - y.get("index");
});
}
}
function getStacksDiagram(am5,elementId,data,seriesLabel,horizontal){
document.getElementById(elementId).outerHTML = '<div class="pieChart box-shart" id="'+elementId+'"></div>';
// Create root element
var root = am5.Root.new(elementId);
root.setThemes([
am5themes_Animated.new(root)
]);
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
layout: root.verticalLayout
}));
if (horizontal) {
var theRenderer = am5xy.AxisRendererY.new(root, {});
var firstAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "item",
renderer: theRenderer,
tooltip: am5.Tooltip.new(root, {})
}));
var secondeAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
min: 0,
renderer: am5xy.AxisRendererX.new(root, {
strokeOpacity: 0.1
})
}));
}else {
var theRenderer = am5xy.AxisRendererX.new(root, {});
var firstAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "item",
renderer: theRenderer,
tooltip: am5.Tooltip.new(root, {})
}));
var secondeAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
min: 0,
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
}
theRenderer.grid.template.setAll({
location: 100
})
firstAxis.data.setAll(data);
var legend = chart.children.push(am5.Legend.new(root, {
centerX: am5.p50,
x: am5.p50
}));
function makeSeries(name) {
if (horizontal) {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
stacked: true,
xAxis: secondeAxis,
yAxis: firstAxis,
baseAxis: firstAxis,
valueXField: name,
categoryYField: "item"
}));
}else {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
stacked: true,
xAxis: firstAxis,
yAxis: secondeAxis,
baseAxis: firstAxis,
valueYField: name,
categoryXField: "item"
}));
}
series.columns.template.setAll({
tooltipText: (horizontal ? "{valueX} " : "{valueY} ") + "{{ 'Booking'|trans }} {name}",
tooltipY: am5.percent(90)
});
series.data.setAll(data);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
series.bullets.push(function() {
return am5.Bullet.new(root, {
sprite: am5.Label.new(root, {
text: "",
fill: root.interfaceColors.get("alternativeText"),
centerY: am5.p0,
centerX: am5.p50,
populateText: true
})
});
});
legend.data.push(series);
}
Object.keys(seriesLabel).forEach(key => {
makeSeries(key)
});
chart.appear(1000, 100);
}
function getTopRessources(am5) {
document.getElementById('topRessources').outerHTML = '<div class="pieChart" id="topRessources"></div>';
if(topResources && topResources.length===0) {
const no_result = '{{'no_results'|trans}}';
document.getElementById('topRessources').outerHTML = '<div class="pieChart" id="topRessources"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
}
var topRessources = am5.Root.new("topRessources");
topRessources._logo.dispose();
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
topRessources.setThemes([
am5themes_Animated.new(topRessources)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = topRessources.container.children.push(am5xy.XYChart.new(topRessources, {
panX: false,
panY: false,
wheelX: "none",
wheelY: "none"
}));
// We don't want zoom-out button to appear while animating, so we hide it
chart.zoomOutButton.set("forceHidden", true);
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var yRenderer = am5xy.AxisRendererY.new(topRessources, {
minGridDistance: 30
});
yRenderer.grid.template.set("location", 1);
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(topRessources, {
maxDeviation: 0,
categoryField: "item",
renderer: yRenderer,
tooltip: am5.Tooltip.new(topRessources, { themeTags: ["axis"] })
}));
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(topRessources, {
maxDeviation: 0,
min: 0,
extraMax: 1,
renderer: am5xy.AxisRendererX.new(topRessources, {
strokeOpacity: 0.1
})
}));
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.ColumnSeries.new(topRessources, {
name: "Series 1",
xAxis: xAxis,
yAxis: yAxis,
valueXField: "value",
categoryYField: "item",
tooltip: am5.Tooltip.new(topRessources, {
pointerOrientation: "left",
labelText: "{valueX} {{ 'Booking'|trans }}"
})
}));
// Rounded corners for columns
series.columns.template.setAll({
cornerRadiusTR: 1,
cornerRadiusBR: 1,
strokeOpacity: 0
});
// Make each column to be of a different color
series.columns.template.adapters.add("fill", function(fill, target) {
return chart.get("colors").getIndex(series.columns.indexOf(target));
});
series.columns.template.adapters.add("stroke", function(stroke, target) {
return chart.get("colors").getIndex(series.columns.indexOf(target));
});
yAxis.data.setAll(topResources);
series.data.setAll(topResources);
sortCategoryAxiss();
// Get series item by category
function getSeriesItem(category) {
for (var i = 0; i < series.dataItems.length; i++) {
let dataItem = series.dataItems[i];
if (dataItem.get("categoryY") == category) {
return dataItem;
}
}
}
chart.set("cursor", am5xy.XYCursor.new(topRessources, {
behavior: "none",
xAxis: xAxis,
yAxis: yAxis
}));
// Axis sorting
function sortCategoryAxiss() {
// Sort by value
series.dataItems.sort(function(x, y) {
return x.get("valueX") - y.get("valueX"); // descending
//return y.get("valueY") - x.get("valueX"); // ascending
})
// Go through each axis item
am5.array.each(yAxis.dataItems, function(dataItem) {
// get corresponding series item
let seriesDataItem = getSeriesItem(dataItem.get("category"));
if (seriesDataItem) {
// get index of series data item
let index = series.dataItems.indexOf(seriesDataItem);
// calculate delta position
let deltaPosition = (index - dataItem.get("index", 0)) / series.dataItems.length;
// set index to be the same as series data item index
dataItem.set("index", index);
// set deltaPosition instanlty
dataItem.set("deltaPosition", -deltaPosition);
// animate delta position to 0
dataItem.animate({
key: "deltaPosition",
to: 0,
duration: 1000,
easing: am5.ease.out(am5.ease.cubic)
})
}
});
// Sort axis items by index.
// This changes the order instantly, but as deltaPosition is set,
// they keep in the same places and then animate to true positions.
yAxis.dataItems.sort(function(x, y) {
return x.get("index") - y.get("index");
});
}
}
function getChartCreneau(am5) {
document.getElementById('chartCreneau').outerHTML = '<div class="pieChart" id="chartCreneau"></div>';
if(tauxOccupation && tauxOccupation.length===0) {
const no_result = '{{'no_results'|trans}}';
document.getElementById('chartCreneau').outerHTML = '<div class="pieChart" id="chartCreneau"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
}
var root = am5.Root.new("chartCreneau");
root._logo.dispose();
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: "panX",
wheelY: "zoomX",
layout: root.verticalLayout
}));
var legend = chart.children.push(
am5.Legend.new(root, {
centerX: am5.p50,
x: am5.p50
})
);
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var xRenderer = am5xy.AxisRendererX.new(root, {
cellStartLocation: 0.1,
cellEndLocation: 0.9
})
var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "hour",
renderer: xRenderer,
tooltip: am5.Tooltip.new(root, {})
}));
xRenderer.grid.template.setAll({
location: 1
})
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
xAxis.data.setAll(tauxOccupation);
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
function makeSeries(name, fieldName) {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueYField: fieldName,
categoryXField: "hour"
}));
series.columns.template.setAll({
tooltipText: "{name}, {categoryX} - {valueY} {{ 'Booking'|trans }}",
width: am5.percent(90),
tooltipY: 0,
strokeOpacity: 0
});
series.data.setAll(tauxOccupation);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
series.bullets.push(function() {
return am5.Bullet.new(root, {
locationY: 0,
sprite: am5.Label.new(root, {
text: "{valueY}",
fill: root.interfaceColors.get("alternativeText"),
centerY: 0,
centerX: am5.p50,
populateText: true
})
});
});
legend.data.push(series);
}
makeSeries('{{"Reserved occupancy"|trans}}', "reservation");
makeSeries('{{"Real occupation"|trans}}', "reservation_reel");
chart.appear(1000, 100);
}
function getTauxOccupation(am5,element, data,categoryXField) {
document.getElementById(element).outerHTML = '<div class="pieChart" id="'+ element +'"></div>';
if(data && data.length===0) {
const no_result = '{{'no_results'|trans}}';
document.getElementById(element).outerHTML = '<div class="pieChart" id="'+ element +'"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
}
var root = am5.Root.new(element);
root._logo.dispose();
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: "panX",
wheelY: "zoomX",
layout: root.verticalLayout
}));
var legend = chart.children.push(
am5.Legend.new(root, {
centerX: am5.p50,
x: am5.p50
})
);
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var xRenderer = am5xy.AxisRendererX.new(root, {
cellStartLocation: 0.1,
cellEndLocation: 0.9
})
var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: categoryXField,
renderer: xRenderer,
tooltip: am5.Tooltip.new(root, {})
}));
xRenderer.grid.template.setAll({
location: 1
})
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
xAxis.data.setAll(data);
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
function makeSeries(name, fieldName) {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueYField: fieldName,
categoryXField: categoryXField
}));
series.columns.template.setAll({
tooltipText: "{name}, {categoryX} - {valueY}%",
width: am5.percent(90),
tooltipY: 0,
strokeOpacity: 0
});
series.data.setAll(data);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
series.bullets.push(function() {
return am5.Bullet.new(root, {
locationY: 0,
sprite: am5.Label.new(root, {
text: "{valueY}",
fill: root.interfaceColors.get("alternativeText"),
centerY: 0,
centerX: am5.p50,
populateText: true
})
});
});
legend.data.push(series);
}
makeSeries('{{"Reserved occupancy"|trans}}', "tauxOccupation");
makeSeries('{{"Real occupation"|trans}}', "tauxOccupationReal");
chart.appear(1000, 100);
}
function getReservationByDay(am5) {
document.getElementById('reservationByDay').outerHTML = '<div class="pieChart" id="reservationByDay"></div>';
if(reservationByDay.length===0) {
const no_result = '{{'no_results'|trans}}';
document.getElementById('reservationByDay').outerHTML = '<div class="pieChart" id="reservationByDay"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
}
var root = am5.Root.new("reservationByDay");
root._logo.dispose();
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: "panX",
wheelY: "zoomX",
layout: root.verticalLayout
}));
var legend = chart.children.push(
am5.Legend.new(root, {
centerX: am5.p50,
x: am5.p50
})
);
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var xRenderer = am5xy.AxisRendererX.new(root, {
cellStartLocation: 0.1,
cellEndLocation: 0.9
})
var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "date",
renderer: xRenderer,
tooltip: am5.Tooltip.new(root, {})
}));
xRenderer.grid.template.setAll({
location: 1
})
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
xAxis.data.setAll(reservationByDay);
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1
})
}));
function makeSeries(name, fieldName) {
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueYField: fieldName,
categoryXField: "date"
}));
series.columns.template.setAll({
tooltipText: "{categoryX} - {valueY} {{ 'Booking'|trans }}",
width: am5.percent(90),
tooltipY: 0,
strokeOpacity: 0
});
series.data.setAll(reservationByDay);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
series.bullets.push(function() {
return am5.Bullet.new(root, {
locationY: 0,
sprite: am5.Label.new(root, {
text: "{valueY}",
fill: root.interfaceColors.get("alternativeText"),
centerY: 0,
centerX: am5.p50,
populateText: true
})
});
});
legend.data.push(series);
}
makeSeries('{{"Number of reservations"|trans}}', "value");
chart.appear(1000, 100);
}
</script>
{% endblock %}