Implementarea Unei Aplicatii Destinată Reprezentării Grafice A Indicatorilor DE Performantă Obtinuti DIN Diferite Fisiere Sursă

UNIVERSITATEA TRANSILVANIA DIN BRAȘOV

FACULTATEA DE INGINERIE ELECTRICĂ ȘI ȘTIINȚA CALCULATOARELOR

Programul de studii: AUTOMATICĂ ȘI

INFORMATICĂ APLICATĂ

PROIECT DE DIPLOMĂ

Student,

Călin Ionuț DRĂGAN

Îndrumător,

Prof. Șef lucrări. dr. fiz. Laura FLOROIAN

BRAȘOV

2016

UNIVERSITATEA TRANSILVANIA DIN BRAȘOV

FACULTATEA DE INGINERIE ELECTRICĂ ȘI ȘTIINȚA CALCULATOARELOR

Programul de studii: AUTOMATICĂ ȘI

INFORMATICĂ APLICATĂ

IMPLEMENTAREA UNEI APLICAȚII DESTINATĂ REPREZENTĂRII GRAFICE A INDICATORILOR DE PERFORMANȚĂ OBȚINUȚI DIN DIFERITE FIȘIERE SURSĂ

Student,

Călin Ionuț DRĂGAN

Îndrumător

Prof. Șef lucrări. dr. fiz. Laura FLOROIAN

BRAȘOV

2016

Introducere

Scopul proiectului este următorul: realizarea unei aplicații utilizată pentru generarea de reprezentări grafice ale datelor provenite din diverse fișiere sursă.

Aplicația GDRT (Graphical Data Representation Tool) a fost realizată cu sprijinul companiilor Schaeffler România și Schaeffler Herzogenaurach și este utilizată pentru obținerea graficelor din fișiere sursă ce conțin informații despre indicatorii de performanță ai serverelor. De asemenea, aplicația poate fi utilizată pentru absolut orice fișier care respectă o anumită structură ce poate fi inserată într-un format tabelar. Aplicația suportă diverse formate ale fișierelor de intrare și încearcă, pe cât posibil, realizarea unor reprezentări grafice a datelor. Formatele suportate au fost alese în funcție de alte aplicații interne care generează ca rezultat fișiere cu structuri diverse. În mare, procesul constă în monitorizarea serverelor de interes, păstrarea în istoric a tuturor informațiilor, generarea unui fișier conținând date dintr-un anumit interval de timp, iar în final crearea unor rapoarte/ grafice.

Windchill-ul este un software de tip PLM dezvoltat de compania PTC. Product Lifecycle Management (PLM) ajută companiile să-și gestioneze într-un mod eficient, ciclul de viață al produselor. Mai concret, Windchill-ul este o mare bază de date în care se introduc și extrag, în funcție de drepturi, toate informațiile care circulă în grupul Schaeffler. Un mare avantaj al acestui soft este trasabilitatea, toate tranzacțiile fiind păstrate în istoric, fără ca utilizatorii să aibă posibilitatea de ștergere a informațiilor. PLM este alcătuit din mai multe domenii:

CAE (simularea asistată de calculator)

CAD/CAM (proiectarea și fabricația asistată de calculator)

PDM (gestionarea datelor produsului)

În grupul Schaeffler, Windchill-ul este folosit în toate filialele, în mare parte de către proiectanți. Aproape în orice filială există un server care gestionează milioanele de documente existente în acea locație. Datorită cantității mari de date și a schimbărilor frecvente care apar în sistem, aceste servere trebuie monitorizate și administrate cu foarte mare responsabilitate. Din această necesitate de administrare/ monitorizare a performanței serverelor s-a dezvoltat aplicația GDRT care poate genera într-un timp scurt un grafic plecând de la fișiere de dimensiuni mari. Fiind o companie multinațională, cu un număr mare de utilizatori ai Windchill-ului, serverele trebuie să funcționeze 100% din timp.

Cea mai mică problemă apărută în sistem poate genera pierderi mari pentru companie și pentru partenerii/ clienții acesteia care își așteaptă produsele. Cu cât sistemul este mai complex, cu atât riscul apariției unei eventuale probleme este mai mare. Deși se încearcă administrarea cât mai eficientă a serverului, sunt foarte mulți factori care pot influența buna funcționare a acestuia, iar uneori apar probleme. În cazul în care problema influențează munca proiectanților, project-managerilor sau a altor persoane care utilizează Windchill-ul, este clar că trebuie luate măsuri. Bineînțeles că prima preocupare a administratorilor de servere este remedierea problemei pentru ca angajații să-și poată continua munca. Pe plan secundar, după remedierea problemei, trebuie realizată o analiza asupra cauzelor care au condus la această „defecțiune”. Studiind jurnalul serverelor, este aproape imposibil de găsit ce a produs eroarea din sistem și momentul exact al apariției acesteia. Din acest motiv, aplicația GDRT este utilă: administratorul poate introduce fișierul de log în soft, își setează opțiunile în funcție de parametrii de interes și obține o reprezentare grafică unde poate vedea exact cauza problemei.

S-a dorit dezvoltarea acestui soft deoarece, momentan, pe piață nu există o aplicație gratuită care să îndeplinească toate condițiile cerute:

Procesarea rapidă a fișierelor de dimensiuni mari

Obținerea a diverse tipuri de grafice generate dinamic, în funcție de intrări

Opțiunea de stocare a datelor procesate în memoria calculatorului

Opțiunea de template (păstrarea opțiunilor alese de utilizator pentru fiecare fișier procesat prin intermediul aplicației)

Pentru a oferi un exemplu al utilizării aplicației, putem lua în considerare următorul fișier (fișier cu date irelevante, pentru a respecta politica de confidențialitate a firmei):

Figura I.1 – Exemplu fișier intrare GDRT

Acest fișier conține informații despre statusul serverelor din locațiile respective(numele serverului, data exactă când serverul avea statusul respectiv precum și valoarea statusului).

Având la intrare acest fișier generat din Windchill, putem monitoriza statusul serverelor, utilizând GDRT. Astfel, vom avea la ieșire următorul grafic pe care îl punem utiliza în analize, rapoarte sau pur și simplu pentru a verifica dacă totul a fost în regulă:

Figura I.2 – Grafic 3D-Bar generat din fișierul de test

O importanță majoră o reprezintă performanța aplicației, deoarece fișierele sursa sunt în general fișiere de tip .TXT sau .CSV, având dimensiuni de ordinul sutelor de megabytes ( sute de mii – milioane de linii). Este dorită, bineînțeles, o procesare cât mai rapidă a datelor, având un timp cât mai mic de așteptare. Totodată, opțiunea de păstrare în memorie a informațiilor generate din fișier, precum și a celor definite de utilizator (opțiunea de template) prezintă interes pentru evitarea timpilor de așteptare mari.

Principiul de bază al proiectului este următorul:

Utilizatorul își alege fișierul pe care dorește să-l proceseze și să-l reprezinte grafic și îl încarcă în cadrul aplicației

În partea de preprocesare, se selectează datele care prezintă interes împreună cu unele informații suplimentare, pentru a facilita citirea fișierului

În partea de procesare, se citește fișierul și se populează listele cu valorile necesare reprezentării

Se memorează informațiile despre fișierul respectiv într-un cache local, evitând astfel timpul de așteptare în cazul în care utilizatorul dorește o nouă reprezentare grafică a aceluiași fișier

Se generează diferite tipuri de grafice (bar/line/pie/area), în funcție de nevoile utilizatorului

Se modifică și analizează graficele obținute

Se salvează graficele, urmând a fi folosite în diverse statistici

Capitolul 1. Aspecte generale

1.1 Mediul de lucru

Aplicația GDRT are la bază limbajul de programare Java (utilizând Java SE7), iar mediul de dezvoltare utilizat este Eclipse (Eclipse IDE for Java EE Developers).

Eclipse este un mediu de dezvoltare integrat (IDE) utilizat în programarea calculatoarelor. Acesta conține un spațiu de lucru și un sistem extensibil de plug-in-uri pentru personalizarea mediului de lucru. Eclipse este scris cea mai mare parte în Java, iar utilizarea sa principală este pentru dezvoltarea de aplicatii Java, dar poate fi de asemenea folosit pentru a dezvolta aplicații în alte limbaje de programare prin utilizarea de plug-in-uri: C, C ++, Cobol, Fortran, Haskell , JavaScript, Julia, Lasso, Lua, Perl, PHP, Prolog, Python etc. Eliberat în conformitate cu termenii licenței Eclipse Public, Eclipse SDK este un software gratuit și open-source.

Java este un limbaj de programare, orientat pe obiecte, dezvoltat de fosta companie Sun Microsystems (actual Oracle) și lansat în anul 1995. Creatorul Java este James Gosling iar utilitatea inițială a fost pentru programarea aparaturii electronice. Mai tâziu, Java a avansat la aplicații Web, apoi la aplicații locale și client-server. În prezent, Java este un mediu de programare ce cuprinde:

Un limbaj de programare

Un compilator ce transformă fișierul de intrare în bytecode (un limbaj intermediar)

O mașină virtuală ce creează instrucțiuni executabile din codul intermediar

O bibliotecă puternică

În ceea ce privește orientarea pe obiecte, se pot evidenția principalele caracteristici ale obiectelor: încapsularea, moștenirea și polimorfismul. Încapsularea reprezintă proprietatea obiectelor de a restricționa accesul asupra unor date și metode. Este permis accesul doar la datele și metodele declarate ca fiind publice. Încapsularea are rolul de a crește fiabilitatea sistemului, evitând posibilele modificări nedorite ale valorilor. Moștenirea este caracteristica unei clase de a îngloba toate variabilele și metodele superclasei sale. Ea poate fi simplă sau multiplă (cea simplă are maxim o superclasă, iar cea multiplă poate avea mai multe superclase). Polimorfismul permite unei operații să funcționeze în mod diferit în clase diferite.

Pentru dezvoltarea aplicației, au fost necesare anumite biblioteci specifice Java, cu ajutorul cărora a fost posibilă realizarea unor grafice la o calitate bună și într-un timp scurt.

1.2 Principalele intrări/ ieșiri

Încă din faza inițială a proiectului, s-a stabilit tipul documentelor pentru care aplicația este destinată. Deși extensia nu este cea mai importantă caracteristică, aplicația GDRT acceptă momentan doar anumite tipuri de fișiere, având formaturi stabilite în funcție de necesități. Această filtrare a fost realizată pentru siguranța sistemului, pentru a restricționa eventuale alegeri inutile ale utilizatorului. Într-o versiune anterioară a aplicației era posibilă alegerea oricărui tip de fișier, fără nicio filtrare, dar s-a constatat că este o pierdere de timp să existe o imagine sau un executabil ca intrare, cu scopul realizării unui grafic.

Principalele intrări sunt:

Fișiere de tip text

Fișiere de tip csv

Fișiere de tip doc

Baze de date (în curs de dezvoltare)

Principalele ieșiri:

Grafice de tip line/bar/area simple sau compuse

Imagini de tip PNG (conținând rezultatele reprezentării)

Fișiere de tip PDF (conținând rezultatele reprezentării)

Fișiere cache conținând informații obținute în urma procesării fișierelor sursă

În general, dacă avem la intrare un fișier care poate fii reprezentat într-un tabel și respectă condiția ca elementele de pe fiecare linie sa fie separate printr-un delimitator, se poate crea un grafic de pe urma acestuia.

Etapa de preprocesare (care va fi detaliată în capitolul 3) realizează, pe lângă alte

funcționalități și o verificare a intrărilor. Dacă se introduce un alt tip de fișier, care nu respectă formatul cerut, în etapa de preprocesare va fi imposibil de setat axa OX a graficului, precum și coloana ce conține setul de date al graficului. Astfel, se previn eventualele probleme, iar codul etapei de procesare nu este rulat niciodată.

Salvarea ieșirilor în diverse formate este facilitată de utilizarea bibliotecii JFreeChart, care conține funcții predefinite de salvare a graficelor create de utilizator. În urma salvării, graficul va exista în fișierul de pe hard-disk, în formatul standard (fără zoom, autoscalat, iar sub grafic va exista legenda acestuia).

Aceste funcționalități sunt importante, deoarece ele reprezintă finalizarea procesului. Graficele sunt utilizate în mare parte pentru statistici, dar sunt extrem de utile pentru a descoperi cauza unei eventuale probleme, precum și timpul în care aceastea au apărut.

1.3 Principalele funcționalități

Principalele cerințe ale soft-ului sunt următoarele:

Performanță foarte bună (procesarea trebuie realizată rapid ținând cont de mărimea fișierelor și de numărul de linii care poate fii chiar și de ordinul milioanelor)

Opțiunea de stocare a datelor necesare reprezentării într-un fișier local după prima citire (utilă pentru viitoarele reprezentări ale aceluiași fișier, evitând astfel timpii mari de așteptare)

Opțiunea de salvare/încărcare template (utilă din același motiv, pentru evitarea timpilor mari de așteptare). Dacă se dorește încărcarea unui fișier care a fost deja reprezentat (cu condiția ca acesta sa nu fi fost modificat între timp), utilizatorul are opțiunea de încărcare template, iar dintr-un fișier local se vor uploada toate datele reprezentării precedente (de exemplu: numele coloanelor, coloanele selectate pentru reprezentare, numărul de eșantioane utilizate etc.)

Partea de preprocesare a fișierului (tot din motivul performanței). Pentru a nu citi întregul fișier, s-a implementat o metodă prin care utilizatorul își poate alege doar elementele de care are nevoie și locul lor în grafic, înainte de partea de procesare.

Funcționalități suplimentare:

Previzualizare a primelor 20 de linii (în urma etapei de preprocesare, s-a implementat pe interfața grafică o opțiune care generează un nou frame conținând primele n linii din fișierul sursă, fără nicio procesare, unde n aparține intervalului [0-20])

Setare număr de eșantioane (această funcționalitate este poate cea mai des folosită dintre cele modificabile. Setarea numărului de eșantioane este o etapă în care este nevoie de puțină experiență cu aplicația pentru a alege numărul exact de eșantioane conform necesităților utilizatorului. Dacă numărul este prea mic, problema în sistem poate fi pierdută în elementele graficului. Dacă numărul este prea mare, problema poate fi evidențiată ușor, dar nu poate fi detaliată datorită suprapunerii pixelilor din imagine)

Setare axă OX (în urma etapei de preprocesare, una dintre coloanele determinate de aplicație va fi setată ca axă OX. Este acceptată orice coloană, nu există nicio filtrare. Poate fi de tip numeric sau șir de caractere. Pentru a obține rezultatul dorit, în mod normal, se adaugă coloana ce conține timpul în care s-au petrecut evenimentele respective)

Selectarea tipului de date al coloanelor (String, numeric, dată)

Curățare fișier cache local (Pe interfața grafică s-a implementat un buton cu această funcționalitate. În cazul în care utilizatorul, din diverse motive, dorește să șteargă toate informațiile din fișierul de cache, o poate face prin intermediul acestui buton. Înainte de ștergere, butonul generează un mesaj de avertizare în care întreabă utilizatorul dacă este sigur că dorește ștergerea fișierului de cache. Nu este indicat acest lucru deoarece, odată șters, se pierd toate informațiile păstrate, iar timpii de așteptare mari vor reveni pentru fișierele care au fost deja procesare)

Salvare reprezentare în format PDF/ PNG (Această funcționalitate este generată de biblioteca JFreeChart și se poate aplica oricărui tip de grafic)

Setare tip de reprezentare

Bar chart/ Pie chart/ Line chart/ Area chart/ 3D charts

Valori medii/ minime/ maxime

1.4 Schema bloc

Figura 1.1 – Schemă bloc a procesului GDRT

1.5 Date de pornire

Proiectul GDRT are ca date de pornire orice tip de fișier care satisface următoarele condiții:

Conține date concludente (cel puțin o coloană cu elemente numerice)

Elementele de pe rânduri sunt separate printr-un delimitator (care trebuie sa fie același pentru tot fișierul)

(de preferat) conține o coloana de tip dată (minutul/ora/ziua/luna/anul în care s-a petrecut evenimentul de pe linia respectivă)

(de preferat) conține același număr de elemente pe fiecare linie (în urma separării după delimitator)

Un exemplu de fișier ce poate fii reprezentat poate fi următorul:

Figura 1.2 – Exemplu fișier sursă

Momentan, majoritatea fișierelor care trebuie reprezentate, sunt de tip .TXT sau CSV. Pe viitor, se dorește extinderea aplicației pentru a putea reprezenta grafic informații obținute din baze de date. Din punct de vedere logic, n-ar trebui să existe restricții în ceea ce privește fișierul de intrare, dar pentru siguranță s-a stabilit acest filtru care permite utilizatorului să aleagă doar anumite tipuri de fișiere. Dacă pe viitor se va dori realizarea unor reprezentări grafice din fișiere cu extensii nesuportate momentan, acea funcționalitate va fi disponibilă foarte rapid, deoarece codul funcției respective este unul destul de simplu, iar singura modificare care va fi făcută va consta în adăugarea unui nou tip de format în lista extensiilor suportate.

În general, aplicația poate fii folosită pentru orice tip de fișier care respectă condițiile enumerate mai sus, dar își arată utilitatea în reprezentarea fișierelor ce conțin informații despre statusul serverelor din toate filialele companiei. De exemplu, dacă într-un server din China a fost o problemă într-o anumită zi, este mult mai la îndemână să se încarce fișierul ce conține informații despre server, să se reprezinte într-un grafic și să se observe imediat la ce oră a picat serverul, decât să se deschidă un fișier text de 500MB și să se caute în milioanele de rânduri o valoare anormală. O altă idee de utilizare a aplicației poate fi pentru verificarea performanței echipelor dintr-un departament pe o anumită perioadă de timp: se creează un fișier excel cu diverse funcții de calcul al performanței, se realizează calculul pentru fiecare echipă, iar apoi se procesează fișierul cu ajutorul aplicației, iar rezultatele pot fi făcute publice angajaților.

Aplicația a fost realizată pe ideea de a putea reprezenta grafic orice tip de fișier ce poate fi folosit într-o statistică (inclusiv pentru statisticile privind performanța departamentelor companiei).

Capitolul 2. Proiectarea aplicației

2.1 Resurse necesare

Pregătirea resurselor necesare proiectării sistemului a reprezentat o etapă importantă în realizarea aplicației GDRT. În urma unor discuții, s-a hotărât să se utilizeze ca limbaj de programare Java, iar ca mediu de dezvoltare Eclipse-ul. Unul din motivele pentru care s-a ales programarea orientată pe obiecte a fost acela că în cazul unui impas, dezvoltatorul putea primi ajutor din partea echipei care lucrează în acest domeniu. Deși un alt mediu de dezvoltare, NetBeans, oferea mai mult ajutor în ceea ce privește anumite funcții predefinite, s-a preferat utilizarea Eclipse-ului datorită experienței dobândite în cadrul facultății.

Interfața a fost creată pe baza unui JDesktopPane (care poate fi văzut ca un desktop

virtual) împreună cu frame-uri interne utilizate în general pentru grafice, pentru partea de preprocesare sau pentru diverse funcții suplimentare. Utilizarea acestor elemente specifice Java a fost de mare ajutor, codul fiind ușor de testat, având o interfață grafică.

Pentru început, s-au folosit fișiere de test, fișiere simple cu câteva zeci de linii, pentru a testa funcționalitățile de bază ale aplicației (citirea fișierului, împărțirea liniilor după separator, adăugarea în liste a valorilor). După această etapă, s-au utilizat fișiere reale conținând date din serverele companiei (fișiere de tip csv conținând statusul serverelor din toată lumea pe parcursul unui an, fișiere de tip txt conținând informații despre timpii de executare ai unor funcții specifice ). Această metodă a fost utilă pentru înțelegerea conceptului proiectului, dar au apărut probleme mai târziu deoarece se păstra toată informația din fișierul de intrare în memorie. Pentru fișiere de peste 500MB, timpul de așteptare pentru procesarea întregului fișier era prea mare așa că a fost nevoie să se schimbe metoda de citire pentru a nu ocupa toată memoria calculatorului.

Din punct de vedere harware, laptopul pe care a fost implementată aplicația au fost de foarte bună calitate în ceea ce privește performanța. Acest lucru a fost de mare ajutor mai ales din perspectiva testării. În etapa de scriere a codului, după finalizarea implementării oricărei metode noi, a avut loc o scurtă testare a funcționalității întregului sistem. Această performanță a componentelor hardware s-a simțit în urma testării pe fișierele mari, în ceea ce privește timpul de așteptare, care era mult mai redus. Tot în această categorie pot intra și diferențele de afișaj, testându-se pe diferite rezoluții dar și pe diferite monitoare sau display-uri ale laptopurilor.

2.2 Performanțe dorite

Dacă ne referim doar la performanța aplicației, sistemul trebuie să genereze ieșiri

într-un timp cât mai scurt, având în vedere că fișierele de intrare conțin milioane de linii. Partea de cod care se compilează cel mai greu este partea de citire a fișierului, deoarece în afară de parcurgerea tuturor liniilor, există multe verificări și adăugări în liste (liste ce conțin datele necesare realizării graficelor).

Pentru îmbunătățirea performanței, a fost nevoie de crearea unei părți de preprocesare. După alegerea fișierului, se citesc doar primele 100 de linii și se alege separatorul și rolul fiecărei coloane pentru reprezentarea grafică. Astfel, prin anumite verificări, se citesc doar datele relevante, ignorându-se datele inutile. Aceasta parte de preprocesare a îmbunătățit semnificativ performanța aplicației, timpul de execuție micșorându-se cu aproximativ 50%.

Prin testarea pe fișiere mari (cu mărimi de ordinul sutelor de megabytes) s-a ales și metoda de citire care oferea cel mai scurt timp de procesare (această parte va fi detaliată în capitolul 3).

Un alt aspect în ceea ce privește performanța este corectitudinea datelor. Degeaba fișierul este procesat într-un timp scurt dacă datele rezultante sunt eronate. Pentru acest criteriu de performanță s-a depus, probabil, cel mai mult efort, datorită multitudinii de fișiere sursă care pot fi introduse, fiecare cu un alt format și conținând date diferite. Metodele ce influențează acest criteriu au fost testate nu doar pentru fiecare fișier, ci și în urma implementării oricărei metode noi care obținea date de la aceasta. Etapa de procesare a datelor este cea mai complexă etapă a sistemului și ca urmare influențează procesul într-o mare măsură. S-a încercat realizarea metodelor în cel mai simplu mod cunoscut de utilizator, cu cât mai puține instrucțiuni și fără a suprasolicita procesorul calculatorului de testare. S-au stabilit anumite limite decente pentru numărul de elemente existente în interfața aplicației. De exemplu s-a considerat că numărul maxim de coloane ale unui fișier de intrare este sub 100. Toate elementele sunt create prin intermediul unor structuri repetitive care iterează coordonatele acestora, plasându-le într-un mod dinamic și plăcut. Dacă ar exista prea multe elemente, ultimele nu ar mai fi vizibile pe ecran.

Atât criteriu de corectitudine al datelor, cât și cel al timpului mic de așteptare sunt influențate aproape în totalitate de metoda citirii. Așadar a fost necesară găsirea unei balanțe cât mai echilibrate pentru a satisface ambele criterii.

2.3 Tehnologii utilizate

În urma etapei de stabilire a limbajului de programare și a mediului de dezvoltare, a urmat alegerea celei mai eficiente tehnologii pentru obținerea rezultatelor dorite. Această alegere nu a fost foarte dificilă deoarece în faza inițială era nevoie de o singură tehnologie prin intermediul căreia să fie realizate graficele. Criteriile de alegere au fost următoarele: tehnologia să fie gratuită, să existe documentație și feedback pozitiv din partea altor utilizatori, graficele să fie clare, să poată reprezenta un număr mare de elemente. A reprezentat un avantaj existența unor funcționalități suplimentare (de exemplu opțiunea de salvare a graficelor, opțiunile de zoom-in, zoom-out, autoscalare).

După multe teste, pentru realizarea graficelor, s-a ales biblioteca JFreeChart din mai multe motive:

Este o bibliotecă 100% gratuită

Este o bibliotecă intuitivă, ușor de manipulat și foarte flexibilă

Conține foarte multe tipuri de grafice care pot fi realizate cu ușurință și într-un mod asemănător

Conține funcții suplimentare pentru salvarea graficelor în diverse formate, opțiuni de zoom-in, zoom-out, autoscalare sau de modificare a unor elemente din grafic (de exemplu: modificare culorii unui set de date, modificare numelor din legenda graficului, adăugarea sau excluderea grid-ului)

Este utilizată de mulți dezvoltatori Java și prin urmare există informație pe Internet despre majoritatea aspectelor referitoare la această bibliotecă

Elementele specifice Java sunt destul de intuitive, astfel încât să nu fie nevoie de un ghid pentru utilizarea aplicației. Am folosit următoarele elemente:

Câmpuri de text (JTextField) pentru numele coloanelor (needitabile), pentru opțiunea de previzualizare a primelor n linii (editabilă) și pentru introducerea numărului de eșantioane dorit de utilizator (de asemenea editabilă)

Căsuțe de bifat (JCheckBox) pentru alegerea coloanelor pe care utilizatorul dorește sa le utilizeze în grafic

Butoane radio (JRadioBox) pentru alegerea axei OX în cazul în care utilizatorul nu a definit-o în partea de preprocesare (această opțiune a fost înlocuită în versiunea finală a aplicației deoarece definirea axei OX are loc acum în etapa de preprocesare)

Etichete (JLabel) pentru a face aplicația mai intuitivă (este cea mai des utilizată componentă Java în cadrul aplicației. În toate cazurile etichetele sunt utilizate în dreptul celorlalte elemente pentru a sugera funcționalitatea componentei respective. De exemplu, în dreptul câmpului de text aferent setării numărului de eșantioane există un JLabel cu conținutul „Set number of samples:”.)

Butoane (JButton) pentru diverse acțiuni în frame-uri (Butonul pentru alegerea fișierului va deschide un JFileChooser prin intermediul căruia se poate căuta în calculator pentru fișierul dorit. Butonul pentru partea de încheiere preprocesare va realiza două verificări: dacă s-a ales o coloană ca axă OX și dacă există cel puțin o coloană setată ca set de date, Dacă aceste condiții sunt respectate, va fi apleată metoda de citire integrală a fișierului. Butonul pentru ștergerea fișierului de cache va declanșa un mesaj de siguranță care va întreba utilizatorul dacă este sigur că dorește ștergerea cache-ului. Dacă primește confirmare, fișierul se șterge de pe hard-disk și va fi creat din nou la următoarea reprezentare grafică)

Frame-uri interne și independente (JFrame și JInternalFrame)

2.4 Tipuri de date

În cadrul aplicației, sunt acceptate orice tipuri de date, dar cu anumite restricții în partea de preprocesare a datelor:

Fiecare coloană trebuie să conțină același tip de date pentru o reprezentare relevantă. Dacă un fișier conține, spre exemplu, atât caractere cât și valori numerice pe aceeași coloană, reprezentarea grafică va fi inutilă și incorectă.

O singură coloană poate fi setată ca axa OX. Din nou, pentru ca reprezentarea să fie relevantă, este indicat ca această coloană să conțină informații de tip „datetime”

Trebuie să existe cel puțin o coloană de tip numeric (int, float, double etc.) deoarece altfel vom avea un grafic gol. În etapa de preprocesare se realizează această verificare și nu este permisă trecerea în etapa următoare fără această condiție

Pot fi alese mai multe coloane de tip numeric

Pot exista coloane de tipul String cu ajutorul cărora putem filtra conținutul datelor(de exemplu putem alege coloana ce conține locațiile filialelor companiei ca String, iar dacă vom selecta doar Brașovul, vom primi informații doar din această locație)

Pot fi excluse coloanele care nu prezintă interes, fără a conta tipul de date al acestora.

Capitolul 3. Implementarea aplicației

3.1 Preprocesarea datelor

În urma stabilirii scopului proiectului, a limbajului de programare care va fi utilizat, al mediului de dezvoltare, al resurselor necesare, s-a trecut efectiv la implementarea aplicației, scrierea codului.

Etapa de preprocesare, așa cum există astăzi în versiunea curentă a aplicației, nu a fost în planul de implementare inițial. În locul ei, exista un algoritm care selecta rolul coloanelor detectate, fără acordul utilizatorului. Datorită diversității fișierelor sursă, s-a renunțat la acea idee din două motive:

Existau mulți factori care puteau influența buna funcționare a aplicației. De exemplu, pentru axa OX exista o metodă care căuta în primele linii ale fișierului un element de tip date-time. Doar pentru acest exemplu puteau apărea multe probleme în funcționalitate (dacă fișierul nu avea o coloană date-time, dacă acea coloană nu era recunoscută datorită existenței unui format aparte, dacă fișierul avea două sau mai multe coloane de tipul date-time și exemplele pot continua)

Performanța aplicației în ceea ce privește timpul de așteptare era mult mai mare datorită prezenței algoritmilor complecși (pentru determinarea axei OX exista o listă largă de variante de format date-time, pentru determinarea coloanelor de tip set de date, se verifica fiecare element al fiecărei linii dacă este număr)

Astfel, s-a decis crearea unei clase diferite, a cărei funcționalitate se declanșează

imediat după alegerea fișierului și se încheie înainte de citirea linie cu linie a acestuia.

S-a ales implementarea clasei de preprocesare pentru a evita timpii mari de așteptare și pentru siguranța obținerii unor rezultate corecte. Funcționalitatea acestei clase este compusă din patru metode:

Setarea delimitatorului

Setarea numelui coloanelor

Setarea rolului coloanelor

Finalizarea preprocesării

Exemplul următor este un frame generat de această metodă. Conține informații de

test (irelevante), datorită politicii de confidențialitate a companiei:

Figura 3.1 – Etapa de preprocesare- interfață grafică

Fără a selecta coloana ce conține valorile de pe axa OX și cel puțin o coloană de date, preprocesarea nu poate fi finalizată. Vor fi prezentate și detaliate toate funcționalitățile acestei etape în subcapitolele următoare.

3.1.1 Setarea delimitatorului

Pentru setarea delimitatorului s-au creat doua metode:

una pentru detectarea automată a acestuia

una pentru setarea manuală a sa (în cazul în care utilizatorul dorește să modifice separatorul detectat automat)

Pentru detectarea automată a delimitatorului, metoda aferentă realizează o citire a primelor 20 de linii și cu ajutorul unui counter, detectează caracterul care apare cel mai des. De asemenea, pentru a evita o detectare eronată (în cazul în care un număr sau o literă apare mai des decât separatorul dorit) am creat o listă de caractere care conține toți delimitatorii posibili. Dacă, din diverse motive, se dorește schimbarea acestui separator detectat automat, există opțiunea de a-l modifica manual cu un element care există în lista de separatori. În cazul în care utilizatorul aplicației dorește modificarea delimitatorului cu alt caracter sau număr ce nu există în listă, acest lucru nu este posibil. El v-a primi un mesaj de avertizare, spunând că delimitatorul ales nu există în listă. Această funcționalitate a fost implementată pentru siguranța aplicației, pentru ca utilizatorul să nu aleagă un delimitator eronat și să primească un tabel de preprocesare nedorit. Scopul aplicației a constituit un alt factor pentru această restricție, deoarece pentru o realizarea unui grafic nu are sens ca separatorul să fie o cifră sau un caracter alfabetic.

Codul sursă al metodei care determină automat separatorul a fost atașat în anexa 3.

3.1.2 Setarea numelui coloanelor

Pentru această metodă, s-au creat căsuțe de tip text pentru fiecare coloană detectată, pentru a putea seta manual numele coloanelor. Coloanele au în mod implicit numele „Coloana + indexul coloanei” pentru a nu fi nevoie mereu să se adauge numele tuturor coloanelor pentru a finaliza preprocesarea. Deoarece aceste șiruri de caractere, corespunzătoare fiecărei coloane sunt transmise mai departe, nu este permis ca o coloană să nu aibă niciun nume. Chiar dacă respectiva coloană nu va fi selectată cu niciun rol, sau va fi exclusă din grafic, datorită opțiunii de întoarcere în etapa de preprocesare, ea poate avea un rol bine definit mai târziu. Tocmai de aceea este nevoie ca fiecare coloană să aibă un nume. În momentul în care butonul de finalizare al preprocesării se apasă, acesta realizează o verificare a numelor coloanelor, iar dacă într-un câmp de text nu găsește nicio valoare, va seta din nou numele cu „Coloana + indexul coloanei”.

Numele coloanelor este transferat într-o căsuță de text în frame-ul principal și totodată în reprezentarea grafică, fiecare coloană având o culoare diferită. Căsuța de text este needitabilă. Pentru a o edita (schimba numele coloanei) trebuie apăsat butonul de întoarcere în etapa de preprocesare („Back to preprocessing”) și schimbat numele din frame-ul respectiv. Dacă două coloane au același nume, aplicația va adăuga un index suplimentar celei din urmă (de exemplu dacă avem două coloane cu numele „Test”, în etapa de procesare vor apărea cu numele „Test” și „Test(1)”). Această adăugare a indexului suplimentar s-a implementat în concordanță cu funcționalitatea Windows, fiind mult mai pe înțelesul utilizatorilor.

3.1.3 Setarea tipului de date al coloanelor

Setarea tipului coloanelor este cea mai importantă parte a etapei de preprocesare. Opțiunile posibile pentru tipul fiecărei coloane sunt următoarele:

Setare pe post de axă OX

Setare pe post de coloană șir de caractere

Setare pe post de coloană numerică

Excludere coloană

Un exemplu de preprocesare în care tipul coloanelor este definit, poate fi

reprezentat de următorul tabel (datele din tabel sunt date de test, irelevante, datorită politicii de confidențialitate a companiei):

Figura 3.2 – Tipuri de date al coloanelor

Setarea ca axă X (culoarea albastră) poate fi realizată doar pentru o singură coloană,

iar valorile acestei coloane vor reprezenta valorile axei OX din grafic. Pentru finalizarea preprocesării este absolut necesar ca o coloană să fie selectată ca axă OX. Nu contează tipul de date al coloanei respective. Este acceptat orice tip (numeric, șir de caractere, date-time etc.), cu excepția, bineînțeles, a coloanelor goale.

Setarea pe post de coloană șir de caractere (culoarea verde deschis) poate fi realizată, de asemenea, doar pentru o singură coloană. Valorile acestei coloane vor fi verificate în partea de procesare a datelor în felul următor: se caută toate string-urile diferite, se adaugă într-o listă și vor fi utile dacă utilizatorul dorește să realizeze câte un grafic pentru fiecare string diferit. Putem lua ca exemplu figura I.1 pentru a indica necesitatea acestei opțiuni: în cazul în care dorim să afișăm statusul fiecărui server separat (pentru a putea realiza o comparație), această opțiune ne ajută deoarece va crea câte un grafic pentru fiecare server.

Setarea pe post de coloană numerică (culoarea verde închis) poate fi realizată pentru mai multe coloane. Pentru finalizarea preprocesării este absolut necesar ca cel puțin o coloană să fie selectată pe post de coloană numerică. Valorile acestei coloane reprezintă plot-ul graficului. Poate fi selectată o coloană ca fiind numerică, chiar dacă aceasta conține doar caractere, dar în etapa de preprocesare, graficul va fi gol deoarece nu se poate realiza o reprezentare din șiruri de caractere. Valorile eșantioanelor fiecărei coloane vor fi corelate cu string-urile din coloana șir de caractere și cu valorile coloanei setate ca axă OX, iar împreună vor forma graficul dorit.

Excluderea unei coloane (culoarea gri) nu este neapărat necesară. Această opțiune setează coloana respectivă ca fiind irelevantă. Este necesară doar dacă utilizatorul a setat o coloană din greșeală, iar apoi dorește să-i schimbe tipul.

3.1.4 Finalizarea preprocesării

Etapa de preprocesare se finalizează apăsând butonul „Done”. Preprocesarea poate fi finalizată cu două condiții: să existe o coloană setată ca axa OX și cel puțin o coloană setată pe post de coloană numerică. După ce butonul este apăsat, se declanșează citirea fișierului ținând cont de toate selecțiile făcute în partea de preprocesare. În același timp, numele coloanelor va fi transferat către etichetele din frame-ul principal și se vor crea checkbox-urile aferente coloanei de tip șir de caractere.

Întotdeauna se poate întoarce din frame-ul principal la frame-ul de preprocesare, apăsând butonul „Back to preprocessing”, dacă se dorește orice modificare. În cazul în care se produce orice modificare a tabelului de preprocesare, aceasta va declanșa o nouă citire, în funcție de noile setări, iar frame-ul principal va fi reîmprospătat.

Etapa de preprocesare este o etapă intermediară în procesul aplicației. Poate fi etichetată ca fiind liantul dintre alegerea fișierului și procesarea acestuia. În cadrul acestei etape se pregătesc datele pentru a simplifica pe cât posibil procesul. A fost implementată în cel mai simplu intuitiv și util mod. Deși nu apărea în planul inițial al proiectului, etapa preprocesării a adus un mare avantaj aplicației, crescând performanța semnificativ.

3.2 Procesarea datelor

După finalizarea etapei de preprocesare, urmează cea mai complexă parte a aplicației, și anume partea de procesare a datelor. De fapt, pe scurt, procesarea datelor în cazul aplicației Graphical Data Representation Tool se compune din trei etape esențiale, fiecare având un rol important în obținerea unui timp de așteptare cât mai scurt:

Citirea fișierului linie cu linie

Calculul valorilor necesare reprezentării grafice

Stocarea în memorie/ încărcarea din memorie

Fiecare din aceste trei etape ale procesării datelor au fost realizate prin mai mulți pași, pornind de la analiza celei mai eficiente metode și finalizând cu testarea integrării în aplicație.

În cadrul acestui subcapitol se va detalia fiecare etapă în parte, evidențiind importanța ei în procesarea fișierului și modul în care a fost gândită pentru a obține o performanță cât mai ridicată.

3.2.1 Citirea fișierului linie cu linie

Citirea fișierului reprezintă cea mai complexă etapă și totodată, etapa care a generat cele mai multe probleme în dezvoltarea aplicației. După ce s-a stabilit atât în cadrul firmei, cât și cu profesorul îndrumător, faptul că este posibilă realizarea acestei aplicații care va servi ca proiect de diplomă, au fost testate celor mai cunoscute metode de citire a fișierelor prin intermediul Java pe un fișier de tip csv, în urma căruia se dorea o reprezentare grafică (fișierul având aproximativ 500 MB).

În urma testelor, s-a decis utilizarea unei metode de citire prin intermediul unui FileInputStream și a unui Scanner. Această soluție va itera prin toate liniile din fișier, permițând procesarea fiecărei linii, fără a se păstra referințe la ele și în concluzie, fără a le păstra în memorie. Toate celelalte metode de citire necesitau mai mult timp pentru a ajunge la ultima linie, unele dintre ele chiar generând mesajul „Java Out Of Memory”.

Deoarece metoda citirii este destul de complexă, a fost atașată în capitolul anexe (vezi anexa 1), dar următoarea imagine oferă un exemplu simplu și concret al metodei:

Figura 3.3 – Exemplu metodă citire

Fiecare linie, după ce este citită, este împărțită prin separatorul ales în etapa de preprocesare, obținându-se coloanele fișierului. După ce a fost generat numărul de elemente (coloane), are loc o serie de verificări, pentru a evita procesarea datelor irelevante, din motivul performanței. Aceste verificări sunt (în ordinea priorității):

linia trebuie să existe

linia nu trebuie să fie goală

coloana de la iterația curentă trebuie să fie setată ca o coloană cu date utile

(această verificare realizează de fapt o căutare a coloanei în lista generată din preprocesare – dacă a fost setată ca axa OX sau în postul unei coloane șir de caractere sau șir numeric, atunci coloana respectivă va fi procesată. În caz contrar, va fi ignorată)

pentru coloanele setate pe postul de coloană șir de caractere se verifică dacă

String-ul curent există deja în lista de String-uri. Dacă nu există este adăugat.

pentru coloanele setate în postul de coloană șir numeric (coloanele ale căror

valori vor fi afișate în plotul graficului), se verifică dacă într-adevăr valorile coloanei respective sunt valori numerice. Dacă valorile nu sunt numere întregi, se face o verificare în plus. Deoarece există fișiere în care numerele reale au formatul „5,8”, virgula trebuie modificată în punct. Această modificare este necesară deoarece biblioteca JFreeChart nu-l recunoaște ca număr real doar dacă este separat prin punct.

tot în cazul coloanelor setate ca șir numeric se verifică o condiție pentru

adăugarea valorilor în listele rezultante ținând cont de numărul de eșantioane ales (această verificare va fi detaliată în continuare)

Pentru a continua detalierea etapei de citire a fișierului, trebuie prezentat un concept de bază utilizat în GDRT, și anume ideea utilizării unui număr de eșantioane. Numărul de eșantioane este reprezentat de numărul de elemente care este dorit la reprezentare (spre exemplu, dacă se alege un tip de grafic – bar chart, iar numărul de eșantioane va fi setat pe 10, în reprezentarea grafică vom avea 10 elemente de tip bar, dispuse în dreptul a 10 elemente de pe axa OX).

Acest concept al numărului de eșantioane a fost implementat datorită cantității de informație care este foarte mare (dintr-un fișier de un milion de linii, fiecare linie având o valoare, nu se poate crea o reprezentare utilă dacă se încearcă afișarea pe grafic a tuturor celor un milion de valori deoarece nu există suficienți pixeli în imagine). Așadar, fiecare eșantion conține valori pentru anumite intervale din coloana respectivă. Am atașat un exemplu, evidențiind modul în care sistemul funcționează dacă eșantionul este setat pentru calculul mediei aritmetice:

Figura 3.4 – Exemplu calcul număr eșantioane

Funcționalitatea metodei poate fi descrisă prin următorii pași:

Pasul 1: Se calculează numărul total de linii printr-o metodă care va fi

prezentată ulterior în acest subcapitol

Pasul 2: Pentru primele n-1 eșantioane se folosește următoarea verificare:

countLines % currentLine == 0 (restul împărțirii numărului total de linii la linie curentă trebuie să fie egal cu 0). În cazul în care condiția este satisfăcută, se adaugă valorile calculate până în acel moment în lista aferentă eșantionului.

Pasul 3: Pentru ultimul eșantion, un counter calculează numărul liniilor rămase, iar când se ajunge la ultima linie se adaugă valori în lista eșantionului corespunzător ținând cont de numărul primit de la counter.

Fiecare eșantion este alcătuit din 3 elemente: media, maximul si minimul valorilor din intervalul respectiv (de fapt un eșantion este o listă de trei valori). În mod implicit, dacă utilizatorul nu modifică setările, se va afișa valoarea medie în grafic.

Deoarece avem nevoie de numărul total de linii pentru a efectua calculele, trebuie realizată o altă citire preliminară. Cea mai rapidă citire care returnează numărul de linii al fișierului este prezentată în anexa 2. Este o citire byte cu byte, care returnează numărul de linii în cel mai scurt timp (pentru un fișier cu 4 milioane de linii, a returnat valoarea în 20 de milisecunde).

Rezultatul final (lista returnată de metoda citirii) conține toate valorile necesare reprezentării. Este de fapt o listă ce conține valorile fiecărei coloane, iar fiecare coloană conține valorile fiecărui eșantion. Structura finală este puțin dificilă datorită utilizării unor liste de liste, dar este cea mai eficientă metodă, deoarece adăugarea în liste este o operație care necesită foarte puțin timp.

Întreaga structură depinde de numărul de eșantioane dorit de utilizator. Dacă acest număr este schimbat, întregul proces pornește din nou (se realizează o nouă citire în funcție de parametrii curenți).

În concluzie, referindu-ne strict la partea de citire a fișierului, putem afirma următoarele aspecte:

Are loc o citire preliminară pentru a determina numărul total de linii al fișierului

Citirea se face în cel mai rapid mod, linie cu linie, păstrând în memorie doar

valorile necesare reprezentării

Se face un set de verificări pentru fiecare element al fiecărei coloane pentru a se observa dacă respectă condițiile coloanei respective

Valorile se adaugă în liste ținând cont de numărul de eșantioane

Se returnează o listă cu valorile coloanelor numerice, împreună cu o listă conținând valorile coloanei șir de caractere

3.2.2 Calculul valorilor necesare reprezentării grafice

Pentru a obține valorile necesare reprezentării grafice, este nevoie de realizarea anumitor calcule în funcție de elementele fiecărei coloane. Astfel, trebuie calculate următoarele valori:

Valoarea medie pentru fiecare eșantion

Valoarea maximă pentru fiecare eșantion

Valoarea minimă pentru fiecare eșantion

Algoritmul de calcul a fost realizat în felul următor, în două etape : pentru primele

n-1 eșantioane și, separat, pentru ultimul eșantion. Pentru primele n-1 eșantioane se calculează astfel:

În primul rând se verifică dacă elementul coloanei respective este de tip numeric

Se calculează media, maximul si minimul pentru eșantionul curent al fiecărei coloane

Se adaugă valorile în lista eșantionului doar când se ajunge la ultima linie a sa (atunci când este respectată condiția: linia curentă % numărul de linii pe interval = 0)

Apoi, se reinițializează valorile mediei, maximului si minimului pentru următorul eșantion

Pentru ultimul eșantion, valoarea medie este calculată diferit. Această metodă este

implementată diferit, deoarece ultimul eșantion nu conține valori pentru același număr de linii, ca restul eșantioanelor. Ultimul eșantion conține valori calculate din restul de linii rămase (de exemplu dacă avem un fișier cu 10 linii și se dorește o reprezentare cu 8 eșantioane, primele 7 eșantioane vor conține valori pentru o linie, iar ultimul va conține valori pentru ultimele 3 linii).

Diferența poate fi observată doar în calculul mediei. Se inițializează un counter pentru fiecare coloană, care începe să numere după finalizarea ultimului eșantion. Acesta va fi utilizat ca numitor în fracția calcului mediei.

Aceste etape sunt integrate în citirea fișierului și au fost implementate astfel încât să fie calculate doar dacă toate verificările au fost realizate. Astfel, performanța aplicației este îmbunătățită.

Toate aceste valori obținute pentru eșantioane vor fi adăugate în listele destinate reprezentării. Aceste liste au o structură complexă, dar ținând cont de mărimea fișierelor, reprezentările grafice se realizează aproape instant. Parcurgea acestor liste este realizată de acțiunea căsuțelor de verificare (checkbox-uri), care printr-un algoritm prezentat în capitolul următor, extrag doar datele necesare acțiunii corespondente.

Aceleași valori obținute sunt stocate în memoria calculatorului folosit de utilizator, într-un fișier de cache. În acest fișier ele au o structură diferită (despre care se va discuta în subcapitolul următor) prin intermediul căreia se poate sări peste etapa citirii fișierului (dacă este ales același fișier cu același număr de eșantioane, compilarea va avea loc în câteva milisecunde deoarece este mult mai ușor de încărcat o structură cu zeci de valori decât să fie citit fișierul, din nou, linie cu linie).

3.2.3 Stocarea în memorie/ încărcarea din memorie

Stocarea în memorie, respectiv încărcarea din memorie reprezintă două dintre funcționalitățile aplicației care contribuie foarte mult la îmbunătățirea performanței și implicit la un timp de așteptare mult mai mic.

În cazul stocării în memorie a informațiilor, datele necesare sunt păstrate în memoria calculatorului, într-un fișier de cache. Scopul acestei funcționalități poate fi observat, măsurând timpul de procesare al datelor. De exemplu, pentru un fișier de 500 MB, având două milioane de linii, prima procesare a fost realizată complet în aproximativ 30 de secunde.

Pentru a doua procesare (în momentul în care utilizatorul a hotărât să reprezinte același fișier, cu aceleași coloane ca seturi de date și aceeași axă OX), timpul de procesare a fost de ordinul milisecundelor. Acest lucru este datorat faptului că pentru a doua procesare, s-a realizat o verificare, căutând în cache dacă fișierul a mai fost utilizat pentru reprezentări grafice. Deoarece cheia fișierului a fost găsită în cache, s-a sărit peste codul părții de citire, iar toate datele necesare reprezentării s-au încărcat din memoria calculatorului.

De fapt, stocarea în memorie utilizează o structură de tip map. Informațiile sunt stocate sub forma: cheie = valoare. Pentru a evita eventuale probleme în ceea ce privește unicitatea cheii, aceasta s-a realizat având următorii parametrii:

Numele fișierului de reprezentat

Data ultimei modificări (parametru util în cazul fișierelor care se updatează fără a-și modifica numele)

Numărul de eșantioane (datorită faptului că reprezentarea se face în funcție de acest număr, nu se poate omite citirea fișierului atunci când numărul de eșantioane se modifică)

Delimitatorul (în cazul în care utilizatorul modifică manual delimitatorul, reprezentarea va fii diferită)

Lista conținând rolul fiecărei coloane în reprezentare (utilă în cazul în care, spre exemplu, se dorește reprezentarea unui alt set de date sau modificarea axei OX)

Ca exemplu, cheia poate avea structura: „test.txt_09.04.2016_5_;_[OX,Data,null]”.

Cheia curentă este realizată, bineînțeles, după parte de preprocesare și înaintea

părții de procesare (exact în momentul în care se cunosc toți parametrii necesari, deoarece numele și data ultimei modificări ale fișierului, delimitatorul, cât și lista cu rolul coloanelor sunt transmise către procesare din tabelul de preprocesare).

Deoarece toate valorile relevante vor fi stocare pe o singură linie în fișierul de cache, a fost nevoie de declararea unor constante, utilizate ca separatori între toate elementele, pentru ca mai târziu să putem extrage informația necesară în cel mai sigur și simplu mod. Utilitatea acestor constante se regăsește în anexele 2 și 3.

Pentru a putea omite citirea fișierului, trebuie obținute, din altă sursă, toate datele necesare reprezentării grafice. Aceste date sunt, în cazul aplicației GDRT, cele trei liste de valori:

Lista seturilor de date care vor reprezenta plot-ul graficelor

Lista conținând valorile axei OX

Lista conținând toate șirurile de caractere

Pentru fiecare din aceste liste, avem 2 metode:

una pentru transformarea listei într-un șir de caractere, care va fi adăugat în fișierul cache, la cheia corespunzătoare

cea de-a doua pentru transformarea opusă (din șirul de caractere din fișierul cache, în lista de date utilizată în grafic)

Codul sursă al celor două metode poate fi analizat în anexa 2 (prima metodă), respectiv în anexa 3 (cea de-a doua metodă). Cea de-a doua metodă reprezintă, de fapt, încărcarea din memoria locală.

În concluzie, datele pot fi obținute din două surse, ținând cont de un singur criteriu: dacă fișierul a fost reprezentat cel puțin odată sau nu. Pentru prima procesare, datele sunt obținute direct din fișier, realizându-se o citire integrală a acestuia. La sfârșitul acestei funcții, valorile obținute sunt stocate local. Pentru o a doua procesare, datele sunt obținute din fișierul cache, realizându-se o citire a unei linii dintr-un fișier text, care reprezintă valoarea cheii respective.

3.3 Componentele Java

Componentele Java asigură mecanica aplicației. Toate aceste componente sunt realizate dinamic, ele fiind create în funcție de rezultatul citirii fișierului. Există o multitudine de componente, ușor de utilizat, care reprezintă 90% din interfața aplicației.

Există elemente Java atât în partea de preprocesare, cât și în partea de procesare (se va discuta despre acestea în următoarele două subcapitole). Ele constituie baza acestei aplicații, prin intermediul lor determinându-se tot ceea ce este necesar într-un grafic și nu numai. Aproape fiecare element are o acțiune proprie, prin intermediul căreia apar modificări în interfața aplicației. Cele mai utilizate sunt căsuțele de bifare (JCheckBox) cu ajutorul cărora se aleg seturile de date necesare graficelor.

3.3.1 Legătura dintre preprocesare și componentele Java

Deși aplicația se bazează pe un tablou de tip desktop (JDesktopPane), partea de preprocesare este realizată într-o fereastră nouă (JFrame). Cu toate că frame-ul de preprocesare este separat de restul aplicației, cele două se află în strânsă legătură (Butonul de „Done” din frame-ul de preprocesare declanșează citirea fișierului).

Preprocesarea conține următoarele componente Java:

Eticheta „Set the delimiter manually” alături de câmpul de text aferent cu ajutorul cărora se poate modifca separatorul determinat automat de algoritmul aplicației

Căsuțe de text (care au ca valori implicite „Coloana + indexul coloanei”) pentru modificarea numelor coloanelor fișierului

Tabelul de preprocesare în strânsă legătură cu căsuțele de text destinate modificării numelor coloanelor (numele selectate de utilizator sunt transferate în capul de tabel)

Meniuri implementate apăsând click dreapta pe coloanele tabelului destinat selectării rolului coloanelor respective în reprezentare

Butonul de finalizare a preprocesării

Pentru fiecare dintre aceste elemente Java (cu excepția etichetelor care nu pot fi modificate) există metode care returnează selecțiile făcute de utilizator. Toate aceste metode transmit valorile către partea de procesare a aplicației. Numele coloanelor sunt transmise în căsuțe de text aflate în interfața aplicației, dar și în graficele realizate. În grafice, sunt trecute în secțiunea de legendă, pentru a recunoaște de unde provin datele reprezentate și ce culoare le corespunde. Delimitatorul este transmis către metoda de citire, care împarte fiecare linie după acest separator provenit din preprocesare. Tabelul de preprocesare transmite către metoda de citire a fișierului o listă de valori numerice ce determină scopul fiecărei coloane în citirea fișierului și totodată în reprezentarea grafică (0 – coloană irelevantă, 1 – axa OX, 2 – șir de caractere, 3 – set de date). Butonul de finalizare preprocesare realizează verificările necesare, iar dacă toate informațiile necesare sunt în regulă, iar condițiile impuse sunt respectate, declanșează metoda de citire a fișierului, apelând toate celelalte metode care returnează selecțiile utilizatorului.

3.3.2 Legătura dintre procesare și componentele Java

Asemenea părții de preprocesare, interfața procesării datelor conține o multitudine de componente Java, fiecare generând anumite modificări prin acțiunile aferente. Cu excepția etichetelor, toate celelalte elemente sunt generate în mod dinamic, după citirea fișierului. În momentul în care toate datele necesare graficelor sunt obținute și structurate în liste, se creează toate elementele și acțiunile corespunzătoare.

Elementele generate de procesare datelor sunt următoarele:

Buton de alegere al unui nou fișier – dacă un nou fișier este ales, se va curăța toată interfața, se va elimina orice informație din fișierul precedent, iar tot algoritmul va fi restartat, începând cu etapa de preprocesare. Deși de pe interfața grafică va dispărea orice urmă a fostului fișier reprezentat, toate informațiile necesare vor putea fi găsite în fișierul de cache, iar într-o reprezentare viitoare, vor fi încărcate toate aceste informații.

Etichete pentru fiecare element Java, indicând funcționalitatea acestuia (de exemplu, pentru alegerea tipului de grafic, înaintea listei există o etichetă cu textul „Type of chart: ”). Etichetele sunt componentele cel mai des folosite și ajută utilizatorul să-și desfășoare munca mai ușor.

Căsuțe de tip text, dezactivate, care conțin numele coloanelor alese din etapa de preprocesare. Aceste căsuțe sunt create în funcție de numărul de coloane al fișierului și nu sunt editabile. Au un scop informativ. Dacă se dorește modificarea numelor, este necesară întoarcerea în etapa de preprocesare. Căsuță de text există și pentru setarea numărului de eșantioane, dar aceasta este editabilă și are ca efect reluarea etapei de procesare.

Căsuțe de bifat (checkbox-uri) care sunt de 2 tipuri: unul pentru setul de date și unul pentru lista de stringuri. De asemenea, ambele sunt realizate dinamic. Căsuțele pentru setul de date sunt realizate în dependență cu numărul de coloane al fișierului. Căsuțele pentru lista de string-uri sunt realizate ținând cont de coloana selectată în postul de coloană șir de caractere din etapa de preprocesare. Astfel, va exista câte o căsuță pentru fiecare string diferit determinat în coloana respectivă. Cele două tipuri de checkbox-uri au acțiuni diferite. Selectarea căsuțelor pentru date va avea ca urmare adăugarea în plot-ul graficului a informațiilor coloanei respective. Deselectarea va avea ca efect eliminarea acestor informații din plot. În legenda graficului va exista numele căsuței. Pentru căsuțele șirurilor de caractere, acțiunea diferă în sensul că selectarea unei astfel de căsuțe are ca efect adăugarea datelor în grafic, doar pentru eșantioanele care conțin stringul respectiv. Deselectarea, de asemenea va elimina datele adăugate pentru acel string.

Căsuța de text pentru previzualizarea fișierului, care oferă informații despre primele 20 linii, neprocesate, așa cum există ele în fișierul sursă. Este utilă dacă utilizatorul dorește o privire de ansamblu a tipului de date din fișier, fără a fi nevoie să se întoarcă în etapa de preprocesare

Butonul „Back to preprocessing”, utilizat pentru întoarcerea la etapa de preprocesare. Apăsarea acestui buton nu influențează în niciun fel etapa de procesare. De fapt, în urma încheierii etapei de preprocesare, frame-ul respectiv nu este închis. Este doar setat ca fiind invizibil. Apăsarea butonului de întoarcere la preprocesare setează frame-ul ca fiind vizibil, iar apoi se poate continua cu modificările dorite de utilizator. Nu butonul de „Back to preprocessing” influențează procesarea fișierelor, ci butonul de „Done preprocessing”.

Butonul „Clear cache”, care odată apăsat, va șterge nu doar conținutul întregului fișier de cache, ci și fișierul de pe hard-disk. Desigur, a fost implementată și o metodă de asigurare pentru a nu șterge cache-ul din greșeală, dar aceasta va fi detaliată într-un capitol următor.

Caseta pentru alegerea tipului de valori dorit la reprezentare. Conține trei opțiuni: media, maximul sau minimul din eșantion. Odată apăsată orice opțiune din această casetă, se reîmprospătează graficul cu noile valori. În mod implicit este selectată opțiunea conținând mediile eșantioanelor de reprezentat.

Căsuța de text pentru modificare numărului de eșantioane. Acest element are un impact important asupra aplicației, deoarece odată modificat acest număr, declanșează o nouă citire a fișierului. Se reîmprospătează toată interfața, se șterge plot-ul graficului, se șterg căsuțele de bifare și cele radio și se creează toate din nou, în funcție de rezultatul procesării.

Caseta pentru alegerea tipului de grafic multi-chart, utilizată atunci când se dorește reprezentarea în mai multe grafice, câte unul pentru fiecare string diferit (necesară pentru compararea statusurilor dintre două sau mai multe servere, de exemplu)

Caseta pentru alegerea tipului de grafic chart simplu, clasic, utilizată pentru realizarea unei singure reprezentări, cu unul sau mai multe seturi de date, dar cu un singur plot, conținând toate valorile

O privire de ansamblu asupra aplicației, după finalizarea etapei de procesare, este

atașată în cadrul anexei 8.

3.4 Realizarea graficelor

În acest subcapitol va fi abordat principalul scop al aplicației. Așa cum sugerează și numele, Graphical Data Representation Tool, aplicația are ca scop reprezentarea datelor prin intermediul graficelor. În cadrul aplicației, graficele sunt create în ferestre interne ale aplicației. Sunt realizate manual pentru tipul de grafic simplu, cu un singur plot, iar pentru graficul de tip multi-chart este realizat dinamic, în funcție de string-urile existente.

Indiferent de tipul de grafic, toate au anumite elemente comune:

Grid-ul (grila), reprezentând o multitudine de linii punctate ajutătoare, orizontale și verticale din dreptul fiecărei valori de pe axele OX si OY. Grid-ul poate fi inclus sau exclus în grafic din proprietățile graficului

Axele OX și OY, dintre care OY-ul este calculat automat ca un interval având la capete cea mai mică și cea mai mare valoare din setul de date, iar axa OX este determinată de coloana aleasă pe acest post în etapa de preprocesare a aplicației

Plot-ul care este constituit din elementele tipului de grafic ales, având ca valori setul de date

Legenda, care diferă în funcție de tipul de grafic ales. Dacă graficul este clasic, simplu, cu un singur plot, atunci legenda va indica culoarea și numele coloanei reprezentate. Dacă graficul este de tip multi-chart, conținând două sau mai multe ploturi, atunci legenda va indica culoarea și numele string-ului determinat

3.4.1 Tipuri de grafice

Pentru a oferi diversitate utilizatorului, s-au creat multe tipuri de grafice, fiecare fiind util în funcție de necesități. Pentru a oferi o imagine de ansamblu asupra tuturor tipurilor de grafic existente în GDRT, se va alege următorul fișier (ce conține date irelevante datorită politicii de confidențialitate a companiei) de tip text, ce conține informații despre statusul serverelor din anumite filiale ale firmei. Datele alese se vor reprezenta, prin intermediul fiecărui tip de grafic, atât simple-chart cât și multi-chart.

Pe axa OX se vor afla datele calendaristice în care s-au petrecut acțiunile, iar setul

de date va fi reprezentat de coloana ce conține valorile statusurilor serverelor la momentul respectiv.

Fișierul de intrare este următorul:

Figura 3.5 – Exemplu fișier status servere

În etapa de preprocesare, coloanele au fost selectate astfel (albastru – axa OX, verde deschis – String, verde închis – seturi de date):

Figura 3.6 – Preprocesarea pentru fișierul din figura 3.5

Toate tipurile de grafice pentru fișierul de intrare precedent, procesat cu setările alese de utilizator sunt prezentate în anexele 6 (pentru graficele de tip one-chart) și 7 (pentru graficele de tip multi-chart).

3.4.2 Aspecte specifice graficelor

Majoritatea funcționalităților graficelor au venit odată cu bibliotecă JFreeChart. Această bibliotecă este gratuită și este cea mai utilizată pentru crearea de grafice deoarece are o multitudine de funcționalități implementate.

JFreeChart are următoarele caracteristici:

Este 100% gratuită, utilizarea sa fiind permisă fără niciun cost

Conține o documentație puternică, care ajută utilizatorul să lucreze mai ușor cu ea

Suportă o gamă largă de tipuri de grafice (de exemplu: pie chart, area chart, bar chart, line chart)

Este ușor de extins și poate fi folosită atât în aplicațiile client, cât și în aplicațiile server-side

Suportă multe tipuri de formate de salvare a graficelor: PDF, JPEG, PNG, SVG etc

Permite o customizare liberă a graficelor

Pe lângă toate aceste funcționalități, cea mai utilă și cea mai des folosită este cea de zoom. Pentru tipul de fișiere care se doresc a fi reprezentate, funcția de zoom este indispensabilă. În momentul în care graficul are peste două sute de elemente este foarte dificil să ții cursorul mouse-ului pe elementul al cărui valoare prezintă interes. De aceea funcțiile de zoom-in, zoom-out sunt utile, ele ajutând utilizatorul să obțină informația dorită.

Totodată, biblioteca JFreeChart oferă un meniu de proprietăți ale graficelor. În acest meniu se poate modifica aproape tot ce ține grafic, cu excepția valorilor din plot. Se pot modifica fontul, mărimea caracterelor, culorile graficului, numele graficului și multe altele. Dezavantajul acestei metode este acela că aceste modificări au loc doar pentru graficul respectiv. Dacă se dorește a se păstra acest template, cu modificările făcute de utilizator, totul trebuie generat din cod.

Biblioteca JFreeChart se bazează pe seturi de date. Acestea constituie plot-ul graficului. Pentru a nu încărca memoria cu date complexe, a fost ales un set de date simplu numit „DefaultCategoryDataset”. Acest tip de set de date utilizează două metode și anume: addValue și removeValue. Aceste metode au necesitat mult timp pentru a funcționa 100% corect deoarece fiecare căsuță de bifare are ca acțiune adăugarea sau eliminarea de valori din setul de date. Pentru tipul de grafic one-chart, căsuțele de bifat ale coloanelor de tip numerice guvernează. Fiecare căsuță corespunde unei coloane din fișierul de intrare. Selectarea sau deselectarea căsuțelor are ca efect adăugarea sau eliminarea din setul de date și implicit, reîmprospătarea graficului. Deoarece structura este complexă și aplicația trebuie să suporte orice tip de combinație generată de utilizator, înainte de adăugarea în setul de date există o serie de verificări. O parte din aceste verificări au fost implementate la crearea funcției, iar altele au fost descoperite prin testarea aplicației pe fișiere cu diferite formate.

Metoda „addValue” are trei parametrii:

Valoarea care se dorește a fi adăugată în locația respectivă

Valoarea de pe axa OX

Numele elementului (coloanei în cazul nostru) de care aparține

Metoda „removeValue” conține doar ultimii doi parametrii (valoarea de pe axa OX

și numele elementului).

Pentru aplicația GDRT, la acțiunea căsuțelor de bifat aferente fiecărei coloane,

metoda „addValue” are următoarea formă:

dataset.addValue(dataList.get(indexColoana).get(esantionCurent).get(tipValoare), numeColoana[index], valoareOX[index]);

Pentru a elimina informații din setul de date, se deselectează căsuța respectivă, metoda „removeValue: având următoarea formă:

dataset.removeValue(numeColoana[index], valoareOX[index]);

Setul de date „DefaultCategoryDataset” cuprinde multe metode, însă s-a ales utilizatea doar acestora (addValue și removeValue). S-a făcut această alegere deoarece cele două metode au ca parametrii exact informațiile necesare pentru scopul aplicației. „addValue” și „removeValue” sunt utilizate atât pentru căsuțele de bifare ale string-urilor diferite, cât și pentru cele ale seturilor de date.

Pentru a înțelege mai bine structura, s-a realizat următorul graf, care explică arborescența creată pentru lista mamă:

Figura 3.7 – Structura listei de date

Lista de date are ca elemente toate coloanele determinate de separatorul generat automat sau setat manual.

Fiecare coloană conține eșantioanele aferente.

Fiecare eșantion este alcătuit din trei elemente: media (AVG), maximul (MAX) și minimul (MIN).

Nu mai este nevoie de modificarea listei, aceasta fiind populată în partea de procesare, mai exact în metoda citirii fișierului. După finalizarea acelei etape, nu se adaugă și nu se elimină niciun element din listă. Singura funcție care se apelează este funcția „get” pentru a obține anumite valori ce prezintă interes în reprezentarea grafică. Același lucru este valabil și pentru lista cu valorile axei OX și pentru lista ce conține șirurile de caractere.

Toate graficele apelează metoda ce returnează setul de date, dar valorile se adaugă doar prin acțiunea căsuțelor de bifat. Eliminarea anumitor valori are loc și în metodele reprezentărilor grafice, doar în cazul graficelor multi-chart. Aici se creează dataset-uri într-un ciclu care merge până la dimensiunea listei de șiruri de caractere. Motivul este acela că este nevoie de câte un set de date pentru fiecare șir de caractere și prin urmare se vor elimina valorile care nu corespund acestui șir.

Majoritatea acțiunilor din interfața aplicației au efect asupra graficelor, excepție făcând doar funcționalitatea de previzualizare a primelor n linii. Prin setarea numărului de eșantioane se „curăță” graficul complet și se realizează unul nou, având numărul de eșantioane setat de utilizator. Prin modificarea tipului de eșantion (medie, maxim sau minim) se elimină elementele din graf și se încarcă din listă eșantioanele având tipul dorit. Modificarea tipului de grafic (one-chart sau multi-chart) duce la eliminarea întregii ferestre a graficului anterior și crearea unei noi ferestre pentru noul grafic. De fapt fereastra nu este eliminată, doar lasă impresia că ar fi. În realitate, în urma etapei de procesare a datelor, se creează toate ferestrele pentru toate tipurile de grafic, atât pentru cele one-chart, cât și pentru cele multi-chart. Când un tip de grafic este selectat, fereastra sa devine vizibilă, iar toate celelalte ferestre devin invizibile.

În concluzie, combinația dintre toate funcționalitățile oferite de biblioteca JFreeChart și metodele create pentru adăugarea, respectiv eliminarea informațiilor din setul de date a condus la rezultatele aplicației. Aceste metode au fost modificate foarte des, în funcție de cerințele primite și de stabilitatea lor anterioară. S-a încercat o implementare cât mai simplă, din două motive: primul, al performanței (cât mai puține instrucțiuni conduc către o compilare mai rapidă a codului), iar al doilea, reprezentat de probabilitatea mai mică de a apărea erori pentru anumite fișiere. S-a ajuns, prin documentare și testare, la o soluție intermediară, care rezolvă conflictul dintre complexitatea structurii datelor și necesitatea unei performanțe foarte bune.

3.5 Funcții suplimentare

În cadrul aplicației Graphical Data Representation Tool a fost introdusă o serie de funcții suplimentare, care au scopul de a ajuta utilizatorul în setarea preferințelor pentru graficul dorit. Unele funcții sunt necesare, altele au rolul de a salva timp utilizatorului în cazul în care acesta dorește anumite informații suplimentare.

Aceste funcții au fost realizate sub forma a mai multor elemente Java:

Etichete de tip text, utilizate doar ca informație

Butoane

Câmpuri de text

Casete cu meniu de alegere a opțiunii.

Aproape toate funcțiile suplimentare, au efect asupra reprezentării grafice. Fiecare

opțiune aleasă de utilizator realizează o reîmprospătare a graficului curent. Această reîmprospătare constă în eliminarea setului de date din fereastra vizibilă a graficului.

Funcțiile suplimentare ale aplicației despre care se va discuta în subcapitolele următoare sunt:

Funcția de preview

Funcția de afișare a numărului total de linii

Funcția de setare al numărului de eșantioane

Funcția de afișare într-un grafic sau în grafice separate

Funcția de alegere a tipului valorilor

3.5.1 Funcția de preview

Această funcție de previzualizarea este alcătuită dintr-o etichetă și un câmp de tip

text. Eticheta este doar informativă („Select number of lines to preview”) și este situată în stânga câmpului.

Prin intermediul acestei funcții se pot previzualiza primele n linii dorite de utilizator. Previzualizarea liniilor din fișierul sursă nu conține nicio procesare. Liniile sunt afișate exact în formatul în care sunt afișate atunci când fișierul este deschis în mod normal (fără separare prin delimitator).

Utilitatea acestei funcții se manifestă prin faptul că utilizatorul poate observa primele linii din fișier fără a fi nevoie să iasă din aplicație și să-l deschidă în mod normal. Totodată poate fi utilă dacă reprezentarea grafică obținută în urma etapelor de preprocesare și procesare nu este tocmai cea dorită de utilizator. El poate observa dacă în primele n linii alese de el fișierul are un format diferit sau dacă există anumite date eronate care trebuie corectate.

În același timp, această funcție realizează anumite verificări:

Numărul de linii alese trebuie să fie mai mic decât numărul maxim de linii determinat cu un alt algoritm

Textul introdus de utilizator trebuie să fie de tip întreg, nu se acceptă valori de tip float ori double

Numărul introdus trebuie să fie mai mare ca 0

Numărul maxim de linii utilizate pentru previzualizare este de 20. Dacă utilizatorul selectează un număr mai mare de 20, este afișat un mesaj de avertizare, informând utilizatorul despre numărul maxim care poate fi introdus

Fereastra de previzualizare nu este editabilă. Poate fii închisă sau maximizată. În

interiorul său, liniile sunt dispuse pe verticală, pornind de la prima linie și având forma: „Line nr. x : valoare”.

Pentru un fișier de test, ce conține 12 linii, previzualizarea prin această funcție este reprezentată de imaginea următoare:

Figura 3.8 – Fereastra de previzualizare

După cum se poate observa din figura 3.8, deasupra etichetei funcției de preview se află o altă etichetă „The file has 12 lines”. Această funcționalitate constituie funcția de afișare a numărului total de linii și este realizată prin intermediul unui algoritm nu foarte complex.

Funcția de afișare a numărului total de linii este reprezentată doar de o etichetă needitabilă, aflată în panoul principal. Această funcționalitate este necesară în anumite cazuri, pentru informarea utilizatorului sau pentru alte utilizări:

Datele se pot utiliza în statistici. De exemplu dacă într-o versiune anterioară, fișierul avea mai puține linii, se poate face o diferență pentru a observa câte date au fost adăugate în versiunea curentă

Este o informație utilă dacă este folosită împreună cu funcția de setare a numărului de eșantioane. În mod implicit se afișează doar 5 sau 10 eșantioane. Dacă fișierul de intrare nu are dimensiuni foarte mari (de ordinul sutelor de linii), poate fi realizată o reprezentare a fiecărei linii în parte (ceea ce este ideal pentru utilizator), fiecare eșantion reprezentând o linie. Astfel, se va seta numărul de eșantioane egal cu numărul total de linii

Se poate utiliza ca informație pentru funcția de previzualizare a primelor n linii din fișier. Luând exemplul anterior, în care fișierul de intrare conține doar 12 linii, este absurd ca utilizatorul să ceară afișarea primelor 20 linii

3.5.2 Funcția de setare al numărului de eșantioane

Această funcționalitate este extrem de importantă în realizarea graficelor din GDRT. Odată schimbat numărul implicit de eșantioane, se va realiza o nouă citire a fișierului (în cazul în care acesta nu există în fișierul de cache).

Așa cum a fost prezentat și în capitolele anterioare, setarea numărului de eșantioane are ca efect modificarea graficului, adăugând sau eliminând elemente din el. Dacă este ales un număr mai mare de eșantioane atunci intervalele din etapa de citire a fișierului vor conține mai puține valori și în concluzie tot setul de date va fi modificat. Același lucru este valabil și pentru un număr mai mic de eșantioane, singura diferență fiind aceea că numărul de linii pentru fiecare interval va fi mai mare.

Funcția este reprezentată, ca și funcția suplimentară de previzualizare a primelor linii, de un câmp de tip text și de o etichetă(„Number of samples: ”) cu caracter informativ ce se află în dreptul câmpului. Numărul de eșantioane declanșează automat citirea fișierului atunci când noua valoare este aleasă si este apăsată tasta „Enter”. Chiar dacă citirea se face din fișierul de cache sau direct din fișierul sursă, rezultatul este același. Singurul aspect care diferă este timpul de execuție, care este mult mai scurt dacă citirea se face din fișierul de cache.

Atunci când funcționalitatea se declanșează, în primul rând se reîmprospătează toată interfața. Se reinițializează listele ce conțin valorile pentru reprezentările grafice și se setează pe valoarea implicită toate variabilele care se modifică în citirea fișierului. Setul de date, de asemenea, va fi curățat. Este nevoie de toate aceste reinițializări din simplul motiv că nu se dorește adăugarea în continuare a valorilor, ci se dorește o nouă reprezentare grafică. Dacă aceste operații ar fi ignorate, reprezentarea nu ar avea niciun sens, în graficul corespunzător fiind afișate atât valori ale setului de date anterior, cât și ale celui curent.

Atât în cazul în care datele sunt obținute din cache, cât și în cazul în care acestea sunt obținute prin citirea fișierului, este nevoie de reîmprospătarea componentelor Java cât și a listelor și variabilelor utilizate.

3.5.3 Funcția de afișare într-un grafic sau în grafice separate

Aceste două funcții sunt reprezentate de două etichete și două liste de alegere a opțiunii. Etichetele oferă informații despre casetele/ listele aferente („One-chart representation” și „Multi-chart representation”) și sunt needitabile. În mod implicit, cele două liste nu au selectată nicio valoare. Opțiunile disponibile, atât pentru lista de tip one-chart, cât și pentru cea multi-chart sunt următoarele:

Valoarea nulă (implicită)

Bar chart(standard bar chart, 3D bar chart și stacked bar chart)

Line chart(standard line chart, 3D line chart)

Area chart

Selectarea oricărei dintre aceste opțiuni, are ca urmare setarea tuturor ferestrelor ce

conțin grafice ca invizibile. S-a ales această metodă cu setarea ferestrelor ca fiind invizibile tocmai din motivul performanței. Este mult mai rapidă procesarea atunci când toate ferestrele sunt create în urma etapei de procesare, acestea fiind setate invizibile. Atunci când o opțiune din cele două liste este selectată, nu este nevoie de crearea unei noi ferestre, ci doar de setarea vizibilității frame-ului respectiv.

În ceea ce privește modul de funcționare al celor două opțiuni, pentru tipul de grafic simplu există un singur plot în care este adăugat sau eliminat setul de date. Sunt create elemente (bar-uri, linii sau zone) în funcție de numărul de eșantioane, axa OX și valoarile aferente din setul de date. Toate elementele, indiferent de string-ul liniei respective, sunt afișate în același grafic. Nu același lucru se poate spune și despre graficul de tip multi-chart. În acest caz, axa OX este aceeași, dar numărul de plot-uri diferă în funcție de numărul de string-uri diferite rezultate din etapa de procesare a datelor. Așadar vom avea un plot pentru fiecare string, toate având aceeași legendă, aceeași axă OX și valori diferite.

3.5.4 Funcția de alegere a tipului valorilor

Alegerea tipului valorilor este ultima funcție suplimentară prezentată în cadrul acestui subcapitol. Funcția este inclusă în acțiunea unei casete ce conține trei opțiuni, acestea fiind:

Valorile medii

Valorile maxime

Valorile minime

În mod implicit, valorile medii sunt afișate pe grafic. În metoda citirii, fiecare eșantion conține cele trei valori. Acestea sunt calculate în funcție de numărul de date conținute pe intervalul generat. Pentru fiecare interval, în etapa de procesare, se calculează maximul, minimul și media dintre valorile cuprinse.

Când oricare dintre aceste opțiuni este aleasă, se realizează o reîmprospătare a aplicației și totodată o curățare a setului de date. Operația se realizează foarte rapid, insesizabil. Pe grafic vor fi înlocuite vechile valori cu cele noi

Capitolul 4. Testarea sistemului

Testarea sistemului a reprezentat o etapă ce s-a realizat încă din faza inițială a proiectului. În urma implementării fiecărei metode, s-a realizat o testare asupra întregului sistem. Testarea a fost utilă în primul rând pentru a observa timpul de procesare.

Pentru a testa timpul s-a implementat o metodă, care utilizează un counter pentru a calcula timpii de execuție pentru fiecare funcție care prezintă interes. Această metodă a fost utilă în etapa de procesare a fișierului, pornindu-se counterul la citirea primei linii și oprindu-se când toate listele au fost completate. Principiul este simplu. La pornire s-a inițializat o variabilă astfel „long startTime = System.currentTimeMillis();”, iar la finalizarea procesului, altă variabilă stopTime cu aceeași valoare. S-a făcut diferența dintre cele două valori obținute, iar rezultatul a fost afișat în consolă.

Prin intermediul acestei metode s-a ales tipul de citire utilizat pentru aplicația GDRT. S-au testat diverse metode, pe diverse tipuri de fișiere, iar rezultatele au fost comparate și în final s-a ales metoda cea mai eficientă. S-a constatat că metoda citirii fișierului ocupă mai mult de 90% din timpul total de execuție. Crearea componentelor și a legăturilor dintre ele se realizează într-un timp insesizabil, de câteva milisecunde, neținând cont de mărimea fișierului.

Tot în cadrul etapei de testare, se pot include și toate testele realizate pe fișiere pentru a observa dacă aplicația funcționează corect. În această privință s-a dezvoltat un set de verificări:

S-a urmărit prin intermediul debug-ului dacă aplicația generează rezultatele dorite

S-au testat fișierele pentru care este nevoie de aplicație

S-au testat alte fișiere de test, cu date asemănătoare celor precedente, dar de dimensiuni diferite

S-au testat fișiere cu date neconcludente sau cu formate ciudate pentru a observa modul în care aplicația răspunde

S-a verificat dacă numărul de eșantioane obținut este cel corect

S-a verificat dacă listele de valori (lista de date, lista cu datele pentru axa OX și lista cu valorile string-urilor) conțin valorile dorite pentru orice tip de fișier

În urma implementării metodei de stocare a datelor în memorie, s-au realizat comparații pentru orice tip de fișier în ceea ce privește formatul pe care listele îl au în cadrul aplicației și formatul lor generat în fișierul de cache

S-a verificat răspunsul aplicației în cadrul etapei de preprocesare a datelor și s-au stabilit anumite restricții

S-a verificat răspunsul fiecărei funcții suplimentare pentru anumite fișiere de intrare

S-au verificat scenarii întregi de procesare a mai multor fișiere, unul după celălalt, pentru a se putea elimina orice urmă a fișierelor precedente

S-a verificat de fiecare dată influența adăugării unei noi metode în cadrul aplicației și compatibilitatea acesteia cu restul programului

S-a urmărit dispunerea tuturor componentelor astfel încât acestea să nu se suprapună

Toate aceste verificări și multe altele au fost realizate în fiecare etapă a dezvoltării aplicației. A fost testată orice variantă și orice scenariu și s-a încercat restricționarea aplicației prin anumite mesaje de avertizare. De exemplu, în etapa de preprocesare, dacă utilizatorii nu selectează o coloană ca axa OX și cel puțin una ca fiind coloană numerică, vor primi mesaje de avertizare la apăsarea butonului de finalizare preprocesare.

Blocurile de try-cache pot fi văzute tot ca o verificare. De exemplu, pentru etapa de procesare, la citirea fișierului se încearcă găsirea cât mai multor probleme și tratarea lor prin mesaje de avertizare. În prezent, acestea sunt:

File Not Found, în cazul în care este dată calea fișierului, iar acesta nu există la locația respectivă

Array Index Out Of Bounds, în cazul în care liniile fișierului nu au același număr de coloane

Arithmetic Exception, în cazul în care numărul de linii pe interval este mai mic ca 1, și se încearcă împărțirea la zero

Pattern Syntax, în cazul în care delimitatorul este greșit

S-au găsit multe bug-uri ale aplicației prin intermediul testării, care mai târziu au fost tratate. Cea mai testată a fost metoda citirii deoarece datorită complexității sale, putea oricând genera probleme. Tocmai din acest motiv, s-a preferat implementarea multor verificări în citirea fișierului în pofida faptului că performanța sistemului scădea. Este de preferat o aplicație puțin mai lentă, dar complet funcționabilă, decât una mai rapidă, dar care poate genera probleme oricând.

Așadar, etapa de testare a fost extrem de utilă la orice pas. Prin intermediul ei s-au stabilit cele mai eficiente metode de implementat și s-a găsit o serie de probleme, care au fost rezolvate ulterior.

Capitolul 5. Rezultate și concluzii

Pentru prezentul proiect, a existat o serie de etape care au condus la aplicația prezentă:

Alegerea mediului de dezvoltare. Am ales Java deoarece aveam anumite cunoștințe de bază în acest limbaj de programare și puteam beneficia de sfaturile colegilor care lucrează în departamentul de dezvoltare

Alegerea tehnologiilor utilizate pentru crearea graficelor, precum și testarea potențialului tehnologiilor gratuite de pe piață

Obținerea cerințelor aplicației și a unei vederi de ansamblu asupra modului în care aplicația trebuie să funcționeze

Implementarea aplicației și testarea continuă

Finalizarea proiectului și realizarea documentației

Aplicația Graphical Data Representation Tool constituie unul dintre cele mai importante proiecte la care am lucrat până în prezent. Am avut această oportunitate prin intermediul companiei Schaeffler România și a colegilor din Germania, care aveau nevoie de o aplicație internă funcționabilă și cât mai dinamică posibil.

În cadrul acestui proiect mi-am dezvoltat cunoștințele de programare, precum și gândirea algoritmică. Mi-au fost de ajutor cunoștințele de bază, în domeniul programării, obținute în cei patru ani de universitate dar mai mult, consider eu, gândirea logică pe care mi-am dezvoltat-o în toți acești ani.

Proiectul este finalizat parțial, deoarece oricând poate fi redeschis, la cererea implementării unor noi funcționalități. Pe viitor se va dori și realizarea unor reprezentări grafice utilizând informații dintr-o bază de date.

Capitolul 6. Bibliografie

Java: A Beginner's Guide, Sixth Edition, Mai 6, 2014 de Herbert Schildt

Head First Java, 2nd Edition, Feb 9, 2005 de Kathy Sierra și Bert Bates

https://www.oracle.com/java/

http://www.jfree.org/jfreechart/

http://www.javaprogrammingforums.com/

http://www.tutorialspoint.com/java/

Captiolul 7. Declarație de originalitate

DECLARAȚIE PRIVIND ORIGINALITATEA LUCRĂRII DE ABSOLVIRE/ LUCRĂRII DE LICENȚĂ/ PROIECTULUI DE DIPLOMĂ/ DISERTAȚIE

UNIVERSITATEA TRANSILVANIA DIN BRAȘOV

FACULTATEA INGINERIE ELECTRICĂ ȘI ȘTIINȚA CALCULATOARELOR

PROGRAMUL DE STUDII AUTOMATICĂ ȘI INFORMATICĂ APLICATĂ

NUMELE ȘI PRENUMELE DRĂGAN CĂLIN IONUȚ

CADRUL DIDACTIC ÎNDRUMĂTOR FLOROIAN LAURA

Declarăm pe propria răspundere că lucrarea de față este rezultatul muncii absolventului, pe baza cercetărilor proprii și pe baza informațiilor obținute din surse care au fost citate și indicate conform normelor etice, în textul proiectului, în note și în bibliografie.

Declarăm că nu s-a folosit în mod tacit sau ilegal munca altora și că nici o parte din proiect nu încalcă drepturile de proprietate intelectuală ale altcuiva, persoană fizică sau juridică.

Declarăm că proiectul nu a mai fost prezentat sub această formă vreunei instituții de învățământ superior în vederea obținerii unui grad sau titlu științific ori didactic.

În cazul constatării ulterioare a unor declarații false, vom suporta rigorile legii.

Data: Absolvent

Cadru didactic îndumător

Capitolul 8. Anexe

Anexa 1 – Cod citire fisier

if (currentSample[j] < nrSamples – 1) {

if (currentLine != 0 && currentLine % linesPerInterval == 0) {

List<Float> essentialList = new ArrayList<Float>();

oneSampleList.add(essentialList);

if (selectedCols.get(j) == PreProcessing.charsValue &&tringsList.size() < nrSamples – 1)

stringsList.add(splitLine[j]);

else if (selectedCols.get(j) == PreProcessing.datasetValue) {

averageVal[j] = totalVal[j]/ linesPerInterval;

oneSampleList.get(j).add(averageVal[j]);

oneSampleList.get(j).add(maximVal[j]);

oneSampleList.get(j).add(minimVal[j]);

maximVal[j] = Float.MIN_VALUE;

minimVal[j] = Float.MAX_VALUE;

totalVal[j] = 0;

currentSample[j]++;

}

else if (selectedCols.get(j) == PreProcessing.xAxisValue && oxList.size() < nrSamples – 1) {

if (!oxList.contains(splitLine[j])) {

oxList.add(splitLine[j]);

}

else {

counterOxList[j]++;

oxList.add(splitLine[j] + "("+ counterOxList[j]+ ")");

}

}

}

}else {

lastSampleCounter[j]++;

if (currentLine == totalCount) {

for(int k=0;k<splitLine.length;k++) {

List<Float> essentialList = new ArrayList<Float>();

oneSampleList.add(essentialList);

if (selectedCols.get(k) == PreProcessing.charsValue && stringsList.size() < nrSamples)

stringsList.add(splitLine[k]);

if (selectedCols.get(k) == PreProcessing.xAxisValue && oxList.size() < nrSamples) {

if (!oxList.contains(splitLine[k])) {

oxList.add(splitLine[k]);

}

else {

counterOxList[k]++;

oxList.add(splitLine[k] + "("+ counterOxList[k]+ ")");

}

}

if (selectedCols.get(k) == PreProcessing.datasetValue) {

averageVal[j] = totalVal[j]/ lastSampleCounter[j];

oneSampleList.get(j).add(averageVal[j]);

oneSampleList.get(j).add(maximVal[j]);

oneSampleList.get(j).add(minimVal[j]);

}

}

}

}

Anexa 2 – Cod Helper – toString

public static StringBuilder toString(List<List<List<Float>>> dataList, List<String> oxList) {

List<Integer> selectedCols = new ArrayList<Integer>();

selectedCols = PreProcessing.getList();

List<String> stringNames = new ArrayList<String>();

stringNames = ProcessingData.getAllStrings();

StringBuilder appendString = new StringBuilder();

for(int i=0; i< dataList.size();i++) {

for(int j = 0; j< dataList.get(i).size();j++) {

if(dataList.get(i).get(j).size() > 0 && selectedCols.get(j) == PreProcessing.datasetValue) {

appendString.append(dataList.get(i).get(j).get(0)).append(ESSENTIAL_SEPARATOR);

appendString.append(dataList.get(i).get(j).get(1)).append(ESSENTIAL_SEPARATOR);

appendString.append(dataList.get(i).get(j).get(2));

} else {

appendString.append(ESSENTIAL_SEPARATOR);

appendString.append(ESSENTIAL_SEPARATOR);

}

if(j<dataList.get(i).size()-1)

appendString.append(SAMPLE_SEPARATOR);

}

if(i<dataList.size()-1)

appendString.append(REPRESENTATION_SEPARATOR);

}

appendString.append(DATA_OX_SEPARATOR);

for(int i=0;i<oxList.size();i++) {

if(i < oxList.size()-1)

appendString.append(oxList.get(i)).append(ESSENTIAL_SEPARATOR);

else

appendString.append(oxList.get(i));

}

appendString.append(DATA_STRING_SEPARATOR);

for(int i=0;i<stringNames.size();i++) {

if(i<stringNames.size()-1)

appendString.append(stringNames.get(i)).append(ESSENTIAL_SEPARATOR);

else

appendString.append(stringNames.get(i));

}

return appendString;

}

Anexa 3 – Cod Helper – fromString

public static List<String> oxFromString(StringBuilder _str) {

List<String> _oxList = new ArrayList<String>();

String oxStr = _str.substring((_str.indexOf(DATA_OX_SEPARATOR) + 2), (_str.indexOf(DATA_STRING_SEPARATOR)));

String[] oxSplit = oxStr.split(ESSENTIAL_SEPARATOR);

for (int i = 0; i < oxSplit.length; i++) {

_oxList.add(oxSplit[i]);

}

return _oxList;

}

Anexa 4 – Cod citire fisier prin bytes

public static int readWithBytes(File fileToRepresent, JDesktopPane desktopPane) throws IOException {

FileInputStream stream = new FileInputStream(fileToRepresent);

byte[] buffer = new byte[8192];

int count = 0;

int n;

while ((n = stream.read(buffer)) > 0) {

for (int i = 0; i < n; i++) {

if (buffer[i] == '\n')

count++;

}

}

stream.close();

return count;

}

Anexa 5 – Cod detectare automată a delimitatorului

inputStreamPreview = new FileInputStream(fileToRepresent);

scPreview = new Scanner(inputStreamPreview, "UTF-8");

try {

for (int i = 0; i < 20; i++) {

if (scPreview.hasNextLine()) {

line = scPreview.nextLine();

concatLines = concatLines.concat(line);

}

}

if (scPreview.ioException() != null) {

throw scPreview.ioException();

}

} finally {

if (inputStreamPreview != null) {

inputStreamPreview.close();

}

if (scPreview != null) {

scPreview.close();

}

}

int maxFreq = 0;

int count = 0;

for (int i = 0; i < concatLines.length(); i++) {

count = 0;

for (int j = i; j < concatLines.length(); j++) {

if (concatLines.charAt(i) == concatLines.charAt(j) && delimitersList.contains(concatLines.charAt(i)))

count++;

}

if (count > maxFreq) {

maxFreq = count;

maxChar = concatLines.charAt(i);

}

}

Anexa 6 – Grafice de tip one-chart

Pentru tipul de grafic simplu, cu un singur plot, reprezentarea de tip „Bar chart” va arăta astfel:

Reprezentarea de tip „Stacked bar chart” pentru graficul cu un singur plot:

Reprezentarea de tip „3D bar chart”:

Reprezentarea de tip „Line chart”:

Reprezentarea de tip „3D line chart”:

Reprezentarea de tip „Area chart”:

Anexa 7 – Grafice de tip multi-chart

În continuare, se vor prezenta graficele aferente fișierului de intrare, dar de această dată prin intermediu opțiunii multi-chart.

Reprezentarea de tip „Bar chart” va arăta astfel:

Reprezentarea de tip „3D bar chart”:

Reprezentarea de tip „Line chart”:

Reprezentarea de tip „3D line chart”:

Anexa 8 – Imagine de ansamblu asupra aplicației în urma etapei de procesare

Similar Posts

  • Strategii DE Imbunatatire A Calitatii Aplicate In Cadrul Unei Firme

    === 9a0067a42ab28d0eebfd26aac5cd0d9770d98b30_540006_1 === FACULTATEA DE ȘTIINȚE ECONOMICE SPECIALIZAREA MANAGEMENT LUCRARE DE LICENȚĂ COORDONATOR, ABSOLVENT, 2018 FACULTATEA DE ȘTIINȚE ECONOMICE SPECIALIZAREA MANAGEMENT STATEGII DE ÎMBUNĂTĂȚIRE A CALITĂȚII APLICATE ÎN CADRUL UNEI FIRME COORDONATOR ABSOLVENT 2018 CUPRINS INTRODUCERE 4 СAΡΙΤОLUL Ι – СОNЅΙDΕRAȚΙΙ ΤΕОRΕΤΙСΕ ΡRΙVΙND MANAGΕMΕNΤUL СALΙΤĂȚΙΙ 7 1.1 СALΙΤAΤΕA ΡRОDUЅΕLОR ȘΙ ЅΕRVΙСΙΙLОR 7 1.2 СОNСΕΡΤUL DΕ…

  • Bazele Merceologiei

    BAZELE MERCEOLOGIEI Generalități și noțiuni fundamentale în merceologie Unul din obiectivele domeniului merceologiei este acela de a crea o terminologie proprie și unitară în afirmarea acestui domeniu. Este sesizată utilizarea inconsecventă și necorelarea în utilizarea unor concepte fundamentale din acest domeniu în cazul normelor legislativ-normative, în cazul terminologiilor și vocabularului utilizate fie de producători, fie…

  • Binele Public șI Rolul Organizațiilor Neguvernamentale ÎN România

    Cuprins INTRODUCERE……………………………………………………………………………………………………7 Capitolul 1. Binele public și factorii de influență ai societății………………………………..8 Binele public…………………………………………………………………………………………………………..8 Valorile…………………………………………………………………………………………………………………9 Educația……………………………………………………………………………………………………………….11 Gândirea socială ……………………………………………………………………………………………………12 Politicile sociale……………………………………………………………………………………………………..14 Instituțiile……………………………………………………………………………………………………………..17 Intervenția în câmpul social…………………………………………………………………………………….18 Capitolul 2. Organizațiile neguvernamentale în România…………………………………..20 2.1. Organizațiile neguvernamentale. Generalități…………………………………………………..20 2.2. Rolul ONG-urilor în societate…………………………………………………………………………23 2.3. Cum funcționează un ONG…………………………………………………………………………….25 2.4. Ce anume determină înființatea și implicarea într-un ONG………………………………26…

  • Influentele Culturale Asupra Campaniilor Globale de Marketing. Studiu de Caz Campania Globala Lay’s Smiles

    === 7d52d641227554610778692edeefddab542200a9_619660_1 === DІЅТRІВUȚІA ΡRΟDUЅЕLΟR LAΥ’Ѕ LA NІVЕL oc NAȚІΟNAL ȘІ ІNТЕNAȚІΟNAL INTRODUCERE Aϲеaѕtă luϲrarе a fοѕt еlabοrată ϲu sϲοрul dе a-mi ѕеrvi реntru ѕuѕținеrеa luϲrării dе liϲеnță, tеma alеaѕă dе minе еѕtе ѕtudiеrеa mοdului ϲum ѕе rеalizеază diѕtribuția рrοduѕеlοr la ЅϹ Ѕtar Fοοd ΕΜ ЅRL, un alt mοtiv al alеgеrii aϲеѕtеi tеmе еѕtе aϲеla…

  • Intocmirea Si Prezentarea Situatiilor Financiare la Sc X.studiu de Caz

    === 3d2e63c69df16359f70ead0eb9aaeb9e0b3ea341_365742_1 === Ϲuрrіnѕ Ιntrοduсеrе…………………………………………………………………………………………………………….5 ϹΑРΙΤΟLUL Ι ΑВΟRDĂRΙ ϹΟΝϹΕРΤUΑLΕ ΙΝΤRΟDUϹΤΙVΕ РRΙVΙΝD ΤΕΜΑ ΑВΟRDΑΤĂ…7 1.1 Ѕtruсturɑ ѕіtuɑțііlοr fіnɑnсіɑrе……………………………………………………………………………..9 1.2 Întοсmіrеɑ ѕіtuɑțііlοr fіnɑnсіɑrе…………………………………………………………………………16 1.3 Vеrіfісɑrеɑ, сеrtіfісɑrеɑ șі сеntrɑlіzɑrеɑ ѕіtuɑțііlοr fіnɑnсіɑrе………………………………17 1.4 Αnɑlіzɑ dɑtеlοr dіn ѕіtuɑțііlе fіnɑnсіɑrе………………………………………………………………19 ϹΑΡIΤОLUL II ΡRΕΖΕΝΤΑRΕΑ GΕΝΕRΑLĂ Α FIRΜΕI Ѕ.Ϲ. WIΕΝΕRВΕRGΕR Ѕ.Α………………22 2.1 Dɑtе dе іdеntіfісɑrе ɑlе ɑɡеntuluі есοnοmіс………………………………………………………..22 2.2 Ѕсurt іѕtοrіс Ѕ.Ϲ ”WІЕΝЕRВЕRGЕR”…

  • Decoratiunile Interioare,ca Materie Optionala Si Valentele Lor Terapeutice In Recuperarea Psihomoticitatii Elevilor CU Deficienta Mintala Severa DE Varsta Scolara Mare

    === b22574d041ac0e16d6155500215770f91265c0d0_332681_1 === CAPITOLUL 1 DEFICIENȚA MINTALĂ 1.1.Aspecte generale privind conceptul de deficiență mintală Deficiența mintală desemnează o modalitate-cu grade și niveluri diferite a personalității cu o specificitate de structură,care are imprimată o finalitate formativă și integrativă.Această categorie de structure beneficiează de o cantitate redusă de informație esențializată ,dar poate recepționa și prelucra o mare…