• Non ci sono risultati.

AnnotationsManager

Nel documento Web based graph library (pagine 59-73)

5.2 Libreria per grafici

5.2.1 Echarts

5.3.1.3 AnnotationsManager

Questo modulo si occupa di attivare la possibilità di aggiungere note ai grafici. Premendo un comando od effettuando un click su un elemento della lista di hotkey si potrà aggiungere una nota ad un grafico, altrimenti questa possibilità è disattivata. Espone due metodi:

activateEvents(listItems, charts) - metodo che accetta come parametri una lista di

elementi HTML e la mappa di istanze di charts. Ogni elemento della lista contiene un attributo data-trigger="" che ha come valore il codice dell’evento KeyboardEvent che viene lanciato quando si preme un bottone sulla tastiera. Ad esempio premendo la lettera "r" sulla tastiera verrà lanciato un evento che ha come codice la stringa

"KeyR". In questo metodo si attiva la possibilità di aggiungere una nota quando viene premuto un certo elemento della lista o viene lanciato l’evento con il codice inserito in data-trigger.

drawEventsFromServer(chart) - questo metodo recupera una lista di annotazioni

dal server eseguendo una richiesta GET all’endpoint "/annotations". La lista di anno- tazioni viene poi inserita nell’istanza del grafico richiamando, per ognuna, il metodo addAnnotationToOptions(). Dopo averli inseriti tutti ridisegna il grafico passato come argomento.

5.3.1.4 CustomEventManager

Quando si aggiunge una qualsiasi nota ad un grafico viene lanciato un evento persona- lizzato. Questo evento ’chartAnnotation’ può venire ascoltato nel documento. Il modulo CustomEventManager si occupa di effettuare determinate operazioni quando si riceve un evento ’chartAnnotation’.

Per abilitare l’ascolto dell’evento personalizzato bisogna invocare il metodoenableCusto- mEventManager(). In questo metodo istanzia un listener, con target document, dell’evento

’chartAnnotation’. Quando viene ricevuto l’evento si effettua una richiesta al server all’end- point "/annotations" con metodo POST, nel cui body vengono inseriti i campi personlizzati dell’evento, ovvero il timestamp, la durata, il nome dell’evento e il file su cui si sta lavorando. Il server salverà quindi nel database l’annotazione appena creata.

In seguito, invocando pubsub.pub con i topic registrati nel modulo AnnotationsAsideMenu si cancellerà la lista di annotazioni nel menù laterale e se ne creerà una nuova aggiorna- ta. Inoltre per tutti grafici verrà invocato il metodo disableNote. In questo modo non sarà possibile aggiungere nessuna nota ad un grafico finché non verranno riattivate.

5.3.1.5 Hypnogram

L’ipnogramma della polisonnografia viene creato in questo modulo, il quale espone 2 metodi:

buildHypno(filename, name, graphContainer, options, color) - A questo metodo

bisogna passare come parametro un oggetto contente le seguenti informazioni: nome del file, nome del grafico, div HTML in cui creare il grafico, opzioni necessarie per creare il grafico e colore della linea da visualizzare. In seguito si crea un’istanza di un grafico, si attiva lo spinner da visualizzare durante il caricamento dei dati, si invoca il metodo addSource dell’istanza del grafico e si chiama il metodo getHypno del modulo net, il quale recupererà i dati dal server e li elaborerà in modo da poter costruire correttamente l’ipnogramma.

updateDataFromHypno() - questo metodo abilita la funzionalità di modificare la fi-

nestra di visualizzazione del grafico in base ad un click sull’ipnogramma. Sfruttando il metodo callFunctionOnClick dell’istanza chart di hypno è possibile invocare la fun- zione updateCharts(params) ad ogni click. Questa funzione modifica i parametri di start e end salvati, effettua una chiamata al server per recuperare i dati della finestra desiderata ed aggiorna i dati visualizzati. Inoltre aggiorna le annotazioni mostrare nel menu laterale.

5.3.1.6 PatientsHandler

Il modulo PatientsHandler si occupa di gestire tutto ciò che riguarda i pazienti. Utilizza il modulo FormHandler per aggiornare e controllare i campi del form dei pazienti. In totale esporta 6 metodi:

init(patientForm, addPatientButton, submitPatientButton, deletePatientButton, patients) - questo metodo deve venire invocato prima di tutti gli altri e serve ad inizia-

lizzare il modulo con i componenti corretti. In particolare bisogna passare un form che viene utilizzato per creare o modificare i pazienti, il quale avrà un bottone di submit e uno di delete. Inoltre serve un bottone addPatientButton che viene usato per mostrare il form di creazione e una lista di bottoni HTML dei pazienti attualmente esistenti.

setupAddNewPatientForm() - in questo metodo si associa all’evento di click sul bot-

tone "addPatientForm" l’inizializzazione corretta del form. In particolar modo il bottone di submit conterrà il testo "Create Patient" e il bottone di delete verrà nascosto. Inoltre si invoca il metodo updateForm del modulo FormHandler passandogli come "data" un oggetto dataCleared che contiene tutti i campi del form vuoti, in modo da ripulirne i campi.

setupValidationAndSubmit() - la validazione e l’invio dei dati del paziente al server

avviene in questo metodo. Un listener di un click sul bottone di submit invoca il metodo validateForm del modulo FormHandler. Validate form sfrutta il metodo checkValidity() associato agli elementi con attributo required per controllare che non siano vuoti. Nel caso in cui i campi obbligatori contengano un qualsiasi valore i dati vengono inviati al server e la pagina viene ricaricata.

enableEditPatient() - Data la lista di pazienti si associa ad ogni bottone un listener

che invocherà ad ogni click una funzione updateFormData(btn). L’oggetto btn è il bottone che viene premuto. La funzione updateFormData andrà ad effettuare una richiesta al server per recuperare le informazioni sul paziente premuto che verranno inseriti nei rispettivi campi del form. Inoltre il bottone di submit conterrà il testo "Update

Patient" ed il bottone di delete verrà mostrato. Infine questo metodo aggiorna un parametro patientSelected, in cui si salva quale paziente è stato selezionato e verrà utilizzato nel metodo enableDeletePatient().

enableDeletePatient() - questo metodo serve per abilitare l’eliminazione di un pa-

ziente. Si associa al click sul bottone di delete una funzione che invierà al server una richiesta all’endpoint "/patient?=patientId=000" con metodo DELETE. L’id del pazien- te viene recuperato dall’attributo data-id dell’elemento salvato nella variabile patien- tSelected. Una volta ottenuta una risposta di successo dal server l’elemento verrà eliminato dalla lista di pazienti nel menu laterale.

populatePatientTab(patientTab, patientList) - la lista di bottoni relativi ai pazienti

presente nella scheda Patients del menu laterale sinistro viene generata in questo metodo. Si scorre la lista ricevuta come parametro e si crea per ognuno un bottone che abbia gli attributi data-toggle="modal", data-target="#newPatient" che indica l’id della finestra di dialogo in cui è presente il form relativo ai pazienti e data-id="XXX" in cui si inserisce l’id del paziente. In seguito il bottone viene aggiunto al container patientTab passato come parametro.

5.3.1.7 RecordingsHandler

La scheda dove appaiono le registrazioni è formata da due bottoni, uno per caricare una nuova polisonnografia e uno per visualizzare e gestire quelle già inserite. Le registrazioni vengono visualizzate all’interno di una tabella in una finestra di dialogo. Questa tabella viene gestita da questo modulo, che espone i seguenti due metodi:

enableDeleteButtons(deleteButtons) - questo metodo riceve come parametro una

lista di bottoni. Viene istanziato un listener per ogni bottone, il quale ad ogni click invoca la funzione deleteRecording(deleteButton). Questa funzione, quando viene in- vocata, recupera, dall’elemento HTML deleteButton passato come parametro, il valore dell’attributo data-file che corrisponde al nome del file da eliminare. In seguito viene effettuata una richiesta all’indirizzo "/recording?filename=XXX" con metodo DELETE. Il server provvederà ad eliminare la registrazione associata al file e, una volta ricevuta risposta positiva, si recupereranno e elimineranno dal document tutti gli elementi con data-file che corrispondono al file eliminato.

populateRecordingTable(table) - La tabella viene popolata da questo metodo, il qua-

le effettua una richiesta a "/recordings" con metodo get e, per ogni elemento dell’array ritornato, crea una riga della tabella, invocando un metodo createRow, in cui sono presenti nome del file, nome completo del paziente un bottone per l’eliminazione del file.

5.3.1.8 SidebarManager

Per scegliere quale polisonnografia visualizzare è necessario selezionare una registrazione da una lista presente nella scheda Recording del menù laterale sinistro.

Questa finestra viene popolata da questo modulo, il quale esponde un solo metodo:

populateSidebar(sidebar, patientsList) - Il metodo riceve come parametro il me-

nu laterale da popolare e la lista di pazienti recuperata dal server. In seguito, per ogni paziente viene creato un div utilizzato come titolo che contiene il nome com- pleto del paziente e sotto il quale vengono aggiunte tutte le registrazioni del pazien- te. Ogni elemento della registrazione deve avere gli attributi data-toggle="modal", data-target="#tracesModal", data-file="nomeDelFile".

5.3.1.9 Colors

Colors si occupa di modificare il colore di un grafico e di attivare e disattivare un grafico. Quando si esegue un click su un grafico questo viene colorato di blu, mentre uno cliccato in precedenza viene ripristinato al suo colore originale. Il grafico attivato viene salvato in una variabile previousChart, mentre il suo colore originale viene salvato in previousColor. Il modulo colors espone 3 metodi per esguire queste operazioni:

activateChart(chart, color) - dapprima viene invocato il metodo restorePreviousChart,

il quale ripristina il grafico premuto in precedenza, se esiste, al colore originale sfrut- tando l’istanza salvata in previousChart e invocando il metodo setColor(previousColor). In seguito si aggiornano le variabile previousChart e previousColor e si modifica il colore del grafico ricevuto come parametro con il colore ricevuto come parametro.

changeColor(chart, color) - analogo al metodo sopra descritto, ma senza salvare da

alcuna parte il riferimento al grafico da modificare. Semplicemente si invoca il metodo setColor(color) del grafico passato come parametro

deactivateChart - invoca il metodo restorePreviousChart() e setta la variabile pre-

viousChart a null

5.3.1.10 ContextMenu

Questo modulo si occupa di mostrare o nascondere un menu contestuale. Espone 2 metodi:

open(dropDown, coordinates) - dato l’elemento HTML da mostrare come menu si

modifica lo stile di quest’ultimo rendendolo visibile. Utilizzando le regole CSS inol-

tre il menu viene posizionato nel punto corrispondente alle coordinate passate come parametro

close(dropDown) - rende invisibile l’elemento passato come parametro settando il

valore display dello stile a ’none’ e rimuovendo la classe ’show’.

5.3.1.11 DataChanger

Il modulo DataChanger si occupa di modificare i dati visualizzati dai grafici. Espone due metodi:

appendData() - metodo che aggiunge alla finestra visualizzata ulteriori dati pari alla

dimensione specificata in Settings.scrollSize (normalmente 30 secondi). Aggiorna anche il valore di Settings.end.

scrollData() - metodo per modificare la finestra di tempo visualizzata. Dato un para-

metro increment che può assumere valore 1 o -1 modifica la finestra avanti o indietro del valore salvato in Settings.scrollSize. Non viene effettuato lo scroll dei dati se si va oltre Settings.min mentre si torna indietro o Settings.max se si va avanti.

5.3.1.12 Viewport

Il modulo Viewport associa le operazioni disponibili in DataChanger, ColorChanger e Con- textMenu ad eventi scatenati nell’interfaccia. I metodi disponibili sono i seguenti:

init() - metodo da invocare all’inizio, che serve ad inizializzare i moduli DataChanger,

ColorChanger e ContextMenu

enableContext(container, dropDown, selector) - questo metodo serve ad abilitare

l’uso del menu contestuale. Istanzia un listener dell’evento ’contextmenu’ (scatenato dal click destro del mouse) nel container specificato come parametro. Inizialmente previene l’esecuzione dell’azione normale, in seguito determina su quale grafico, al- l’interno di un container, è stato premuto il tasto destro del mouse. Se il click avviene su un grafico esegue la funzione open di ContextMenu mostrando il grafico nel punto dove è posizionato il mouse, altrimenti esegue la funzione close. Inoltre istanzia sul document un listener di click che esegue ContextMenu.close(). In questo modo un click su un punto qualsiasi esterno al container chiuderà un eventuale menu aperto

activeChart(container, color, selector) - in questa funzione viene attivato un liste-

ner sul container passato come parametro. Quando si rileva un click si determina quale grafico è stato premuto, si recupera l’istanza dalla mappa di grafici in Setting utilizzando l’attributo data-id del div premuto e si colora il grafico selezionato

changeColor(colorPicker) - il parametro colorPicker è un elemento input HTML con

type="color". Questo metodo rileva l’evento "change" su colorPicker e invoca il metodo changeColor passando il grafico premuto e il colore selezionato nel color picker

appendData(dataButton) - metodo che istanzia il listener di un evento ’click’ sul bot-

tone passato come parametro. Il listener invocherà il metodo dataChanger.appendData() quando eseguito.

scrollData() - Questo metodo serve per modificare la finestra di dati visualizzata pre-

mendo la freccia destra o sinistra sulla tastiera. Quando viene rilevato l’evento ’keyup’ della freccia destra o sinistra si invoca la funzione scrollData di DataChanger che aggiorna, utilizzando pubsub, le annotazioni del menu laterale.

5.3.1.13 FileUploader

Il caricamento di una nuova registrazione nel server avviene tramite un form. Questo modulo si occupa di aggiungere la lista di pazienti al form e gestire il caricamento dei dati nel server. Viene esposto un metodo:

enableFileUploader(form, submitButton, progressBar, selectPatient, patientsLi- st) - questo metodo si occupa di gestire il caricamento dei file nel server. Dapprima

viene chiamata la funzione populatePatientList(selectPatient, patientsList). SelectPa- tient è l’elemento HTML input del form, mentre patientList è una lista di pazienti, dove ogni elemento della lista contiene il nome completo e l’id associato ad un paziente. Per ogni paziente viene creato un elemento HTML option che viene popolato con no- me completo e valore pari all’id. In seguito ogni option viene aggiunto a selectPatient. In seguito si istanzia un listener di un click sull’oggetto submitButton. Quando viene premuto il bottone di submit i dati del form vengono inseriti in un oggetto FormData, viene creata una nuova XMLHttpRequest che ha come metodo post e come destina- zione l’URI inserito nell’attributo action del form.

Un listener sulla progressbar modifica il valore lo stile della barra per indicare la per- centuale di caricamento dei file. Al termine del caricamento la pagina verrà ricaricata. In questo metodo non si è utilizzato ’fetch’, nonostante sia più moderno, perché era necessario avere l’evento ’progress’ al fine di poter animare la progress bar.

5.3.1.14 Network

Tutte le chiamate al server vengono gestite tramite questo modulo, che esporta un oggetto con 3 funzioni:

getData(source) - Questo metodo accetta un ogggetto source che abbia al suo in-

terno due campi: url e topic. Dopo aver fatto una richiesta all’url indica e aver con- vertito la risposta in JSON viene chiamato pubsub.pub passando come parametro source.topic e la risposta del server. Questo metodo viene usato per passare i dati delle registrazioni da disegnare al modulo Charts.

getHypno(source) - analogo a getData ma viene usato per costruire l’ipnogramma.

Per questo motivo i dati ricevuti prima di venire inviati a Chart devono venire convertiti. Al server vengono richieste tutte le annotazioni, in seguito si filtrano gli eventi che cominciano per ’SLEEP_’ ma che non contengano SPINDLE o KCOMPLEX. Gli eventi rimanenti saranno: SLEEP_S0, SLEEP_S1, SLEEP_S2, SLEEP_S3 e SLEEP_REM. Dagli eventi verranno estratti i valori 0,1,2 e 3, mentre REM verrà convertito in 4 e saranno aumentati di 1 unità. In seguito a Chart() verrà inviato un array contenente le coppie timestamp-valore tra 0 e 5.

getRequest(url, params, opts - questo metodo dato un url e una serie di parametri

che può essere sia un oggetto unico, contenente una chiave e un valore, sia un array di parametri contenti coppie key-value costruirà una richiesta per il server che sarà formata da url e una serie di parametri ’?key=value&’. È possibile passare un oggetto opts contente dettagli su metodo da usare o l’header della richiesta. La risposta del server verrà convertita in JSON e ritornata alla funzione chiamante. Nel caso in cui la risposta del server non possa venire convertita in JSON verrà catturato un errore e stampato a console assieme all’endpoint della richiesta

5.3.1.15 TracesModal

Questo metodo si occupa di popolare dinamicamente il form per il caricamento dei canali e di avviare il caricamento del file desiderato nel server. Esporta un metodo solo:

enableModal(file, tracesModalCheckboxes - la prima operazione effettuata è recu-

perare il nome del file dall’attributo data-file dell’oggetto passato come primo parame- tro. In seguito viene effettuata la chiamata a /load per iniziare il caricamento del file voluto in memoria. Successivamente viene recuperata, tramite una richiesta al server, la lista di canali esistenti nel file e per ogni canale viene creato un oggetto checkbox. I checkbox creati vengono poi aggiunti al elemento tracesModalCheckboxes passato come parametro.

5.3.1.16 ChartsManager

Come suggerisce il nome, questo modulo si occupa di gestire tutti i grafici. Espone i seguenti metodi:

init() - Questo metodo serve per inizializzare correttamente le variabili e deve venire

invocato prima di tutti gli altri. Vengono effettuate 2 richieste al server per poter recu- perare il primo e l’ultimo timestamp della registrazione. Questi valori vengono salvati in Settings.start e Settings.min per l’inizio e Settings.max per la fine. In seguito si calcola la dimensione di un grafico e del suo container basandosi sulla dimensione attuale del container.

buildChartCanvas(chartName, chartId) - Questa funzione crea un div in cui viene

disegnato un grafico. Questo div avrà un attributo data-chart=chartName e uno data- id=chartId. Il metodo ritorna l’elemento creato.

connectChart() - questo metodo serve per sincronizzare il livello di zoom tra tutti i

grafici. Quando viene invocato recupera il livello di zoom dal grafico da cui è stato invocato e aggiorna i valori per tutti gli altri

smartDataZoom - siccome i dati sono sottocampionati dal server potrà capitare che

ad un livello di zoom elevato vi siano troppo pochi punti disegnati. Questo metodo ser- ve a rilevare il livello di zoom ed effettuare una nuova chiamata al server per ottenere ulteriori punti all’interno dell’intervallo attualmente visibile per tutti i grafici.

requestDataChart(key, chartName, start, end) - questo metodo serve per effettuare

una chiamata all’endpoint ’/trace?filename=XXX&channel=key&start=start&end=end’. Una volta recuperati i dati dal server con il metodo net.getData() verrà invocato pub- sub.pub con topic chartName

drawCharts() - In questo metodo vengono disegnati effettivamente i grafici. Si invoca

per ogni canale un’istanza di Chart() e si settano le opzioni come configurato nell’og- getto Settings. in seguito si associa all’evento ’datazoom’ su ogni grafico la funzione connectChart e la funzione smartDataZoom. Inoltre vengono attivate tutte le note e gli handler degli eventi in annotationsManager. I dati veri e propri vengono caricati invocando il metodo requestChhartData e verranno inseriti una volta che il metodo pubsub.pub con topic chartName verrà invocato.

buildHypno() - Per disegnare l’ipnogramma viene invocato questo metodo, il quale

dapprima modifica l’oggetto Settings.options per renderlo adatto al grafico, ad esem- pio impostando il colore della linea in rosso. Infine utilizzerà il modulo Hypnogram e il suo metodo buildHypno per disegnare il grafico.

enableScrollDataFromHypno() - è un metodo che serve ad invocare updateDataFro-

mHypno() di Hypnogram, ovvero la funzione che abilita lo scroll dei dati effettuando un click sull’ipnogramma

5.3.1.17 Punto di accesso

Il file main.js rappresenta il punto d’accesso dell’applicazione. In questo file vengono re- cuperati tutti gli elementi HTML necessari al funzionamento del sistema, inoltre vengono inizializzati i moduli utilizzati. Viene istanziato un oggettoapp che ha i seguenti metodi:

getPatientsList - utilizzando net.getRequest recupera la lista di tutti i pazienti dal

server e li salva in una variabile patientsList

loadTracesFile() - In questo metodo vengono svolte diverse operazioni per disegnare

i grafici ed abilitare le varie funzionalità implementate. Innanzitutto si recupera quali checkboxes sono stati selezionati per sapere i canali da caricare.

Dal form di caricamento si salva in una variabile in Settings qual è la dimensione della finestra desiderata in secondi. Data la dimensione della finestra si può stabilire qual’è il timestamp finale voluto, che viene salvato in Settings.end.

Nel documento Web based graph library (pagine 59-73)

Documenti correlati