templates/statistiques/resources.html.twig line 1

  1. {% extends 'base.html.twig' %}
  2. {% block title %}WFO Stat{% endblock %}
  3. {% block body %}
  4.     
  5.     <div class="row" id="divStats" style="display:none">
  6.         <div class="row margin-bottom-3">
  7.             <div class="col-md-2">
  8.                 <div class="container-resa float-left">
  9.                     <div class="div-bordred">
  10.                         <div class="d-flex title-box">
  11.                             <img src="{{ asset('assets/img/paper.svg') }}" class="img-fluid">
  12.                             <h4>{{ 'Booking'|trans }}</h4>
  13.                         </div>
  14.                         <span id="nbrReservation">
  15.                             <div class="loader"></div>
  16.                         </span>
  17.                     </div>
  18.                 </div>
  19.             </div>
  20.         </div>
  21.         <div class="row margin-bottom-3">
  22.             <div class="col-md-6">
  23.                 <div class="box-shart">
  24.                     <div class="pieChart display-center" id="statusChart">
  25.                         <div class="loader"></div>
  26.                     </div>
  27.                 </div>
  28.             </div>
  29.             <div class="col-md-6">
  30.                 <div class="box-shart">
  31.                     <div class="pieChart display-center" id="immediateChart">
  32.                         <div class="loader"></div>
  33.                     </div>
  34.                 </div>
  35.             </div>
  36.             <div class="col-md-6">
  37.                 <div class="box-shart">
  38.                     <div class="pieChart display-center" id="originChart">
  39.                         <div class="loader"></div>
  40.                     </div>
  41.                 </div>    
  42.             </div>
  43.             <div class="col-md-6">
  44.                 <div class="box-shart">
  45.                     <div class="pieChart display-center" id="resourceByTypeChart">
  46.                         <div class="loader"></div>
  47.                     </div>
  48.                 </div>    
  49.             </div>
  50.         </div>
  51.         <div class="row margin-bottom-3">
  52.             <div class="title-block row align-items-center">
  53.                 <div class="col-md-3"><h5>{{"by Site"|trans}}</h5></div>
  54.                 <div class="col-md-9"><hr></div>
  55.             </div>
  56.             <div class="col-md-12">
  57.                 <div class="box-shart">
  58.                     <div class="pieChart display-center" id="resourceBySite">
  59.                         <div class="loader"></div>
  60.                     </div>
  61.                 </div>
  62.             </div>
  63.         </div>
  64.         <div class="row margin-bottom-3">
  65.             <div class="title-block row align-items-center">
  66.                 <div class="col-md-3"><h5>{{"by Stage"|trans}}</h5></div>
  67.                 <div class="col-md-9"><hr></div>
  68.             </div>
  69.             <div class="col-md-12">
  70.                 <div class="box-shart">
  71.                     <div class="pieChart display-center" id="resourceByStage">
  72.                         <div class="loader"></div>
  73.                     </div>
  74.                 </div>
  75.             </div>
  76.         </div>
  77.         <div class="row margin-bottom-3">
  78.             <div class="title-block row align-items-center">
  79.                 <div class="col-md-3"><h5>{{"by Zone"|trans}}</h5></div>
  80.                 <div class="col-md-9"><hr></div>
  81.             </div>
  82.             <div class="col-md-12">
  83.                 <div class="box-shart">
  84.                     <div class="pieChart display-center" id="resourceByZone">
  85.                         <div class="loader"></div>
  86.                     </div>
  87.                 </div>
  88.             </div>
  89.         </div>
  90.         <div class="row margin-bottom-3">
  91.             <div class="title-block row align-items-center">
  92.                 <div class="col-md-3"><h5>{{"by Resource Type"|trans}}</h5></div>
  93.                 <div class="col-md-9"><hr></div>
  94.             </div>
  95.             <div class="col-md-12">
  96.                 <div class="box-shart">
  97.                     <div class="pieChart display-center" id="resourceByStackingDiagram">
  98.                         <div class="loader"></div>
  99.                     </div>
  100.                 </div>
  101.             </div>
  102.         </div>
  103.         <div class="row margin-bottom-3 align-items-center">
  104.             <div class="title-block row align-items-center">
  105.                 <div class="col-md-2"><h5>{{ 'Occupancy rate'|trans }}</h5></div>
  106.                 <div class="col-md-10"><hr></div>
  107.             </div>
  108.             <div class="col-md-8">
  109.                 <div class="box-shart">
  110.                     <div class="pieChart display-center" id="tauxOccupation">
  111.                         <div class="loader"></div>
  112.                     </div>
  113.                 </div>
  114.             </div>
  115.             <div class="col-md-3">
  116.                 <div class="box-shart-2">
  117.                     <span id="tauxOccupationTotal">
  118.                         <div class="loader"></div>
  119.                     </span>
  120.                     <h4>{{ 'Occupancy rate'|trans }}</h4>
  121.                 </div>
  122.             </div>
  123.         </div>
  124.         <div class="row margin-bottom-3 align-items-center">
  125.             <div class="title-block row align-items-center">
  126.                 <div class="col-md-4"><h5>{{ 'Occupancy rate'|trans }} 9h-12h 14h-17h</h5></div>
  127.                 <div class="col-md-8"><hr></div>
  128.             </div>
  129.             <div class="col-md-8">
  130.                 <div class="box-shart">
  131.                     <div class="pieChart display-center" id="tauxOccupationReal">
  132.                         <div class="loader"></div>
  133.                     </div>
  134.                 </div>
  135.             </div>
  136.             <div class="col-md-3">
  137.                 <div class="box-shart-2">
  138.                     <span id="tauxOccupationRealTotal">
  139.                         <div class="loader"></div>
  140.                     </span>
  141.                     <h4>{{ 'Occupancy rate'|trans }}</h4>
  142.                 </div>
  143.             </div>
  144.         </div>
  145.         <div class="row margin-bottom-3 align-items-center">
  146.             <div class="title-block row align-items-center">
  147.                 <div class="col-md-4"><h5>{{ 'Daily occupancy rate'|trans }}</h5></div>
  148.                 <div class="col-md-8"><hr></div>
  149.             </div>
  150.             <div class="col-md-8">
  151.                 <div class="box-shart">
  152.                     <div class="pieChart display-center" id="tauxOccupationByWeekDay">
  153.                         <div class="loader"></div>
  154.                     </div>
  155.                 </div>
  156.             </div>
  157.             <div class="col-md-3">
  158.                 <div class="box-shart-2">
  159.                     <span id="tauxOccupationByWeekDayTotal">
  160.                         <div class="loader"></div>
  161.                     </span>
  162.                     <h4>{{ 'Occupancy rate'|trans }} </h4>
  163.                 </div>
  164.             </div>
  165.         </div>
  166.         <div class="row margin-bottom-3 align-items-center">
  167.             <div class="title-block row align-items-center">
  168.                 <div class="col-md-4"><h5>{{ 'Peak_occupancy_rate_per_day'|trans }} </h5></div>
  169.                 <div class="col-md-8"><hr></div>
  170.             </div>
  171.             <div class="col-md-8">
  172.                 <div class="box-shart">
  173.                     <div class="pieChart display-center" id="tauxOccupationDesPickByDate">
  174.                         <div class="loader"></div>
  175.                     </div>
  176.                 </div>
  177.             </div>
  178.             <div class="col-md-3">
  179.                 <div class="box-shart-2">
  180.                     <span id="tauxOccupationDesPickByDateTotal">
  181.                         <div class="loader"></div>
  182.                     </span>
  183.                     <h4>{{ 'Occupancy rate'|trans }} </h4>
  184.                 </div>
  185.             </div>
  186.         </div>
  187.         <div class="row margin-bottom-3">
  188.             <div class="title-block row align-items-center">
  189.                 <div class="col-md-3"><h5>{{"per time slot"|trans}}</h5></div>
  190.                 <div class="col-md-9"><hr></div>
  191.             </div>
  192.             <div class="col-md-12">
  193.                 <div class="box-shart">
  194.                     <div class="pieChart display-center" id="chartCreneau">
  195.                         <div class="loader"></div>
  196.                     </div>
  197.                 </div>    
  198.             </div>
  199.         </div>
  200.         <div class="row margin-bottom-3">
  201.             <div class="title-block row align-items-center">
  202.                 <div class="col-md-3"><h5>{{'Reservation per day'|trans}}</h5></div>
  203.                 <div class="col-md-9"><hr></div>
  204.             </div>
  205.             <div class="col-md-12">
  206.                 <div class="box-shart">
  207.                     <div class="pieChart display-center" id="reservationByDay">
  208.                         <div class="loader"></div>
  209.                     </div>
  210.                 </div>    
  211.             </div>
  212.         </div>
  213.         <div class="row margin-bottom-3">
  214.             <div class="title-block row align-items-center">
  215.                 <div class="col-md-3"><h5>{{'Top 5 resources'|trans}}</h5></div>
  216.                 <div class="col-md-9"><hr></div>
  217.             </div>
  218.             <div class="col-md-12">
  219.                 <div class="box-shart">
  220.                     <div class="pieChart display-center" id="topRessources">
  221.                         <div class="loader"></div>
  222.                     </div>
  223.                 </div>    
  224.             </div>
  225.         </div>
  226.         <div class="row margin-bottom-3">
  227.             <div class="title-block row align-items-center">
  228.                 <div class="col-md-3"><h5>{{'Top 10 users'|trans}}</h5></div>
  229.                 <div class="col-md-9"><hr></div>
  230.             </div>
  231.             <div class="col-md-12">
  232.                 <div class="box-shart">
  233.                     <div class="pieChart display-center" id="topUsers">
  234.                         <div class="loader"></div>
  235.                     </div>
  236.                 </div>    
  237.             </div>
  238.         </div>
  239.     </div>
  240. {% endblock %}
  241. {% block scripts %}
  242. <script>
  243.         var topResources = [];
  244.         var reservationByDay = [];
  245.         var tauxOccupation = [];
  246.         var tauxOccupationReal = [];
  247.         var resourceTypeSelected = [
  248.             {% for item in typeResources %}
  249.                 {{ item.id }}
  250.                 {% if loop.last == false %},{% endif %}
  251.             {% endfor %}
  252.         ]
  253.         var localisationSelected = [
  254.             {% for item in localisations %}
  255.                 {{ item.id }}
  256.                 {% if loop.last == false %},{% endif %}
  257.             {% endfor %}
  258.         ]
  259.         $(document).ready(function() {
  260.             const treeResourcesTree = new Treeselect({
  261.                 parentHtmlContainer: document.querySelector('#typeResourcesTree'),
  262.                 value: resourceTypeSelected,
  263.                 options: JSON.parse(`{{ typeResourcesTree|json_encode|raw }}`),
  264.             });
  265.             treeResourcesTree.srcElement.addEventListener('input', (e) => {
  266.                 resourceTypeSelected = e.detail;
  267.             })
  268.             const treeLocalisation = new Treeselect({
  269.                 parentHtmlContainer: document.querySelector('#localisationsTree'),
  270.                 value: localisationSelected,
  271.                 options: JSON.parse(`{{ localisationsTree|json_encode|raw }}`),
  272.             })
  273.             treeLocalisation.srcElement.addEventListener('input', (e) => {
  274.                 localisationSelected = e.detail;
  275.             })
  276.         })
  277.         function getReservation() {
  278.             if (!!!$('#startDate').val() || !!!$('#endDate').val()) {
  279.                 toastr.error("{{'Please select the start and end dates.'|trans}}");
  280.                 return; 
  281.             }
  282.             
  283.             const status = $('[data-type="status"]').map(function () {
  284.                 if ($(this).is(':checked'))
  285.                     return $(this).val();
  286.             }).get();
  287.             if (status.length == 0 ) {
  288.                 toastr.error("{{'Please select at least one status.'|trans}}");
  289.                 return; 
  290.             }
  291.             if (localisationSelected.length == 0 ) {
  292.                 toastr.error("{{'Please select at least one location.'|trans}}");
  293.                 return; 
  294.             }
  295.             
  296.             if (resourceTypeSelected.length == 0 ) {
  297.                 toastr.error("{{'Please select at least one type of resource.'|trans}}");
  298.                 return; 
  299.             }
  300.             const resource = $('#txtResource').val() != '' ? $('#txtResource').val() : null;
  301.             initCharts()
  302.             getTotalReservation(localisationSelected,resourceTypeSelected,status,resource);
  303.         }
  304.         function getTotalReservation(localisation,resourceType,status,resource) {
  305.             $.ajax({
  306.                 type: "POST",
  307.                 url: "{{ path('getReservation') }}",
  308.                 data: {
  309.                     localisation: localisation.join(),
  310.                     resourceType: resourceType.join(),
  311.                     status: status.join(),
  312.                     resource: resource,
  313.                     user: $('#txtUser').val() ?? null,
  314.                     startDate: $('#startDate').val(),
  315.                     endDate: $('#endDate').val(),
  316.                 },
  317.                 success: function(response) {
  318.                     document.getElementById('nbrReservation').innerHTML = response['totalReservations'];
  319.                     getStatus(localisationSelected,resourceTypeSelected,status,resource);
  320.                     
  321.                     if (response['totalReservations']) {
  322.                         $('#divStats').css('display', '');
  323.                     }
  324.                 }
  325.             });
  326.         }
  327.         function getStatus(localisation,resourceType,status,resource) {
  328.             $.ajax({
  329.                 type: "POST",
  330.                 url: "{{ path('getStatus') }}",
  331.                 data: {
  332.                     localisation: localisation.join(),
  333.                     resourceType: resourceType.join(),
  334.                     status: status.join(),
  335.                     resource: resource,
  336.                     user: $('#txtUser').val() ?? null,
  337.                     startDate: $('#startDate').val(),
  338.                     endDate: $('#endDate').val(),
  339.                 },
  340.                 success: function(response) {
  341.                     getOrigin(localisationSelected,resourceTypeSelected,status,resource);
  342.                     am5.ready(
  343.                         getDataByHistograme(am5,'statusChart',response['reservationStatus']),
  344.                     )
  345.                 }
  346.             });
  347.         }
  348.         function getOrigin(localisation,resourceType,status,resource) {
  349.             $.ajax({
  350.                 type: "POST",
  351.                 url: "{{ path('getOrigin') }}",
  352.                 data: {
  353.                     localisation: localisation.join(),
  354.                     resourceType: resourceType.join(),
  355.                     status: status.join(),
  356.                     resource: resource,
  357.                     user: $('#txtUser').val() ?? null,
  358.                     startDate: $('#startDate').val(),
  359.                     endDate: $('#endDate').val(),
  360.                 },
  361.                 success: function(response) {
  362.                     getImmediate(localisationSelected,resourceTypeSelected,status,resource);
  363.                     am5.ready(
  364.                         getDataByHistograme(am5,'originChart',response['reservationOrigin']),
  365.                     )
  366.                 }
  367.             });
  368.         }
  369.         function getImmediate(localisation,resourceType,status,resource) {
  370.             $.ajax({
  371.                 type: "POST",
  372.                 url: "{{ path('getImmediate') }}",
  373.                 data: {
  374.                     localisation: localisation.join(),
  375.                     resourceType: resourceType.join(),
  376.                     status: status.join(),
  377.                     resource: resource,
  378.                     user: $('#txtUser').val() ?? null,
  379.                     startDate: $('#startDate').val(),
  380.                     endDate: $('#endDate').val(),
  381.                 },
  382.                 success: function(response) {
  383.                     getTypeSite(localisationSelected,resourceTypeSelected,status,resource);
  384.                     am5.ready(
  385.                         getDataByHistograme(am5,'immediateChart',response['immediateReservation']),
  386.                     )
  387.                 }
  388.             });
  389.         }
  390.         function getTypeSite(localisation,resourceType,status,resource) {
  391.             $.ajax({
  392.                 type: "POST",
  393.                 url: "{{ path('getTypeSite') }}",
  394.                 data: {
  395.                     localisation: localisation.join(),
  396.                     resourceType: resourceType.join(),
  397.                     status: status.join(),
  398.                     resource: resource,
  399.                     user: $('#txtUser').val() ?? null,
  400.                     startDate: $('#startDate').val(),
  401.                     endDate: $('#endDate').val(),
  402.                 },
  403.                 success: function(response) {
  404.                     $('#divStats').css('display', '');
  405.                     getByStage(localisationSelected,resourceTypeSelected,status,resource);
  406.                     am5.ready(
  407.                         getDataByHistograme(am5,'resourceBySite',response['resourceBySite']),
  408.                     )
  409.                 }
  410.             });
  411.         }
  412.         function getByStage(localisation,resourceType,status,resource) {
  413.             $.ajax({
  414.                 type: "POST",
  415.                 url: "{{ path('getByStage') }}",
  416.                 data: {
  417.                     localisation: localisation.join(),
  418.                     resourceType: resourceType.join(),
  419.                     status: status.join(),
  420.                     resource: resource,
  421.                     user: $('#txtUser').val() ?? null,
  422.                     startDate: $('#startDate').val(),
  423.                     endDate: $('#endDate').val(),
  424.                 },
  425.                 success: function(response) {
  426.                     $('#divStats').css('display', '');
  427.                     getWithoutSite(localisationSelected,resourceTypeSelected,status,resource);
  428.                     const seriesLabel = {'{{ "Confirmed"|trans }}':0,'{{ "Refused"|trans }}':0,'{{ "Pending"|trans }}':0,'{{ "Cancelled"|trans }}':0};
  429.                     am5.ready(
  430.                         getStacksDiagram(am5,"resourceByStage",response['resourceByStage'],seriesLabel, false),
  431.                     )
  432.                 }
  433.             });
  434.         }
  435.         function getWithoutSite(localisation,resourceType,status,resource) {
  436.             $.ajax({
  437.                 type: "POST",
  438.                 url: "{{ path('getWithoutSite') }}",
  439.                 data: {
  440.                     localisation: localisation.join(),
  441.                     resourceType: resourceType.join(),
  442.                     status: status.join(),
  443.                     resource: resource,
  444.                     user: $('#txtUser').val() ?? null,
  445.                     startDate: $('#startDate').val(),
  446.                     endDate: $('#endDate').val(),
  447.                 },
  448.                 success: function(response) {
  449.                     $('#divStats').css('display', '');
  450.                     getByZone(localisationSelected,resourceTypeSelected,status,resource);
  451.                     am5.ready(
  452.                         getStacksDiagram(am5,"resourceByStackingDiagram",response['resourceByStackingDiagram'],response['resourceWithoutSite'],false)
  453.                     )
  454.                 }
  455.             });
  456.         }
  457.         function getByZone(localisation,resourceType,status,resource) {
  458.             $.ajax({
  459.                 type: "POST",
  460.                 url: "{{ path('getByZone') }}",
  461.                 data: {
  462.                     localisation: localisation.join(),
  463.                     resourceType: resourceType.join(),
  464.                     status: status.join(),
  465.                     resource: resource,
  466.                     user: $('#txtUser').val() ?? null,
  467.                     startDate: $('#startDate').val(),
  468.                     endDate: $('#endDate').val(),
  469.                 },
  470.                 success: function(response) {
  471.                     $('#divStats').css('display', '');
  472.                     getStatsCreneau(localisationSelected,resourceTypeSelected,status,resource);
  473.                     am5.ready(
  474.                         getDataByHistograme(am5,'resourceByZone',response['resourceByZone'],true),
  475.                     )
  476.                 }
  477.             });
  478.         }
  479.         function getByZone(localisation,resourceType,status,resource) {
  480.             $.ajax({
  481.                 type: "POST",
  482.                 url: "{{ path('getByZone') }}",
  483.                 data: {
  484.                     localisation: localisation.join(),
  485.                     resourceType: resourceType.join(),
  486.                     status: status.join(),
  487.                     resource: resource,
  488.                     user: $('#txtUser').val() ?? null,
  489.                     startDate: $('#startDate').val(),
  490.                     endDate: $('#endDate').val(),
  491.                 },
  492.                 success: function(response) {
  493.                     $('#divStats').css('display', '');
  494.                     getByType(localisationSelected,resourceTypeSelected,status,resource);
  495.                     am5.ready(
  496.                         getDataByHistograme(am5,'resourceByZone',response['resourceByZone'],true),
  497.                     )
  498.                 }
  499.             });
  500.         }
  501.         function getByType(localisation,resourceType,status,resource) {
  502.             $.ajax({
  503.                 type: "POST",
  504.                 url: "{{ path('getByType') }}",
  505.                 data: {
  506.                     localisation: localisation.join(),
  507.                     resourceType: resourceType.join(),
  508.                     status: status.join(),
  509.                     resource: resource,
  510.                     user: $('#txtUser').val() ?? null,
  511.                     startDate: $('#startDate').val(),
  512.                     endDate: $('#endDate').val(),
  513.                 },
  514.                 success: function(response) {
  515.                     $('#divStats').css('display', '');
  516.                     getStatsCreneau(localisationSelected,resourceTypeSelected,status,resource);
  517.                     am5.ready(
  518.                         getDataByHistograme(am5,'resourceByTypeChart',response['resourceByType']),
  519.                     )
  520.                 }
  521.             });
  522.         }
  523.         function getStatsCreneau(localisation,resourceType,status,resource) {
  524.             $.ajax({
  525.                 type: "POST",
  526.                 url: "{{ path('getCreneau') }}",
  527.                 data: {
  528.                     localisation: localisation.join(),
  529.                     resourceType: resourceType.join(),
  530.                     status: status.join(),
  531.                     resource: resource,
  532.                     user: $('#txtUser').val() ?? null,
  533.                     startDate: $('#startDate').val(),
  534.                     endDate: $('#endDate').val(),
  535.                 },
  536.                 success: function(response) {
  537.                     reservationByDay = response['reservationByDay'];
  538.                     topResources = response['topResources'];
  539.                     tauxOccupation = response['tauxOccupation'];
  540.                     tauxOccupationReal = response['tauxOccupationReal'];
  541.                     document.getElementById('tauxOccupationTotal').innerHTML = response['tauxOccupationTotal'] + '%';
  542.                     document.getElementById('tauxOccupationByWeekDayTotal').innerHTML = response['tauxOccupationTotal'] + '%';
  543.                     document.getElementById('tauxOccupationDesPickByDateTotal').innerHTML = response['tauxOccupationDesPickByDateTotal'] + '%';
  544.                     document.getElementById('tauxOccupationRealTotal').innerHTML = response['tauxOccupationRealTotal'] + '%';
  545.                     
  546.                     getTopUsers(localisation,resourceType,status,resource);
  547.                     const seriesLabel = {'{{ "Confirmed"|trans }}':0,'{{ "Refused"|trans }}':0,'{{ "Pending"|trans }}':0,'{{ "Cancelled"|trans }}':0};
  548.                     am5.ready(
  549.                         getStacksDiagram(am5,"topRessources",response['topResources'],seriesLabel, true),
  550.                         getChartCreneau(am5),
  551.                         getTauxOccupation(am5,"tauxOccupation",tauxOccupation,"hour"),
  552.                         getTauxOccupation(am5,"tauxOccupationReal",tauxOccupationReal,"hour"),
  553.                         getTauxOccupation(am5,"tauxOccupationByWeekDay",response['tauxOccupationByWeekDay'],"day"),
  554.                         getTauxOccupation(am5,"tauxOccupationDesPickByDate",response['tauxOccupationDesPickByDate'],"date"),
  555.                         getReservationByDay(am5),
  556.                     )
  557.                 }
  558.             });
  559.         }
  560.         
  561.         function getTopUsers(localisation,resourceType,status,resource) {
  562.             
  563.             $.ajax({
  564.                 type: "POST",
  565.                 url: "{{ path('top_users') }}",
  566.                 data: {
  567.                     localisation: localisation.join(),
  568.                     resourceType: resourceType.join(),
  569.                     status: status.join(),
  570.                     resource: resource,
  571.                     user: $('#txtUser').val() ?? null,
  572.                     startDate: $('#startDate').val(),
  573.                     endDate: $('#endDate').val(),
  574.                 },
  575.                 success: function(response) {
  576.                     getDataByHistograme(am5,'topUsers',response['topUsers']);
  577.                 }
  578.             });
  579.         }
  580.         function initCharts() {
  581.             document.getElementById("nbrReservation").outerHTML = '<span id="nbrReservation">~</span>'
  582.             document.getElementById("topRessources").outerHTML = '<div class="pieChart display-center" id="topRessources"><div class="loader"></div></div>'
  583.             document.getElementById("reservationByDay").outerHTML = '<div class="pieChart display-center" id="reservationByDay"><div class="loader"></div></div>'
  584.             document.getElementById("chartCreneau").outerHTML = '<div class="pieChart display-center" id="chartCreneau"><div class="loader"></div></div>'
  585.             document.getElementById("tauxOccupationTotal").outerHTML = '<span class="display-center" id="tauxOccupationTotal"><div class="loader"></div></span>'
  586.             document.getElementById("tauxOccupation").outerHTML = '<div class="pieChart display-center" id="tauxOccupation"><div class="loader"></div></div>'
  587.             document.getElementById("tauxOccupationReal").outerHTML = '<div class="pieChart display-center" id="tauxOccupationReal"><div class="loader"></div></div>'
  588.             
  589.             document.getElementById("tauxOccupationByWeekDay").outerHTML = '<div class="pieChart display-center" id="tauxOccupationByWeekDay"><div class="loader"></div></div>'
  590.             document.getElementById("tauxOccupationByWeekDayTotal").outerHTML = '<span class="display-center" id="tauxOccupationByWeekDayTotal"><div class="loader"></div></span>'
  591.             
  592.             document.getElementById("tauxOccupationDesPickByDate").outerHTML = '<div class="pieChart display-center" id="tauxOccupationDesPickByDate"><div class="loader"></div></div>'
  593.             document.getElementById("tauxOccupationDesPickByDateTotal").outerHTML = '<span class="display-center" id="tauxOccupationDesPickByDateTotal"><div class="loader"></div></span>'
  594.             
  595.             document.getElementById("resourceBySite").outerHTML = '<div class="pieChart display-center" id="resourceBySite"><div class="loader"></div></div> '
  596.             document.getElementById("resourceByStage").outerHTML = '<div class="pieChart display-center" id="resourceByStage"><div class="loader"></div></div> '
  597.             document.getElementById("resourceByZone").outerHTML = '<div class="pieChart display-center" id="resourceByZone"><div class="loader"></div></div> '
  598.             document.getElementById("resourceByTypeChart").outerHTML = '<div class="pieChart display-center" id="resourceByTypeChart"><div class="loader"></div></div>'
  599.             document.getElementById("originChart").outerHTML = '<div class="pieChart display-center" id="originChart"><div class="loader"></div></div>'
  600.             document.getElementById("immediateChart").outerHTML = '<div class="pieChart display-center" id="immediateChart"><div class="loader"></div></div>'
  601.             document.getElementById("statusChart").outerHTML = '<div class="pieChart display-center" id="statusChart"><div class="loader"></div></div>'
  602.             document.getElementById("resourceByStackingDiagram").outerHTML = '<div class="pieChart display-center" id="resourceByStackingDiagram"><div class="loader"></div></div>'
  603.         }
  604.         function camembertChart(am5,component,data) {
  605.             document.getElementById(component).outerHTML = '<div class="pieChart" id="' + component + '"></div>';
  606.             if(data && data.length===0) {
  607.                 const no_result = '{{'no_results'|trans}}';
  608.                 document.getElementById(component).outerHTML= '<div class="pieChart" id="' + component + '"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
  609.             }
  610.             var myChart = am5.Root.new(component);
  611.             myChart._logo.dispose();
  612.             myChart.setThemes([
  613.                 am5themes_Animated.new(myChart)
  614.             ]);
  615.             var chart = myChart.container.children.push(am5percent.PieChart.new(myChart, {
  616.                 layout: myChart.verticalLayout,
  617.                 innerRadius: am5.percent(70)
  618.             }));
  619.             var series = chart.series.push(am5percent.PieSeries.new(myChart, {
  620.                 valueField: "value",
  621.                 categoryField: "item",
  622.                 tooltip: am5.Tooltip.new(myChart, {pointerOrientation: "left",
  623.                     labelText: "{category}: {valuePercentTotal.formatNumber('0.00')}%[/] [bold]({value})"}),
  624.                 legendValueText: "[bold]{value}",
  625.             }));
  626.             series.labels.template.set("text", "{category}: [bold]{value}");
  627.             series.labels.template.setAll({
  628.                 textType: "circular",
  629.                 centerX: 0,
  630.                 centerY: 0,
  631.                 fontSize: 14
  632.             });
  633.             series.data.setAll(data);
  634.            
  635.             var legend = chart.children.push(am5.Legend.new(myChart, {
  636.                 centerX: am5.percent(50),
  637.                 x: am5.percent(50),
  638.                 marginTop: 15,
  639.                 marginBottom: 15
  640.             }));
  641.             legend.data.setAll(series.dataItems);
  642.             legend.labels.template.setAll({
  643.                 fontSize: 14
  644.             });
  645.             legend.valueLabels.template.setAll({
  646.                 fontSize: 14
  647.             });
  648.            // legend.itemContainers.template.togglable = false;
  649.             series.appear(100, 1000);
  650.         }
  651.         function getDataByHistograme(am5,component,data,withScroll=false) {
  652.             document.getElementById(component).outerHTML = '<div class="pieChart box-shart" id="' + component + '"></div>';
  653.             if(data && data.length===0) {
  654.                 const no_result = '{{'no_results'|trans}}';
  655.                 document.getElementById(component).outerHTML = '<div class="pieChart box-shart" id="' + component + '"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
  656.             }
  657.             $( "#"+ component ).parent().attr("class", "col-md-12")
  658.             // originChart
  659.             var root = am5.Root.new(component);
  660.             root._logo.dispose();
  661.             // Set themes
  662.             root.setThemes([
  663.                 am5themes_Animated.new(root)
  664.             ]);
  665.             // Create chart
  666.             var chart = root.container.children.push(am5xy.XYChart.new(root, {
  667.                 panX: false,
  668.                 panY: false,
  669.                 layout: root.verticalLayout
  670.             }));
  671.             // We don't want zoom-out button to appear while animating, so we hide it
  672.             chart.zoomOutButton.set("forceHidden", true);
  673.             if(withScroll){
  674.                 const scrollableContainer = chart.chartContainer.children.unshift(am5.Container.new(root, {
  675.                     width: am5.p100, height: am5.p100, verticalScrollbar: am5.Scrollbar.new(root, {
  676.                         orientation: "vertical",
  677.                         dx: 20
  678.                     })
  679.                 }));
  680.                 {# chart.yAxesAndPlotContainer.set("height", 500);
  681.                 chart.yAxesAndPlotContainer.set("paddingBottom", 3) #}
  682.                 scrollableContainer.children.push(chart.yAxesAndPlotContainer);
  683.             }
  684.             // Create axes
  685.             var yRenderer = am5xy.AxisRendererY.new(root, {
  686.                 minGridDistance: 10
  687.             });
  688.             yRenderer.grid.template.set("location", 1);
  689.             var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
  690.                 maxDeviation: 0,
  691.                 categoryField: "item",
  692.                 renderer: yRenderer,
  693.                 tooltip: am5.Tooltip.new(root, { themeTags: ["axis"] })
  694.             }));
  695.             var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
  696.                 maxDeviation: 0,
  697.                 min: 0,
  698.                 extraMax: 1,
  699.                 renderer: am5xy.AxisRendererX.new(root, {
  700.                     strokeOpacity: 0.1
  701.                 })
  702.             }));
  703.             // Add series
  704.             // https://www.amcharts.com/docs/v5/charts/xy-chart/series/
  705.             var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  706.                 name: "Series 1",
  707.                 xAxis: xAxis,
  708.                 yAxis: yAxis,
  709.                 valueXField: "value",
  710.                 categoryYField: "item",
  711.                 tooltip: am5.Tooltip.new(root, {
  712.                     pointerOrientation: "left",
  713.                     labelText: "{valueX}"
  714.                 })
  715.             }));
  716.             // Rounded corners for columns
  717.             series.columns.template.setAll({
  718.                 cornerRadiusTR: 1,
  719.                 cornerRadiusBR: 1,
  720.                 strokeOpacity: 0
  721.             });
  722.             // Make each column to be of a different color
  723.             series.columns.template.adapters.add("fill", function(fill, target) {
  724.                 return chart.get("colors").getIndex(series.columns.indexOf(target));
  725.             });
  726.             series.columns.template.adapters.add("stroke", function(stroke, target) {
  727.                 return chart.get("colors").getIndex(series.columns.indexOf(target));
  728.             });
  729.             yAxis.data.setAll(data);
  730.             series.data.setAll(data);
  731.             sortCategoryAxiss();
  732.             // Get series item by category
  733.             function getSeriesItem(category) {
  734.                 for (var i = 0; i < series.dataItems.length; i++) {
  735.                     let dataItem = series.dataItems[i];
  736.                     if (dataItem.get("categoryY") == category) {
  737.                         return dataItem;
  738.                     }
  739.                 }
  740.             }
  741.             chart.set("cursor", am5xy.XYCursor.new(root, {
  742.                 behavior: "none",
  743.                 xAxis: xAxis,
  744.                 yAxis: yAxis
  745.             }));
  746.             // Axis sorting
  747.             function sortCategoryAxiss() {
  748.                 // Sort by value
  749.                 series.dataItems.sort(function(x, y) {
  750.                     return x.get("valueX") - y.get("valueX"); // descending
  751.                     //return y.get("valueY") - x.get("valueX"); // ascending
  752.                 })
  753.                 // Go through each axis item
  754.                 am5.array.each(yAxis.dataItems, function(dataItem) {
  755.                     // get corresponding series item
  756.                     let seriesDataItem = getSeriesItem(dataItem.get("category"));
  757.                     if (seriesDataItem) {
  758.                     // get index of series data item
  759.                     let index = series.dataItems.indexOf(seriesDataItem);
  760.                     // calculate delta position
  761.                     let deltaPosition = (index - dataItem.get("index", 0)) / series.dataItems.length;
  762.                     // set index to be the same as series data item index
  763.                     dataItem.set("index", index);
  764.                     // set deltaPosition instanlty
  765.                     dataItem.set("deltaPosition", -deltaPosition);
  766.                     // animate delta position to 0
  767.                     dataItem.animate({
  768.                         key: "deltaPosition",
  769.                         to: 0,
  770.                         duration: 1000,
  771.                         easing: am5.ease.out(am5.ease.cubic)
  772.                     })
  773.                     }
  774.                 });
  775.                 // Sort axis items by index.
  776.                 // This changes the order instantly, but as deltaPosition is set,
  777.                 // they keep in the same places and then animate to true positions.
  778.                 yAxis.dataItems.sort(function(x, y) {
  779.                     return x.get("index") - y.get("index");
  780.                 });
  781.             }
  782.         }
  783.         
  784.         function getStacksDiagram(am5,elementId,data,seriesLabel,horizontal){
  785.             document.getElementById(elementId).outerHTML = '<div class="pieChart box-shart" id="'+elementId+'"></div>';
  786.             // Create root element
  787.             var root = am5.Root.new(elementId);
  788.             root.setThemes([
  789.                 am5themes_Animated.new(root)
  790.             ]);
  791.             var chart = root.container.children.push(am5xy.XYChart.new(root, {
  792.                 panX: false,
  793.                 panY: false,
  794.                 layout: root.verticalLayout
  795.             }));
  796.             if (horizontal) {
  797.                 var theRenderer = am5xy.AxisRendererY.new(root, {});
  798.                 var firstAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
  799.                     categoryField: "item",
  800.                     renderer: theRenderer,
  801.                     tooltip: am5.Tooltip.new(root, {})
  802.                 }));
  803.                 var secondeAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
  804.                     min: 0,
  805.                     renderer: am5xy.AxisRendererX.new(root, {
  806.                         strokeOpacity: 0.1
  807.                     })
  808.                 }));
  809.             }else {
  810.                 var theRenderer = am5xy.AxisRendererX.new(root, {});
  811.                 var firstAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
  812.                     categoryField: "item",
  813.                     renderer: theRenderer,
  814.                     tooltip: am5.Tooltip.new(root, {})
  815.                 }));
  816.                 var secondeAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  817.                     min: 0,
  818.                     renderer: am5xy.AxisRendererY.new(root, {
  819.                         strokeOpacity: 0.1
  820.                     })
  821.                 }));
  822.             }
  823.             theRenderer.grid.template.setAll({
  824.                 location: 100
  825.             })
  826.             firstAxis.data.setAll(data);
  827.            
  828.             var legend = chart.children.push(am5.Legend.new(root, {
  829.                 centerX: am5.p50,
  830.                 x: am5.p50
  831.             }));
  832.             function makeSeries(name) {
  833.                 if (horizontal) {
  834.                     var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  835.                         name: name,
  836.                         stacked: true,
  837.                         xAxis: secondeAxis,
  838.                         yAxis: firstAxis,
  839.                         baseAxis: firstAxis,
  840.                         valueXField: name,
  841.                         categoryYField: "item"
  842.                     }));
  843.                 }else {
  844.                     var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  845.                         name: name,
  846.                         stacked: true,
  847.                         xAxis: firstAxis,
  848.                         yAxis: secondeAxis,
  849.                         baseAxis: firstAxis,
  850.                         valueYField: name,
  851.                         categoryXField: "item"
  852.                     }));
  853.                 }
  854.                 series.columns.template.setAll({
  855.                     tooltipText: (horizontal ? "{valueX} " : "{valueY} ") + "{{ 'Booking'|trans }} {name}",
  856.                     tooltipY: am5.percent(90)
  857.                 });
  858.                 series.data.setAll(data);
  859.                 // Make stuff animate on load
  860.                 // https://www.amcharts.com/docs/v5/concepts/animations/
  861.                 series.appear();
  862.                 series.bullets.push(function() {
  863.                     return am5.Bullet.new(root, {
  864.                     sprite: am5.Label.new(root, {
  865.                         text: "",
  866.                         fill: root.interfaceColors.get("alternativeText"),
  867.                         centerY: am5.p0,
  868.                         centerX: am5.p50,
  869.                         populateText: true
  870.                     })
  871.                     });
  872.                 });
  873.                 legend.data.push(series);
  874.             }
  875.             Object.keys(seriesLabel).forEach(key => {
  876.                 makeSeries(key)
  877.             });
  878.             chart.appear(1000, 100);
  879.         }
  880.         function getTopRessources(am5) {
  881.             document.getElementById('topRessources').outerHTML = '<div class="pieChart" id="topRessources"></div>';
  882.             if(topResources && topResources.length===0) {
  883.                 const no_result = '{{'no_results'|trans}}';
  884.                 document.getElementById('topRessources').outerHTML = '<div class="pieChart" id="topRessources"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
  885.             }
  886.             var topRessources = am5.Root.new("topRessources");
  887.             topRessources._logo.dispose();
  888.             // Set themes
  889.             // https://www.amcharts.com/docs/v5/concepts/themes/
  890.             topRessources.setThemes([
  891.                 am5themes_Animated.new(topRessources)
  892.             ]);
  893.             // Create chart
  894.             // https://www.amcharts.com/docs/v5/charts/xy-chart/
  895.             var chart = topRessources.container.children.push(am5xy.XYChart.new(topRessources, {
  896.                 panX: false,
  897.                 panY: false,
  898.                 wheelX: "none",
  899.                 wheelY: "none"
  900.             }));
  901.             // We don't want zoom-out button to appear while animating, so we hide it
  902.             chart.zoomOutButton.set("forceHidden", true);
  903.             // Create axes
  904.             // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
  905.             var yRenderer = am5xy.AxisRendererY.new(topRessources, {
  906.                 minGridDistance: 30
  907.             });
  908.             yRenderer.grid.template.set("location", 1);
  909.             var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(topRessources, {
  910.                 maxDeviation: 0,
  911.                 categoryField: "item",
  912.                 renderer: yRenderer,
  913.                 tooltip: am5.Tooltip.new(topRessources, { themeTags: ["axis"] })
  914.             }));
  915.             var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(topRessources, {
  916.                 maxDeviation: 0,
  917.                 min: 0,
  918.                 extraMax: 1,
  919.                 renderer: am5xy.AxisRendererX.new(topRessources, {
  920.                     strokeOpacity: 0.1
  921.                 })
  922.             }));
  923.             // Add series
  924.             // https://www.amcharts.com/docs/v5/charts/xy-chart/series/
  925.             var series = chart.series.push(am5xy.ColumnSeries.new(topRessources, {
  926.                 name: "Series 1",
  927.                 xAxis: xAxis,
  928.                 yAxis: yAxis,
  929.                 valueXField: "value",
  930.                 categoryYField: "item",
  931.                 tooltip: am5.Tooltip.new(topRessources, {
  932.                     pointerOrientation: "left",
  933.                     labelText: "{valueX} {{ 'Booking'|trans }}"
  934.                 })
  935.             }));
  936.             // Rounded corners for columns
  937.             series.columns.template.setAll({
  938.                 cornerRadiusTR: 1,
  939.                 cornerRadiusBR: 1,
  940.                 strokeOpacity: 0
  941.             });
  942.             // Make each column to be of a different color
  943.             series.columns.template.adapters.add("fill", function(fill, target) {
  944.                 return chart.get("colors").getIndex(series.columns.indexOf(target));
  945.             });
  946.             series.columns.template.adapters.add("stroke", function(stroke, target) {
  947.                 return chart.get("colors").getIndex(series.columns.indexOf(target));
  948.             });
  949.             yAxis.data.setAll(topResources);
  950.             series.data.setAll(topResources);
  951.             sortCategoryAxiss();
  952.             // Get series item by category
  953.             function getSeriesItem(category) {
  954.                 for (var i = 0; i < series.dataItems.length; i++) {
  955.                     let dataItem = series.dataItems[i];
  956.                     if (dataItem.get("categoryY") == category) {
  957.                         return dataItem;
  958.                     }
  959.                 }
  960.             }
  961.             chart.set("cursor", am5xy.XYCursor.new(topRessources, {
  962.                 behavior: "none",
  963.                 xAxis: xAxis,
  964.                 yAxis: yAxis
  965.             }));
  966.             // Axis sorting
  967.             function sortCategoryAxiss() {
  968.                 // Sort by value
  969.                 series.dataItems.sort(function(x, y) {
  970.                     return x.get("valueX") - y.get("valueX"); // descending
  971.                     //return y.get("valueY") - x.get("valueX"); // ascending
  972.                 })
  973.                 // Go through each axis item
  974.                 am5.array.each(yAxis.dataItems, function(dataItem) {
  975.                     // get corresponding series item
  976.                     let seriesDataItem = getSeriesItem(dataItem.get("category"));
  977.                     if (seriesDataItem) {
  978.                     // get index of series data item
  979.                     let index = series.dataItems.indexOf(seriesDataItem);
  980.                     // calculate delta position
  981.                     let deltaPosition = (index - dataItem.get("index", 0)) / series.dataItems.length;
  982.                     // set index to be the same as series data item index
  983.                     dataItem.set("index", index);
  984.                     // set deltaPosition instanlty
  985.                     dataItem.set("deltaPosition", -deltaPosition);
  986.                     // animate delta position to 0
  987.                     dataItem.animate({
  988.                         key: "deltaPosition",
  989.                         to: 0,
  990.                         duration: 1000,
  991.                         easing: am5.ease.out(am5.ease.cubic)
  992.                     })
  993.                     }
  994.                 });
  995.                 // Sort axis items by index.
  996.                 // This changes the order instantly, but as deltaPosition is set,
  997.                 // they keep in the same places and then animate to true positions.
  998.                 yAxis.dataItems.sort(function(x, y) {
  999.                     return x.get("index") - y.get("index");
  1000.                 });
  1001.             }
  1002.         }
  1003.         function getChartCreneau(am5) {
  1004.             document.getElementById('chartCreneau').outerHTML = '<div class="pieChart" id="chartCreneau"></div>';
  1005.             if(tauxOccupation && tauxOccupation.length===0) {
  1006.                 const no_result = '{{'no_results'|trans}}';
  1007.                 document.getElementById('chartCreneau').outerHTML = '<div class="pieChart" id="chartCreneau"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
  1008.             }
  1009.             var root = am5.Root.new("chartCreneau");
  1010.             root._logo.dispose();
  1011.             // Set themes
  1012.             // https://www.amcharts.com/docs/v5/concepts/themes/
  1013.             root.setThemes([
  1014.                 am5themes_Animated.new(root)
  1015.             ]);
  1016.             // Create chart
  1017.             // https://www.amcharts.com/docs/v5/charts/xy-chart/
  1018.             var chart = root.container.children.push(am5xy.XYChart.new(root, {
  1019.                 panX: false,
  1020.                 panY: false,
  1021.                 wheelX: "panX",
  1022.                 wheelY: "zoomX",
  1023.                 layout: root.verticalLayout
  1024.             }));
  1025.             var legend = chart.children.push(
  1026.             am5.Legend.new(root, {
  1027.                 centerX: am5.p50,
  1028.                 x: am5.p50
  1029.             })
  1030.             );
  1031.             // Create axes
  1032.             // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
  1033.             var xRenderer = am5xy.AxisRendererX.new(root, {
  1034.                 cellStartLocation: 0.1,
  1035.                 cellEndLocation: 0.9
  1036.             })
  1037.             var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
  1038.                 categoryField: "hour",
  1039.                 renderer: xRenderer,
  1040.                 tooltip: am5.Tooltip.new(root, {})
  1041.             }));
  1042.             xRenderer.grid.template.setAll({
  1043.                 location: 1
  1044.             })
  1045.             var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  1046.                 renderer: am5xy.AxisRendererY.new(root, {
  1047.                     strokeOpacity: 0.1
  1048.                 })
  1049.             }));
  1050.             xAxis.data.setAll(tauxOccupation);
  1051.             var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  1052.                 renderer: am5xy.AxisRendererY.new(root, {
  1053.                     strokeOpacity: 0.1
  1054.                 })
  1055.             }));
  1056.             function makeSeries(name, fieldName) {
  1057.                 var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  1058.                     name: name,
  1059.                     xAxis: xAxis,
  1060.                     yAxis: yAxis,
  1061.                     valueYField: fieldName,
  1062.                     categoryXField: "hour"
  1063.                 }));
  1064.                 series.columns.template.setAll({
  1065.                     tooltipText: "{name}, {categoryX} - {valueY} {{ 'Booking'|trans }}",
  1066.                     width: am5.percent(90),
  1067.                     tooltipY: 0,
  1068.                     strokeOpacity: 0
  1069.                 });
  1070.                 series.data.setAll(tauxOccupation);
  1071.                 // Make stuff animate on load
  1072.                 // https://www.amcharts.com/docs/v5/concepts/animations/
  1073.                 series.appear();
  1074.                 series.bullets.push(function() {
  1075.                     return am5.Bullet.new(root, {
  1076.                     locationY: 0,
  1077.                     sprite: am5.Label.new(root, {
  1078.                         text: "{valueY}",
  1079.                         fill: root.interfaceColors.get("alternativeText"),
  1080.                         centerY: 0,
  1081.                         centerX: am5.p50,
  1082.                         populateText: true
  1083.                     })
  1084.                     });
  1085.                 });
  1086.                 legend.data.push(series);
  1087.             }
  1088.             makeSeries('{{"Reserved occupancy"|trans}}', "reservation");
  1089.             makeSeries('{{"Real occupation"|trans}}', "reservation_reel");
  1090.             chart.appear(1000, 100);
  1091.         }
  1092.         function getTauxOccupation(am5,element, data,categoryXField) {
  1093.             document.getElementById(element).outerHTML = '<div class="pieChart" id="'+ element +'"></div>';
  1094.             if(data && data.length===0) {
  1095.                 const no_result = '{{'no_results'|trans}}';
  1096.                 document.getElementById(element).outerHTML = '<div class="pieChart" id="'+ element +'"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
  1097.             }
  1098.             var root = am5.Root.new(element);
  1099.             root._logo.dispose();
  1100.             // Set themes
  1101.             // https://www.amcharts.com/docs/v5/concepts/themes/
  1102.             root.setThemes([
  1103.                 am5themes_Animated.new(root)
  1104.             ]);
  1105.             // Create chart
  1106.             // https://www.amcharts.com/docs/v5/charts/xy-chart/
  1107.             var chart = root.container.children.push(am5xy.XYChart.new(root, {
  1108.                 panX: false,
  1109.                 panY: false,
  1110.                 wheelX: "panX",
  1111.                 wheelY: "zoomX",
  1112.                 layout: root.verticalLayout
  1113.             }));
  1114.             var legend = chart.children.push(
  1115.             am5.Legend.new(root, {
  1116.                 centerX: am5.p50,
  1117.                 x: am5.p50
  1118.             })
  1119.             );
  1120.             // Create axes
  1121.             // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
  1122.             var xRenderer = am5xy.AxisRendererX.new(root, {
  1123.                 cellStartLocation: 0.1,
  1124.                 cellEndLocation: 0.9
  1125.             })
  1126.             var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
  1127.                 categoryField: categoryXField,
  1128.                 renderer: xRenderer,
  1129.                 tooltip: am5.Tooltip.new(root, {})
  1130.             }));
  1131.             xRenderer.grid.template.setAll({
  1132.                 location: 1
  1133.             })
  1134.             var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  1135.                 renderer: am5xy.AxisRendererY.new(root, {
  1136.                     strokeOpacity: 0.1
  1137.                 })
  1138.             }));
  1139.             xAxis.data.setAll(data);
  1140.             var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  1141.                 renderer: am5xy.AxisRendererY.new(root, {
  1142.                     strokeOpacity: 0.1
  1143.                 })
  1144.             }));
  1145.             function makeSeries(name, fieldName) {
  1146.                 var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  1147.                     name: name,
  1148.                     xAxis: xAxis,
  1149.                     yAxis: yAxis,
  1150.                     valueYField: fieldName,
  1151.                     categoryXField: categoryXField
  1152.                 }));
  1153.                 series.columns.template.setAll({
  1154.                     tooltipText: "{name}, {categoryX} - {valueY}%",
  1155.                     width: am5.percent(90),
  1156.                     tooltipY: 0,
  1157.                     strokeOpacity: 0
  1158.                 });
  1159.                 series.data.setAll(data);
  1160.                 // Make stuff animate on load
  1161.                 // https://www.amcharts.com/docs/v5/concepts/animations/
  1162.                 series.appear();
  1163.                 series.bullets.push(function() {
  1164.                     return am5.Bullet.new(root, {
  1165.                     locationY: 0,
  1166.                     sprite: am5.Label.new(root, {
  1167.                         text: "{valueY}",
  1168.                         fill: root.interfaceColors.get("alternativeText"),
  1169.                         centerY: 0,
  1170.                         centerX: am5.p50,
  1171.                         populateText: true
  1172.                     })
  1173.                     });
  1174.                 });
  1175.                 legend.data.push(series);
  1176.             }
  1177.             makeSeries('{{"Reserved occupancy"|trans}}', "tauxOccupation");
  1178.             makeSeries('{{"Real occupation"|trans}}', "tauxOccupationReal");
  1179.             chart.appear(1000, 100);
  1180.         }
  1181.         function getReservationByDay(am5) {
  1182.             document.getElementById('reservationByDay').outerHTML = '<div class="pieChart" id="reservationByDay"></div>';
  1183.             if(reservationByDay.length===0) {
  1184.                 const no_result = '{{'no_results'|trans}}';
  1185.                 document.getElementById('reservationByDay').outerHTML = '<div class="pieChart" id="reservationByDay"><div style="text-align: center;top: 50%;position: relative;">'+no_result+'</div></div>';
  1186.             }
  1187.             var root = am5.Root.new("reservationByDay");
  1188.             root._logo.dispose();
  1189.             // Set themes
  1190.             // https://www.amcharts.com/docs/v5/concepts/themes/
  1191.             root.setThemes([
  1192.                 am5themes_Animated.new(root)
  1193.             ]);
  1194.             // Create chart
  1195.             // https://www.amcharts.com/docs/v5/charts/xy-chart/
  1196.             var chart = root.container.children.push(am5xy.XYChart.new(root, {
  1197.                 panX: false,
  1198.                 panY: false,
  1199.                 wheelX: "panX",
  1200.                 wheelY: "zoomX",
  1201.                 layout: root.verticalLayout
  1202.             }));
  1203.             var legend = chart.children.push(
  1204.             am5.Legend.new(root, {
  1205.                 centerX: am5.p50,
  1206.                 x: am5.p50
  1207.             })
  1208.             );
  1209.             // Create axes
  1210.             // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
  1211.             var xRenderer = am5xy.AxisRendererX.new(root, {
  1212.                 cellStartLocation: 0.1,
  1213.                 cellEndLocation: 0.9
  1214.             })
  1215.             var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
  1216.                 categoryField: "date",
  1217.                 renderer: xRenderer,
  1218.                 tooltip: am5.Tooltip.new(root, {})
  1219.             }));
  1220.             xRenderer.grid.template.setAll({
  1221.                 location: 1
  1222.             })
  1223.             var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  1224.                 renderer: am5xy.AxisRendererY.new(root, {
  1225.                     strokeOpacity: 0.1
  1226.                 })
  1227.             }));
  1228.             xAxis.data.setAll(reservationByDay);
  1229.             var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  1230.                 renderer: am5xy.AxisRendererY.new(root, {
  1231.                     strokeOpacity: 0.1
  1232.                 })
  1233.             }));
  1234.             function makeSeries(name, fieldName) {
  1235.                 var series = chart.series.push(am5xy.ColumnSeries.new(root, {
  1236.                     name: name,
  1237.                     xAxis: xAxis,
  1238.                     yAxis: yAxis,
  1239.                     valueYField: fieldName,
  1240.                     categoryXField: "date"
  1241.                 }));
  1242.                 series.columns.template.setAll({
  1243.                     tooltipText: "{categoryX} - {valueY} {{ 'Booking'|trans }}",
  1244.                     width: am5.percent(90),
  1245.                     tooltipY: 0,
  1246.                     strokeOpacity: 0
  1247.                 });
  1248.                 series.data.setAll(reservationByDay);
  1249.                 // Make stuff animate on load
  1250.                 // https://www.amcharts.com/docs/v5/concepts/animations/
  1251.                 series.appear();
  1252.                 series.bullets.push(function() {
  1253.                     return am5.Bullet.new(root, {
  1254.                     locationY: 0,
  1255.                     sprite: am5.Label.new(root, {
  1256.                         text: "{valueY}",
  1257.                         fill: root.interfaceColors.get("alternativeText"),
  1258.                         centerY: 0,
  1259.                         centerX: am5.p50,
  1260.                         populateText: true
  1261.                     })
  1262.                     });
  1263.                 });
  1264.                 legend.data.push(series);
  1265.             }
  1266.             makeSeries('{{"Number of reservations"|trans}}', "value");
  1267.             chart.appear(1000, 100);
  1268.         }
  1269.     </script>
  1270.     
  1271. {% endblock %}