Metodo elegante per disegnare un grafico a barre orario dai dati di intervallo di tempo?

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

  •  09-06-2019
  •  | 
  •  

Domanda

Ho un elenco di voci della scheda attività che mostrano un'ora di inizio e di fine.Questo è seduto in un database MySQL.Devo creare grafici a barre basati su questi dati con le 24 ore del giorno in basso e la quantità di ore di lavoro lavorate per ciascuna ora del giorno.

Ad esempio, se Alice svolgesse un lavoro dalle 15:30 alle 19:30 e Bob lavorasse dalle 12:15 alle 17:00, il grafico sarebbe simile al seguente:

Example Chart

Ho una soluzione WTFey in questo momento che prevede un foglio di calcolo che esce nella colonna DY o qualcosa del genere.La risoluzione necessaria è intervalli di 15 minuti.

Presumo che sia meglio farlo nel database e poi esportarlo per la creazione del grafico.Fammi sapere se mi manca qualche dettaglio.Grazie.

È stato utile?

Soluzione

Crea una tabella con solo l'ora da mezzanotte a mezzanotte contenente ogni minuto della giornata.Nel mondo del data warehouse la chiameremmo dimensione temporale.Ecco un esempio:

TIME_DIM
 -id
 -time_of_day
 -interval_15 
 -interval_30

un esempio dei dati nella tabella sarebbe

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

Quindi tutto ciò che devi fare è unire la tua tabella alla dimensione temporale e quindi raggrupparla per intervallo_15.Per esempio:

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

Altri suggerimenti

Ho trovato una soluzione in pseudocodice, spero che sia d'aiuto.

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

Ora l'array dell'orario contiene i valori desiderati con una granularità di 15 minuti, ad es.un valore di 4 = 1 ora, 5 = 1 ora e 15 minuti, 14 = 3 ore e 30 minuti.

Ecco un'altra soluzione di pseudocodice da una diversa angolazione;un po' più intenso perché esegue 96 query per ogni periodo di 24 ore:

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)

Cosa ne pensi di questo:

Usa la tabella "tempi", ma con due colonne, contenenti gli intervalli di 15 minuti.I from_times sono tempi di 15 minuti, i to_times sono un secondo prima del successivo from_times.Ad esempio dalle 12:30:00 alle 12:44:59.

Ora prendi la tabella di lavoro della tua persona, che qui ho chiamato "attività", con le colonne start_time e end_time.

Ho aggiunto valori per Alice e Bob come da domanda originale.

Ecco la query da 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)

che mi dà questo:

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

Sembra giusto...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top