Graph with Hours and Minutes

1

Good morning, I am trying to make a graph that shows the total hours and minutes of classes given by a teacher per month. I have only managed to show the hours on the line but I would like the minutes to go out as well. The query is done in PHP and then I pass the variables to JS. Thanks:

<div class="panel-body">Taught hours chart
                        <div class="canvas-wrapper">
                            <canvas class="main-chart" id="line-chart" height="200" width="600"></canvas>
                        </div>
                    </div>    
<script>
    var horas_mes1 = '<?php echo $horas2_mes1 ?>';
    var min_mes1 = '<?php echo $min2_mes1 ?>';
    var horas_mes2 = '<?php echo $horas2_mes2 ?>';
    var min_mes2 = '<?php echo $min2_mes2 ?>';
    var horas_mes3 = '<?php echo $horas2_mes3 ?>';
    var min_mes3 = '<?php echo $min2_mes3 ?>';
    var horas_mes4 = '<?php echo $horas2_mes4 ?>';
    var min_mes4 = '<?php echo $min2_mes4 ?>';
    var horas_mes5 = '<?php echo $horas2_mes5 ?>';
    var min_mes5 = '<?php echo $min2_mes5 ?>';
    var mes1letra = '<?php echo $mes1letra ?>';
    var mes2letra = '<?php echo $mes2letra ?>';
    var mes3letra = '<?php echo $mes3letra ?>';
    var mes4letra = '<?php echo $mes4letra ?>';
    var mes5letra = '<?php echo $mes5letra ?>';

    var lineChartData = {
        labels :[mes1letra,mes2letra,mes3letra,mes4letra,mes5letra],
        datasets : [
            {
                label: "My First dataset",
                fillColor : "rgba(48, 164, 255, 0.2)",
                strokeColor : "rgba(48, 164, 255, 1)",
                pointColor : "rgba(48, 164, 255, 1)",
                pointStrokeColor : "#fff",
                pointHighlightFill : "#fff",
                pointHighlightStroke : "rgba(48, 164, 255, 1)",
                data : [horas_mes1,horas_mes2,horas_mes3,horas_mes4,horas_mes5]
            }
        ]
    }
    window.onload = function(){
    var chart1 = document.getElementById("line-chart").getContext("2d");
    window.myLine = new Chart(chart1).Line(lineChartData, {
        responsive: true,
        scaleLineColor: "rgba(255,255,255,.2)", 
        scaleGridLineColor: "rgba(255,255,255,.05)", 
        scaleFontColor: "#ffffff"
    });
    }
    </script>
    
asked by Vieira 10.01.2017 в 10:52
source

1 answer

2

To begin with, I think it would be better:

  • Append the hours with the minutes to have a total of decimal hours, for example: 49.50 horas , where the fractional part equals the minutes.
  • Get the data by ajax, because the Chart.js is a library that needs the data available in JavaScript.
  

At this point I guess you have extra minutes in the database, since having the number of hours and the same amount in minutes (h * 60) would not make any sense.

Let's say you bring the hours and minutes of class for each month from the database:

$monthHours = array(
  "mes1" => 75,
  "mes2" => 80,
  "mes3" => 83
  "mes4" => 78
);

$monthMinutes = array(
  "mes1" => 25,
  "mes2" => 37,
  "mes3" => 18,
  "mes4" => 29
);

In the client, what we can do is know the percentage of 1h of each minute . Basic math: yes 1h = 60m = 100% | Xm = %? .

const totalHours = [];
for (let key in monthHours) {
  const val = monthHours[key];
  const minute = monthMinutes[key] / 100;
  totalHours.push(val + minute);
}
  

In case you send the hours from the backend in a simple (non-associative) array as $monthHours = array(75, 80, 83, 78) , then the above can be done using Array#map .

const totalHours = hours.map(function (hour, i) {
  const minute = minutes[i] / 100;
  return hour += minute;
});

Custom tooltips in Chart.js

Chart.js allows us to customize tooltips to display personalized information. This functionality is useful for example when we work with coins. To customize the tooltips, just create an object with the key tooltips.callbacks.label . This key accepts a function that receives two parameters: current tooltip and object data (our datasets).

const options = {
  tooltips: {
    callbacks: {
        label: function (tooltip, data) {
        const index = tooltip.index;
        let hours = data.datasets[0].data[index];
        let minutes = (hours % 1).toFixed(2);
        hours = parseInt(hours);
        minutes = minutes.substring(minutes.indexOf('.') + 1);
        return '${hours} horas y ${minutes} minutos';
      }
    }
  }
};

In the code above we only extract the time of the label on which it was made hover. Afterwards, we extract the minutes of the hours and we give it the following format:

  

X hours and Y minutes

Once we have everything, we put it together and get the desired result.

You can see working code below (or also this one fiddle ):

document.addEventListener('DOMContentLoaded', function () {
	const ctx = document.getElementById('draw').getContext('2d');

  let monthHours = {
    mes1: 78,
    mes2: 80,
    mes3: 83,
    mes4: 78,
    mes5: 79
  };
  let monthMinutes = {
    mes1: 25,
    mes2: 37,
    mes3: 18,
    mes4: 29,
    mes5: 32
  };
  const totalHours = [];

  for (let key in monthHours) {
    const val = monthHours[key];
    const minute = monthMinutes[key];
    totalHours.push(val + (minute / 100));
  }
  const labels = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo'];
  const datasets = [
    {
      label: 'Horas de clases',
      backgroundColor: 'rgba(0, 150, 255, .13)',
      borderColor: 'rgba(0, 150, 255, .35)',
      pointColor: '#3498db',
      pointBorderColor: 'rgba(0, 150, 255, .55)',
      pointBackgroundColor: '#fff',
      data: totalHours
    }
  ];
  const options = {
    tooltips: {
      callbacks: {
        label: function (tooltip, data) {
          const index = tooltip.index;
          let hours = data.datasets[0].data[index];
          let minutes = (hours % 1).toFixed(2);
          hours = parseInt(hours);
          minutes = minutes.substring(minutes.indexOf('.') + 1);
          return '${hours} horas y ${minutes} minutos';
        }
      }
    }
  };

  new Chart.Line(ctx, {
    data: { labels, datasets },
    options
  });
});
<!-- Chart.js -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>

<!-- HTML (canvas) -->
<section class="chart">
  <canvas id="draw" height="300" width="700"></canvas>
</section>
    
answered by 10.01.2017 / 15:45
source