Méthode élégante pour dessiner un graphique à barres horaire à partir de données d'intervalle de temps?

StackOverflow https://stackoverflow.com/questions/79789

  •  09-06-2019
  •  | 
  •  

Question

J'ai une liste d'entrées de la feuille de temps indiquant les heures de début et de fin. Ceci est assis dans une base de données MySQL. Je dois créer des diagrammes à barres basés sur ces données, avec les 24 heures de la journée en bas et le nombre d'heures-homme travaillées pour chaque heure de la journée.

Par exemple, si Alice travaillait de 15h30 à 19h30 et Bob de 12h15 à 17h00, le graphique ressemblerait à ceci:

 Exemple de graphique

J'ai actuellement une solution WTFey qui implique un tableur dans la colonne DY ou quelque chose comme ça. La résolution requise est de 15 minutes.

Je suppose que cette opération est préférable dans la base de données, puis exportée pour la création de graphique. Faites-moi savoir s'il me manque des détails. Merci.

Était-ce utile?

La solution

Créez un tableau contenant uniquement l'heure de minuit à minuit et contenant chaque minute de la journée. Dans le monde des entrepôts de données, nous appellerions cela une dimension temporelle. Voici un exemple:

TIME_DIM
 -id
 -time_of_day
 -interval_15 
 -interval_30

un exemple des données de la table serait

id   time_of_day    interval_15    interval_30
1    00:00          00:00          00:00
...
30   00:23          00:15          00:00
...
100  05:44          05:30          05:30

Ensuite, tout ce que vous avez à faire est de joindre votre table à la dimension time, puis de grouper par intervalle_15. Par exemple:

SELECT b.interval_15, count(*) 
FROM my_data_table a
INNER JOIN time_dim b ON a.time_field = b.time
WHERE a.date_field = now()
GROUP BY b.interval_15

Autres conseils

Je suis arrivé avec une solution de pseudocode, espérons que cela aide.

create an array named timetable with 24 entries
initialise timetable to zero

for each user in SQLtable
  firsthour = user.firsthour
  lasthour = user.lasthour

  firstminutes = 4 - (rounded down integer(user.firstminutes/15))
  lastminutes = rounded down integer(user.lastminutes/15)

  timetable(firsthour) = timetable(firsthour) + firstminutes
  timetable(lasthour) = timetable(lasthour) + lastminutes

  for index=firsthour+1 to lasthour-1
    timetable(index) = timetable(index) + 4
  next index

next user

Le tableau d’horaires contient maintenant les valeurs que vous désirez en 15 minutes, par exemple. une valeur de 4 = 1 heure, 5 = 1 heure 15 minutes, 14 = 3 heures 30 minutes.

Voici une autre solution de pseudocode sous un angle différent; un peu plus intensif car il fait 96 requêtes pour chaque période de 24 heures:

results = []
for time in range(0, 24, .25):
  amount = mysql("select count(*) from User_Activity_Table where time >= start_time and time <= end_time")
  results.append(amount)

Que diriez-vous de cela:

Utilisez-le & fois; fois " table, mais avec deux colonnes, contenant les intervalles de 15 minutes. Les from_times sont les 15 minutes, ils sont une seconde avant le prochain from_times. Par exemple, de 12h30 à 12h44:59.

Maintenant, obtenez votre table de travail personnelle, que j'ai appelée "activité". ici, avec les colonnes start_time et end_time.

J'ai ajouté des valeurs pour Alice et Bob conformément à la question initiale.

Voici la requête de MySQL:

SELECT HOUR(times.from_time) AS 'TIME', count(*) / 4 AS 'HOURS'
FROM times
  JOIN activity
  ON times.from_time >= activity.start_time AND 
     times.to_time   <= activity.end_time
GROUP BY HOUR(times.from_time)
ORDER BY HOUR(times.from_time)

qui me donne ceci:

TIME   HOURS
12     0.7500
13     1.0000
14     1.0000
15     1.5000
16     2.0000
17     1.0000
18     1.0000
19     0.7500

Regarde à droite ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top