¿Método elegante para dibujar un gráfico de barras por hora a partir de datos de intervalos de tiempo?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

Tengo una lista de entradas de la hoja de horas que muestran una hora de inicio y finalización.Esto está ubicado en una base de datos MySQL.Necesito crear gráficos de barras basados ​​en estos datos con las 24 horas del día en la parte inferior y la cantidad de horas de trabajo trabajadas para cada hora del día.

Por ejemplo, si Alice trabajaba de 15:30 a 19:30 y Bob trabajaba de 12:15 a 17:00, el gráfico se vería así:

Example Chart

Tengo una solución WTFey en este momento que implica una hoja de cálculo que sale a la columna DY o algo así.La resolución necesaria es intervalos de 15 minutos.

Supongo que es mejor hacer esto en la base de datos y luego exportarlo para la creación de gráficos.Déjame saber si me falta algún detalle.Gracias.

¿Fue útil?

Solución

Cree una tabla con solo el tiempo desde medianoche hasta medianoche que contenga cada minuto del día.En el mundo del almacenamiento de datos, lo llamaríamos dimensión temporal.He aquí un ejemplo:

TIME_DIM
 -id
 -time_of_day
 -interval_15 
 -interval_30

un ejemplo de los datos de la tabla sería

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

Luego todo lo que tienes que hacer es unir tu tabla a la dimensión de tiempo y luego agruparla por intervalo_15.Por ejemplo:

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

Otros consejos

Se me ocurrió una solución de pseudocódigo, espero que ayude.

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

Ahora la matriz de horarios contiene los valores que desea en una granularidad de 15 minutos, es decir.un valor de 4 = 1 hora, 5 = 1 hora 15 minutos, 14 = 3 horas 30 minutos.

Aquí hay otra solución de pseudocódigo desde un ángulo diferente;un poco más intensivo porque realiza 96 consultas por cada período de 24 horas:

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)

Qué tal esto:

Utilice esa tabla de "tiempos", pero con dos columnas, que contengan los intervalos de 15 minutos.Los from_times son los tiempos de 15 minutos, los to_times son un segundo antes del siguiente from_times.Por ejemplo, de 12:30:00 a 12:44:59.

Ahora obtenga la tabla de trabajo de su persona, a la que he llamado "actividad" aquí, con las columnas hora_inicio y hora_final.

Agregué valores para Alice y Bob según la pregunta original.

Aquí está la consulta 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)

lo que me da esto:

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

Parece correcto...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top