Uniwersytet Mikołaja Kopernika Wydział Fizyki, Astronomii i Informatyki Stosowanej Michał Kołkowski nr albumu: 236391 Praca inżynierska na kierunku Informatyka Stosowana Wizualizacja Informacji Tekstowej Opiekun pracy dyplomowej prof. dr hab. Włodzisław Duch Katedra Informatyki Stosowanej Toruń 2013 Pracę przyjmuję i akceptuję Potwierdzam złożenie pracy dyplomowej...... data i podpis opiekuna pracy data i podpis pracownika dziekanatu
Dziękuję prof. dr hab. Włodzisławowi Duchowi za pomoc w przygotowaniu pracy. 2
UMK zastrzega sobie prawo własności niniejszej pracy magisterskiej (licencjackiej, inżynierskiej) w celu udostępniania dla potrzeb działalności naukowo-badawczej lub dydaktycznej 3
Spis treści Strona 1. Wstęp..... 6 1.1 Wprowadzenie do tematu pracy....... 6 1.2 Repozytorium stworzonego projektu. 7 2. Baza danych WordNet........ 8 2.1 WordNet wprowadzenie..... 8 2.2 Zastosowanie bazy danych WordNet 9 2.3 Budowa WordNet na podstawie plików WNDB.. 10 2.4 WordNet w postaci relacyjnej bazy danych..... 11 3. Sposób realizacji zadania wizualizacji bazy danych...... 13 3.1 Sposoby wizualizacji danych.... 13 3.2 Projekty wizualizujące słownik języka angielskiego.... 16 3.3 Założenia wizualizacji w moim projekcie.... 16 4. Budowa aplikacji do wizualizacji danych...... 20 4.1 Budowa aplikacji opartej na JavaScript i HTML5 Canvas.. 20 4.2 Struktura mojej aplikacji... 21 4.3 Zarządzanie projektem programistycznym........ 22 5. Pobieranie danych z bazy SQL. 25 5.1 Skrypty PHP używające biblioteki PDO. 25 5.2 Dynamiczne pobieranie treści technologia AJAX.. 28 6. Struktury przechowujące dane.... 31 6.1. JavaScript jako język obiektowy... 31 6.2. Struktury danych przechowujące dane do wizualizacji. 32 7. Wizualizacja elementów na grafie... 35 7.1 Algorytm rozkładu grafu na bazie sił skierowanych. 35 7.2 Modyfikacje algorytmu na potrzeby projektu... 37 7.3 Algorytm rozkładu kołowego 39 8. Interfejs użytkownika aplikacji wizualizującej dane..... 41 8.1 Budowa interfejsu użytkownika 41 8.2 Zastosowanie jquery UI okna dialogowe i podpowiedzi... 43 4
8.3 Dodatkowe możliwości z pomocą narzędzia Firebug... 45 9. Zastosowanie dla aplikacji wizualizującej WordNet. 47 10. Podsumowanie... 48 11. Literatura i odnośniki... 49 5
1. Wstęp 1.1. Wstęp do tematu pracy Tematem mojej pracy inżynierskiej jest Wizualizacja Informacji Tekstowej. W dzisiejszym świecie jesteśmy zalewani różnego rodzaju informacjami tekstowymi. Złożone informacje z wielu dziedzin coraz częściej przechowywane są w wielkich bazach danych. Interpretacja dużej ilości danych w formie tekstowej jest dla człowieka zadaniem trudnym. Bardzo przydatne okazują się wizualizacje graficzne. Przedstawiając dane na rysunku możemy w sposób przejrzysty pokazać powiązania między konkretnymi informacjami. Zadanie przystępnego przedstawienia danych tekstowych znacznie się komplikuje wraz ze wzrostem ilości wyświetlanych danych. Dobra aplikacja wizualizująca informacje powinna, więc umożliwić filtrowanie informacji. Celem mojej pracy inżynierskiej było stworzenie aplikacji wizualizującej informacje tekstowe przechowywane w już istniejącej bazie oraz opisanie sposobów realizacji tego zadania. W Internecie można znaleźć bardzo wiele możliwych do wykorzystania baz danych. Zarówno dostępnych w formie plików do pobrania jak i tylko za pomocą gotowego API (Application Programming Interface) stworzonego na potrzeby danej bazy. Wybrałem bazę danych WordNet, która jest ogromną leksykalną bazą języka angielskiego. Zaletą tego wyboru jest szeroka możliwość zastosowania danych językowych, licencja umożliwiająca wykorzystanie także w komercyjnych projektach oraz dostępność tej bazy w formacie SQL. Problem przejrzystej wizualizacji dużej ilości danych jest złożony. Często istnieje wiele możliwości zaprezentowania danych i musimy wybrać taką, która naszym zdaniem sprawdzi się najlepiej. Poza samym zagadnieniem wizualizacji danych musiałem również wybrać technologie, przy użyciu których będę realizował projekt. W założeniu program miał działać w przeglądarce internetowej. Taka forma programu powoduje, że jest on łatwo dostępny dla niemal każdego użytkownika komputera, a także coraz powszechniejszych smartfonów i tabletów multimedialnych. Zdecydowałem się na użycie stosunkowo nowej technologii HTML 5 współpracującej z językiem skryptowym JavaScript. Wybór ten był podyktowany chęcią uniknięcia używania technologii Adobe Flash, która nie jest już rozwijana. 6
W tekście mojej pracy inżynierskiej postaram się przybliżyć temat wizualizacji danych tekstowych oraz schemat działania stworzonej przeze mnie aplikacji. W celu odpowiedniej prezentacji bazy danych warto najpierw poznać jej budowę. Z tego względu na początku skupie się na opisie bazy danych WordNet. Jako, że przedstawione przeze mnie rozwiązania nie są jedynymi możliwymi, zaprezentuje też inne projekty dotyczące wizualizacji danych. Od rozdziału czwartego skupię się głównie na mojej aplikacji jej budowie, wykorzystanych algorytmach oraz problemach, które w trakcie jej tworzenia napotkałem. 1.2. Hiperłącza do stworzonego projektu Wykonaną przeze mnie aplikację można znaleźć pod adresem: http://mkolkowski.lqnstudio.mydevil.net/ Publiczne repozytorium projektu dostępne jest pod adresem: https://repo.mydevil.net/svn/pub/lqnstudio/vsearch/ 7
2. Baza danych WordNet 2.1. WordNet - wprowadzenie WordNet [1] to leksykalny słownik języka angielskiego. WordNet powstał na Uniwersytecie Princeton w Laboratorium Nauk Kognitywnych. Jego rozwój rozpoczął się w 1985 i trwa do dzisiaj. Obecna wersja projektu jest oznaczona jako 3.1. Zaletą WordNet jest licencja, która pozwala na darmowe używanie słownika także do komercyjnego użytku. Na stronie projektu można również przeglądać zawartość słownika z poziomu przeglądarki internetowej [2]. Słownik WordNet jest rozprowadzany w postaci plików ASCII, ale w Internecie można znaleźć także wersję w postaci relacyjnej bazy danych. W słowniku WordNet formy podstawowe słów(w lingwistyce zwane lemmą) pogrupowane są w zbiory synonimów(zwane synsetami), które reprezentują odrębne pojęcia. Należy zaznaczyć, że baza danych WordNet nie zawiera między innymi zaimków, przyimków oraz spójników. WordNet różni się od słownika wyrazów bliskoznacznych przede wszystkim tym, że to nie słowa są między sobą powiązane relacjami semantycznymi, ale ich znaczenia. WordNet wyróżnia również określanie relacji semantycznych innych niż znaczeniowe podobieństwo. Zbiory synonimów zawierają również dodatkowe informacje: definicje oraz przynależność leksykalną. Większość synsetów zawiera również przykłady użycia jednego lub większej ilości słów zawartych w zbiorze. WordNet w wersji 3.0 zawiera 117659 zbiorów synonimów. Dokładne statystyki z podziałem na części mowy przedstawiam poniżej (Tab. 1.). Część mowy Tab.1. Statystyka dotycząca bazy danych WordNet [1]. Unikalny ciąg Zbiory Pary Lemma-znaczenie znaków synonimów Rzeczownik 117798 82115 146312 Czasownik 11529 13767 25047 Przymiotnik 21479 18156 30002 Przysłówek 4481 3621 5580 Łącznie 155287 117659 206941 8
Oprócz relacji synonimii w słowniku WordNet występują inne relacje [3]. Generalnie relacje można podzielić na leksykalne oraz semantyczne. Większość relacji semantycznych łączy zbiory z tej samej części mowy. Zdarzają się jednak połączenia pomiędzy różnymi częściami mowy. Postaram się przybliżyć znaczenie posiadania w słowniku relacji, przez przedstawienie najczęściej występujących relacji z podziałem na części mowy. Dla rzeczowników najczęściej występującą relacją jest hiponimia. Zachodzi ona między wyrazem o treści szczegółowej oraz wyrazem bardziej ogólnym. Polega na stosunku podrzędność-nadrzędność. Przykładowo wyraz krzesło jest hiponimem w stosunku do słowa meble. Hiponim jest słowem podrzędnym w stosunku do bardziej ogólnego słowa, zawiera się w jego znaczeniu. Hiperonimem nazywamy słowo nadrzędne. Hiponimia jest relacją przechodnią. Jeśli krzesło jest hiponimem dla słowa meble, a fotel dla słowa krzesło, to fotel również będzie hiponimem dla słowa meble. Należy też zaznaczyć, że słownik WordNet rozróżnia typy oraz instancje. Przykładowo fotel może być rodzajem krzesła. Natomiast Polska jest konkretnym państwem, a nie typem państwa. Ważną relacją semantyczną dla rzeczowników jest meronimia. Meronimem jest fragment większej całości, czyli holonimu. Dla czasowników najczęściej występującą relacją jest troponimia. Relacja ta oznacza, że jeden synset opisuje szczególny przypadek drugiego synsetu(zawierający charakterystyczne cechy). Przykładem może być relacja pomiędzy słowami mówić oraz szeptać. Dla przymiotników ważną relacją jest antonimia. Antonimami nazywamy słowa o przeciwnym znaczeniu np. zimny-ciepły. Jeśli chodzi o relacje przysłówków, to większość wskazuje na przymiotniki bazowe (np. slow slowly). 2.2. Zastosowanie bazy danych WordNet Przedstawione możliwości projektu WordNet czynią go bardzo użytecznym narzędziem do lingwistyki komputerowej oraz przetwarzania języka naturalnego. 9
Natural Language Processing (Przetwarzanie języków naturalnych) [4] jest dziedziną łączącą zagadnienia sztucznej inteligencji i językoznawstwa. Zajmuje się automatyzacją analizy, zrozumienia i generowania języka naturalnego(używanego przez ludzi do komunikacji) przez komputer. Głównym problemem dziedziny jest przekształcanie języka naturalnego na język formalny łatwy do odczytania przez komputer i odwrotnie. W tym aspekcie dane występujące w słowniku WordNet są bardzo przydatne. WordNet jest wykorzystywany w algorytmach zajmujących się identyfikacją encji (Named-entity recognition), czyli klasyfikowaniem elementów do kategorii takich jak osoby, organizacje czy lokacje. Przykładem narzędzia używającego bazy WordNet jest Natural Language Toolkit (NLTK) [5] zestaw bibliotek napisanych w języku Python. 2.3. Budowa WordNet na podstawie plików WNDB Ze strony projektu można pobrać bazę danych WordNet w postaci wielu plików ASCII o różnych formatach. W zrozumieniu zawartości tych plików pomaga dostępna dokumentacja [6]. Formą przypomina ona dokumentacje programów systemu bazującego na Unix. Główne dane słownika dotyczące słów, synsetów oraz połączeń znajdują się w 8 plikach bazodanowych(wndb). Pliki WNDB to zwykłe pliki ASCII. Każde słowo lub synset stanowi oddzielną linię w pliku. Dokładne omówienie każdego pliku można znaleźć w dokumentacji [6]. Kolejne pola zawierające informacje o wpisie oddzielane są spacjami. Pliki podzielone są na kategorie: noun, verb, adjective, adverb. Dla każdej kategorii istnieją dwa pliki: index oraz data. Pliki index stanowią alfabetyczną listę słów występujących w słowniku. Pojedynczy wpis zawiera słowo pisane małymi literami, część mowy, liczbę synsetów, do których należy słowo oraz liczbę wszystkich wskazań na dane słowo. Dla każdego odniesienia do słowa przypisany jest specjalny znak, który oznacza typ relacji. Znaki te zdefiniowane są w plikach leksykograficznych. 10
Ważnym polem jest synset offset pole zawiera liczbę będącą w bajtach przesunięciem, po którym można odnaleźć miejsce synsetu powiązanego z lemmą w pliku typu: data. Pliki data zawierają informacje o synsetach. Pojedynczy wpis zaczyna się polem synset offset, czyli 8-bitowym przesunięciem danego wpisu w pliku. Plik data posiada informacje o części mowy synsetu, ilości słów w tym zbiorze oraz listę wszystkich słów do niego należących. Znajduje się tu także definicja zbioru oraz przykład użycia niektórych członków zbioru. Bardzo ważną informacją zawartą pliku data są relacje między synsetami. Pojedynczy wpis zawiera liczbę relacji, w które wchodzi dany synset oraz tablicę przesunięć w pliku data, czyli po prostu tablicę wskaźników na połączone synsety razem z typem relacji. Używanie plików bazodanowych w przedstawionej formie wiążę się z koniecznością używania pól zawierających przesunięcie rekordu w pliku. Jest to dość niewygodne rozwiązanie. Duże problemy pojawiają się, gdy chce się dodać lub usunąć rekordy. Należałoby wówczas obliczyć na nowo wartości pól zawierających przesunięcia rekordów. 2.4. WordNet w postaci relacyjne bazy danych W tworzonym przeze mnie projekcie nie zdecydowałem się na używanie plików WNDB. Wymagałoby to ode mnie stosunkowo dużo kodu do obsługi takiej bazy. Dużo lepszym rozwiązaniem jest użycie relacyjnej bazy danych. W relacyjnych systemach baz danych dane przechowywane są w strukturach nazwanych tabelami. Pomiędzy danymi zawartymi w tych tabelach występują relacje. Jednoznaczną identyfikacje każdego rekordu osiągniemy dzięki istnieniu kluczy głównych - nie będzie, więc problemów z usuwaniem albo dodawaniem danych. Zaletą takiego rozwiązania jest prostota pobierania danych i modyfikacji oraz przede wszystkim istnienie wielu gotowych interfejsów usprawniających pracę z takimi bazami. Napisanie parsera, który przekonwertuje dane z postaci plików ASCII do dowolnej relacyjnej bazy danych nie jest bardzo trudnym zadaniem. Istnieją jednak gotowe rozwiązania, których można użyć. 11
WordNet SQL Builder [7] jest projektem na licencji GPL, który udostępnia oprogramowanie umożliwiające przekształcenie bazy WordNet do formatu MySQL lub PostgreSQL. Oprogramowanie zostało napisane w języku Java. Ze względu na otwartość kodu można wprowadzać do niego swoje zmiany. Na stronie dostępne są też gotowe bazy danych w wyżej wspomnianych formatach. Projekt WordNet SQL [8] zajmuje się udostępnieniem baz danych WordNet w większej ilości baz danych SQL. Ze strony projektu można pobrać bazę danych WordNet w formacie SQLite. Baza ta zawiera dane słownika WordNet w wersji 3.0. Schemat bazy danych również można pobrać ze strony projektu. Bazę danych w tym formacie używam w mojej aplikacji. W celu zmniejszenia rozmiaru bazy usunąłem jednak tabele, których nie używam. 12
3. Sposób realizacji zadania wizualizacji danych 3.1. Wizualizacja danych Ludzkie zdolności do analizy dużych danych tekstowych w nieprzetworzonej (np. formalnej, generowanej przez komputer) postaci są bardzo ograniczone. Potrzeba wizualizacji informacji wynika ze zdolności człowieka do stosunkowo szybkiego rozpoznawania i interpretowania obrazów [9]. Proces wizualizacji może być kluczem do współpracy komputera oraz ludzkiego umysłu. Badania na temat wizualizacji informacji mają duży związek z potrzebą interpretacji danych generowanych, przetwarzanych i gromadzonych przez urządzenia pomiarowe lub trakcie symulacji komputerowych [11]. Celem jest umożliwienie użytkownikowi łatwego przeszukiwania, filtrowania bazy danych oraz zapewnienie wystarczającego poziomu zrozumienia informacji. Wizualizacje mogą ukazywać tylko konkretne cechy danych. Dzięki ograniczeniu ilości prezentowanych cech można dokładniej obejrzeć wybrany aspekt. Wizualizacja danych często dotyczy ogromnych zbiorów danych, ale odpowiednio przygotowane prezentacje pozwalają bardzo szybko rozpoznać ogólne cechy zjawiska. Najbardziej oczywistym celem wizualizacji jest oczywiście prezentacja informacji w łatwo przyswajalnej formie graficznej [9]. Do prezentacji danych można użyć na przykład powszechnie używanych form histogramu, wykresu kołowego czy struktury grafu. Coraz powszechniejsze są jednak bardzie nowatorskie metody. Obecnie coraz ważniejszym powodem tworzenia wizualizacji jest analiza i eksploracja zgromadzonych danych. Istnieje możliwość oceny kompletności i prawidłowości zgromadzonych danych. Na podstawie odpowiedniej wizualizacji łatwo rozpoznać różnice między grupami danych. Można też rozpoznawać tendencje i trendy, a także wykrywać wyjątki oraz anomalie. W praktyce badawczej tradycyjnie wizualnie zorientowanych nauk (np. historia sztuki, antropologia) wizualizacje były stosowane od połowy XIX wieku jako środek wyrazu wytwarzanej wiedzy [9]. Obecnie za sprawą konieczności analizy danych gromadzonych przez urządzenia wizualizacje znalazły szerokie zastosowanie w naukach technicznych i przyrodniczych. Wizualizacje nie są już tylko ozdobą ani metodą prezentacji, ale mają więcej zadań związanych z analizą wiedzy. 13
Duże zastosowanie metody wizualizacji znalazły dzięki powstaniu sieci Internet, która zawiera ogromną ilość informacji. Dostępne w Internecie bazy danych często korzystają z wizualizacji. Nie chodzi tu tylko o bazy naukowe. Z wizualizacji korzystają dziś serwisy społecznościowe czy serwisy internetowe na dowolny temat. Wizualizowane są często rozmaite statystyki, a także np. powiązania słów kluczowych czy kategorii dotyczących artykułów. W Internecie złożonym z rozproszonych na różnych serwerach danych problemem pozostaje wyszukiwanie danych. Obecnie główną rolę w wyszukiwaniu danych pełnią wyszukiwarki tekstowe np. Google. Istnieją również wyszukiwarki wizualne, które umożliwiają przeglądanie zasobów Internetu z pomocą interaktywnej i efektownej graficznie wizualizacji. Przykładem takiej wyszukiwarki jest Search-Cube [10], która prezentuje zasoby sieci jako kwadratowe pola znajdujące się na sześciennej kostce. Użytkownik może obracać kostkę, aby obejrzeć inne dane. Wizualizacje prezentowane w Internecie mają szczególną cechę są bardzo często przeznaczone dla odbiorcy masowego. Istnieje mnóstwo sposobów wizualizacji danych. Ważną cechą, która wpływa na możliwości prezentacji danych jest rodzaj pokazywanej informacji [11]. Informacja liniowa składa się z ciągu liczb i cyfr. Dane są w postaci list i tabel, mogą to być też kody programów. Ten rodzaj danych może być ciężki do przedstawienia w formie graficznej. Dużo łatwiej przedstawić wizualnie informację hierarchiczną. Jest to najczęściej spotykana grupa informacji. Dane podlegają wyraźnej hierarchii. Hierarchiczną strukturą danych nazwiemy strukturę, którą może reprezentować drzewo [12] (graf bez cykli). Przykładem może być struktura plików czy dane geologiczne. Przykładem konkretnego rozwiązania jest program TreeMap [13]. Wizualizuje on drzewa katalogów (może też przedstawiać inne dane) w postaci zagnieżdżonych prostokątów. Wielkość pól jest proporcjonalna do rozmiaru pliku, a kolor może przedstawiać typ pliku. Ciekawym przykładem wizualizacji informacji hierarchicznej jest też aplikacja Newsmap [14]. Prezentuje ona podzielone na kategorie informacje ze świata lub wybranego regionu za pomocą prostokątów z tekstem. Takie rozwiązanie może być szczególnie wygodne na powszechnych dzisiaj ekranach dotykowych. Informację sieciową najłatwiej sobie wyobrazić jako topologię okablowania czy komunikacji. Informacja sieciowa może być również zbiorem słów powiązanych 14
znaczeniowo relacjami semantycznymi i leksykalnymi. Tego typu informacje zawarte są w słowniku WordNet. Poszczególne informacje są najczęściej przedstawiane jako wierzchołki, a relacje między nimi jako ich połączenia. Strukturą odpowiednią dla takiej informacji jest graf lub wiele grafów. Przykładem takiej informacji może być sieć podwodnych kabli. Na stronie TeleGeography można znaleźć wizualizacje tych danych na mapie [15]. Innym rodzajem informacji jest informacja wielowymiarowa, która może opierać się na istnieniu metadanych, które zawierają informacje o dokumencie i jednocześnie zawarte są w nim zawarte. Wiele ciekawych wizualizacji w temacie różnych dziedzin nauki można znaleźć na stronie Places & Spaces: Mapping Science [16]. Projekt ma dwa aspekty. Pierwszym jest tworzenie wysokiej jakości map w celu zaprezentowania ich na wystawach na konferencjach i w ośrodkach edukacyjnych. Drugim jest możliwość uzyskania dostępu do wybranych serii map przez stronę za pomocą Internetu. Jako przykład wizualizacji o mniej naukowym charakterze można podać projekt ASK KEN [17]. Przedstawia on w postaci połączonych węzłów będących kołowymi diagramami, bazę danych Freebase [18]. ASK KEN zapewnia efektowną wizualizację. Aplikacja ma wbudowany algorytm fizyczny, który umożliwia użytkownikowi zabawę układem węzłów. Baza danych Freebase to otwarta baza posiadająca ponad 23 miliony encji. Encją mogą być rzeczy, osoby, miejsca, ale też na przykład konkretne filmy czy książki. Elementy połączone są wzajemnie w strukturę grafu. Rys.1. Wizualizacja z pomocą programu ASK KEN. 15
3.2. Projekty wizualizujące słownik języka angielskiego Tworzony przeze mnie projekt ma za zadanie wizualizować dane słownika WordNet. Przed rozpoczęciem tworzenia programu zapoznałem się z już istniejącymi rozwiązaniami. Dostępne projekty na ten temat mają różne zadania i są przeznaczone do różnych odbiorców. Niektóre mają na celu umożliwienie w sposób graficzny rozwijania bazy danych. Inne służą głównie do edukacji np. poprawienia znajomości języka szczególnie zwiększenia zasobu słownictwa. Poniższe programy prezentują dane używając struktury grafu lub drzewa. Visual Thesaurus [19] jest interaktywnym tezaurusem. W atrakcyjny sposób przedstawia powiązania miedzy znaczeniami słów (Rys.2.). Aplikacja bardzo sprawnie, w dynamiczny sposób rozkłada elementy grafu. Program wspiera grafy o bardzo dużej wielkości. Jak w wielu tego typu programach, w środku znajduje się wpisywany przez użytkownika element. Od niego odchodzą kolejne elementy tworząc strukturę grafu. Po najechaniu myszą na zbiór synonimów można poznać jego definicję i przykłady użycia. Program umożliwia również filtrowanie danych np. pokazywanie tylko konkretnych części mowy. Plusem programu są też dodatkowe funkcje jak na przykład historia wyszukiwania czy możliwość wygenerowania i wydrukowania dokumentu pdf, który podsumuje przeprowadzoną wizualizację. Rys.2. Wizualizacja dla słowa word z pomocą programu Visual Thesaurus. 16
Prostym programem o podobnych założeniach jak Visual Thesaurus jest program JavaScript Visual WordNet [20]. Program rozkłada drzewo za pomocą algorytmu sił skierowanych (Rys.3.). Projekt jest warty uwagi, ponieważ do wyświetlania węzłów używa wyłącznie DOM (Document Object Model) [21] oraz technologii CSS. Elementy drzewa pozycjonowane są absolutnie. Wizualizacja przedstawia tylko synonimy, nie są zawarte inne relacje z bazy WordNet. Rys.3. Wizualizacja dla słowa void z pomocą programu JavaScript Visual WordNet. Bardzo ciekawym projektem jest WordNet Editor [22] (Rys.4.) jest on częścią projektu WordNet Solution rozwijanego na Wydziale Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej. WordNet Editor jest stworzony przy użyciu oprogramowania open source. Poza wizualizacją umożliwia także edycje słownika w intuicyjny, graficzny sposób. Program działa zgodnie z koncepcją Wiki. WordNet Editor prezentuje informacje używając technologii Flash z pomocą oprogramowania Gossamer. Przeglądać oraz edytować słownik WordNet można zarówno z poziomu strony internetowej jak i aplikacji klienckiej napisanej w języku Java. Program ma czasem problemy z wizualizacją dużej ilości danych. W trakcie rozwijania kolejnych węzłów w programie rysunek może stać się nieczytelny, jednak dzięki możliwości filtrowania danych, czyli na przykład ukazania tylko wybranych relacji, można uniknąć takich sytuacji. WordNet Editor to bardzo zaawansowana aplikacja, która może posłużyć również jako narzędzie do budowy słownika dla innego języka niż angielski. 17
Rys.4. Wizualizacja z programu WordNet Editor. 3.3. Założenia wizualizacji w mojego projektu Wizualizacje rozpoczynam od umieszczenia na rysunku słowa wpisanego przez użytkownika. Wybrałem umieszczenie tego słowa w centrum rysunku, jako korzeń drzewa. Duże ułatwienie stanowi uniemożliwienie przemieszczania tego słowa. W ten sposób każdy inny element może być ustawiony względem węzła głównego. Pozwala to na dostosowanie rozmiaru wyświetlanego rysunku do rozmiaru roboczego użytkownika. Drzewiastą strukturę stanowią zbiory synonimów (przedstawione w postaci koła), do których należy korzeń, wraz z innymi słowami do nich należącymi. Całość uzupełniają relacje semantyczne oraz leksykalne. Łączą one istniejące już synsety z innymi istniejącymi albo nowymi synsetami. W ten sposób powstaje graf. Relacje są oznaczone za pomocą kwadratu znajdującego się po środku linii łączącej dwa synsety. Ważny czynnik wizualizacji stanowi kolor. Korzeń ma inne tło niż pozostałe słowa. Również specjalny kolor dostały słowa, które wiążą się z relacją leksykalną. Kolor prezentuje również część mowy jaką stanowi zbiór synonimów. Moja wizualizacja zakłada również możliwość ukrywania konkretnych części mowy, relacji czy grup relacji. Mój program ma również możliwość rozbicia węzła na kilka takich samych elementów. Powoduje to powstanie nadmiarowości, ale za to umożliwia łatwiejsze rozłożenie grafu i lepszą widoczność głównej, drzewiastej struktury (opartej na synonimach). Spora część tych założeń przypomina dwa pierwsze programy przedstawione w rozdziale 3.2. 18
Do założeń mojego projektu należy również umożliwienie użytkownikowi wpływu na algorytm rozmieszczania elementów grafu. Z pomocą ustawień programu można modyfikować parametry tego algorytmu. Użytkownik może również wyłączyć algorytm rozkładu i rozmieścić elementy według swojego pomysłu po prostu przeciągając je po planszy. Rys.5. Wizualizacja relacji słowa void za pomocą wykonanej przeze mnie aplikacji. 19
4. Budowa aplikacji do wizualizacji danych w przeglądarce 4.1. Budowa nowoczesnej aplikacji opartej na HTML5 i JavaScript Obecnie w przeglądarce oprócz wyświetlania stron internetowych, możemy także używać zaawansowanych aplikacji. Powoduje to większą dostępność programów dla użytkownika, brak konieczności posiadania konkretnego systemu operacyjnego oraz brak konieczności instalowania oprogramowania na swoim komputerze. Aplikacje typu Rich Internet Application [23] (bogata aplikacja internetowa) oferują bardzo zaawansowany, dynamiczny oraz przede wszystkim jednoekranowy interfejs. Inaczej niż w przypadku statycznej strony internetowej, użytkownik nie musi ładować całego dokumentu od nowa na przykład podczas wprowadzania danych w formularzach albo nawigacji po aplikacji. Dużym plusem tego typu aplikacji jest również wykorzystanie zasobów sprzętowych użytkownika, co może odciążyć serwer. Na dodatek aplikacje typu RIA mogą działać w trybie offline, jeśli jest to możliwe w przypadku danej aplikacji. Czasami aplikacje posiadające wielofunkcyjne, interaktywne interfejsy wyświetlane w przeglądarce zwane są również Web 2.0. Bardzo szybko rozwija się kierunek budowania bogatych aplikacji internetowych w oparciu o HTML, JavaScript oraz technologie AJAX. JavaScript jest zorientowanym obiektowo oraz wieloplatformowym językiem skryptowym. Może działać na pulpicie czy serwerze, ale jego najpopularniejszym środowiskiem jest przeglądarka. Aplikacja zbudowana oparta o JavaScript nie wymaga od przeglądarki żadnych dodatkowych pluginów. JavaScript posiada wiele bibliotek wspomagających tworzenie zaawansowanych programów takich jak jquery, EXT JS, Prototype czy Yahoo! User Interface Library. Przyśpieszają one pisanie kodu, a także zapewniają poprawne działanie kodu w najważniejszych przeglądarkach. Podział aplikacji na moduły zajmujące się konkretnymi czynnościami przyśpiesza rozwijanie kodu. Podczas tworzenia dużej aplikacji warto zastosować wzorzec projektowy MVC Model-View-Controller (Model-Widok-Kontroler) [24]. Model stanowią dane np. pobrane informacje o rozkładach autobusów. Widok to warstwa prezentacji, która wyświetlana jest użytkownikowi programu. Interakcja aplikacji z użytkownikiem jest 20
natomiast zapewniana przez kontroler. Uproszczony model działania takiej aplikacji może wyglądać następująco: Użytkownik używa interfejsu aplikacji Kontroler przechwytuje wykonywane przez użytkownika akcje Kontroler pobiera dane z modelu oraz wymusza aktualizację widoku Widok jest pokazywany użytkownikowi Model stanowią struktury, gdzie dane są przechowywane. Model nie powinien wiedzieć nic o widokach ani kontrolerze. Model po prostu zawiera dane oraz logikę z nimi powiązaną. Kiedy kontroler pobierze dane z serwera wrzuca je do stworzonych dla nich struktur danych. JavaScript jest językiem zorientowanym obiektowo. Możemy więc przechowywać dane w obiektach, które mogą być przechowywane w zbiorczym obiekcie, który na przykład będzie umożliwiał wyszukanie encji o konkretnych właściwościach. Widok aplikacji może być wykonany z użyciem technologii HTML oraz CSS. Widok również powinien być oddzielony od reszty aplikacji i nie wiedzieć nic o warstwie danych oraz kontrolerze. Kontroler łączy model oraz widok. Otrzymuje zdarzenia i informacje od użytkownika, przetwarza je i aktualizuje widok. 4.2. Struktura mojej aplikacji Aplikacja do wizualizacji WordNet, którą zrealizowałem jest aplikacją typu Rich Internet Application. Jest dostępna dla użytkownika przez przeglądarkę internetową, umożliwia użytkownikowi szeroką interakcje oraz nie wymaga odświeżania strony. Większość kodu projektu została napisana w języku JavaScript. Interfejs programu został zaprojektowany przy użyciu technologii HTML i CSS. Ważną rolę pełnią skrypty PHP, które pobierają dane z bazy danych SQLite. Oczywiście skrypty i baza muszą znajdować się na serwerze. Pozostałą część aplikacji można umieścić na w dowolnym miejscu(nawet na lokalnym komputerze) pod warunkiem, że poprawne będą linki prowadzące do skryptów PHP. Z pomocą programu CLOC [25] wygenerowałem statystyki na temat kodu projektu (Rys.6.). Przedstawiona na rysunku ilość kodu uwzględnia tylko kod napisany przeze mnie, bez dołączonych bibliotek. 21
Kwestią, która rzuca się w oczy jest bardzo mała liczba linii kodu przeznaczona na PHP. Kod PHP dotyczy tylko pobierania danych z bazy danych i zwracaniem ich do JavaScript. Niewielka ilość kodu spowodowana jest użyciem bazy danych SQLite, która umożliwia bardzo łatwe pobieranie danych na podstawie zapytań w języku SQL. Rys.6. Podział kodu na konkretne technologie. Moją aplikację można podzielić ze względu na funkcjonalność na następujące elementy: Pobieranie danych z bazy dany SQLite za pomocą skryptów PHP Realizacja żądania danych z pomocą technologii AJAX Uzupełnianie stworzonych struktur danych pobranymi informacjami Wyświetlanie danych na elemencie płótna zawartym w dokumencie HTML Rozmieszczenie węzłów grafu Obsługa interfejsu użytkownika dotyczącego elementu płótna: translacja, skalowanie i wyświetlanie szczegółowych danych Obsługa pozostałej części interfejsu, nie dotyczącej bezpośrednio płótna ustawienia programu i algorytmów, filtrowanie danych, pomoc programu. Elementy te zostaną dokładniej opisane w dalszej części pracy. 4.3. Zarządzanie projektem programistycznym W pracy nad projektem programistycznym bardzo pomocne jest stosowanie odpowiedniego środowiska programistycznego, najlepiej posiadającego możliwość instalowania dodatków. Wybranym przeze mnie środowiskiem jest NetBeans IDE dostępny dla systemów operacyjnych Windows, Mac OS, Linux oraz Solaris. Projekt 22
składa się z NetBeans open-source IDE oraz platformy aplikacji, która usprawnia tworzenie aplikacji Rich Client, głównie przez udostępnienie gotowych usług oraz komponentów. NetBeans IDE wspiera rozwijanie oprogramowania w technologiach PHP, JavaScript, Ajax, Groovy and Grail, oraz C/C++. NetBeans IDE udostępnia także narzędzia wspomagające wyszukiwanie błędów aplikacji oraz używanie systemów kontroli wersji. Ważnym czynnikiem usprawniającym proces tworzenia aplikacji może być zastosowanie systemu kontroli wersji. System kontroli wersji pomaga śledzić zmiany w kodzie i łączyć zmiany dokonane przez wielu programistów. System jest przydatny nawet, gdy nad projektem pracuje tylko jeden programista. Pozwala bowiem przechowywać różne wersje kodu oraz cofać niechciane zmiany. Gdy stosujemy system kontroli wersji przechowujący dane poza naszym komputerem(na serwerze), stanowi on również kopię zapasową w przypadku uszkodzenia naszego urządzenia. Systemy kontroli wersji dzielą się na scentralizowane(klient-serwer) oraz rozproszone(p2p). W przypadku systemu scentralizowanego istnieje centralny serwer, do którego programista wysyła swoje zmiany i pobiera najnowsze wersje oprogramowania. Oczywiście w takim wypadku wymagany jest stały dostęp do takiego serwera. Przykładem systemu scentralizowanego jest używany przeze mnie w projekcie SVN (Subversion). Jest to wolne, otwarte i wieloplatformowe oprogramowanie. SVN udostępnia możliwość autoryzacji użytkowników, a archiwa mogą być publiczne lub prywatne. System prowadzi historie zmian wszystkich plików wraz z nazwą użytkownika, który dane zmiany wprowadził. W przypadku programów o otwartym źródle, system kontroli wersji umożliwia łatwe udostępnienie kodu zainteresowanym osobom. Ważną cechą SVN jest użycie transakcji, czyli zatwierdzanie dokonywanych zmian dopiero, gdy wykonano poprawnie wszystkie zlecone modyfikacje. Dużą zaletą jest również odróżnianie plików binarnych(np. grafik, skompilowanych elementów) od kodu. Przydatną cechą jest możliwość opatrzenia wysłanych zmian komentarzem. Dzięki temu wiemy, co zostało w wybranej wersji projektu zaktualizowane. 23
Rys.7. Podział repozytorium na foldery. Często używaną praktyką jest podział repozytorium na foldery zgodnie z ogólnie przyjętymi zasadami (Rys.7.). Trunk zawiera główną linie rozwijanego kodu. Folder branch powinien zawierać alternatywne wersje projektu rozwijające testowe funkcjonalności(jeśli istnieją). Folder tags może zawierać wybrane, stabilne wersje kodu, najlepiej oznaczone numerem wersji. Szczególnie w przypadku projektów o otwartym źródle przydaje się możliwość przeglądania kodu projektu przez przeglądarkę WWW. Z gotowych rozwiązań wartym polecenia jest projekt WebSVN [26]. Zaletą użycia takiego systemu jest brak konieczności posiadania środowiska programistycznego i importowania repozytorium w celu przejrzenia kodu. Takie rozwiązanie oferuje również bardzo łatwy dostęp do dziennika zmian oraz możliwość sprawdzenia, przez którego użytkownika zostały dodane konkretne fragmenty kodu projektu. 24
5. Pobieranie danych z bazy SQLite 5.1. Skrypty PHP używające biblioteki PDO Baza danych, której używam w mojej aplikacji zajmuje ponad 60 megabajtów. Użytkownik w każdym zapytaniu będzie pobierał tylko niewielką część danych znajdujących się w bazie. Z tego powodu warto bazę umieścić na serwerze, a dane pobierać uruchamiając po stronie serwera skrypty z pomocą technologii AJAX. PHP jest językiem najczęściej stosowanym do tworzenia skryptów, które działają po stronie serwera. Skrypty PHP są czasami umieszczane plikach HTML, gdy służą do generowania danych na stronie internetowej. Skrypty PHP nie muszą być używane do generowania strony, mogą także zostać wywołane z poziomu konsoli, na przykład w celu przetworzenia danych. Warto wspomnieć, że obecnie język PHP umożliwia sprawne programowanie obiektowe. PHP ma budowę modularną. W celu dodania dodatkowych funkcjonalności można zainstalować nowe moduły. Plusem użycia PHP jest ogromna popularność z czym wiąże się duży wybór serwerów(co przekłada się też na atrakcyjną cenę) oraz mnóstwo dostępnego kodu o otwartym źródle. PHP obsługuje większość znanych baz danych takich jak MySQL, PostgreSQL, Oracle, MS SQL, DB2 czy używana przeze mnie baza SQLite. SQLite to system zarządzania bazą danych oraz biblioteka języka C implementująca taki system. SQLite posiada również API do innych języków programowania między innymi PHP, C++, Python czy Java. Na stronie projektu [27] autorzy przedstawiają najważniejsze cechy systemu baz danych SQLite: samowystarczalny, nie wymagający serwera, bez konfiguracyjny oraz transakcyjny. Samowystarczalność polega na wymaganiu tylko niewielkiego wsparcia ze strony zewnętrznych bibliotek i systemu operacyjnego. Pozwala to na używanie tego systemu baz danych na wielu konfiguracjach sprzętowych, nawet bez modyfikacji. Cała zawartość bazy jest przechowywana na dysku w postaci jednego pliku. Rozwiązanie to nie wymaga stosowania osobnego serwera dla bazy danych. SQLite nie używa również żadnych plików konfiguracyjnych, nie ma potrzeby żadnych początkowych konfiguracji. Ostatnia z wymienionych cech transakcyjność oznacza, że w trakcie pojedynczej transakcji wykonywane są wszystkie zlecone operacje lub żadna. Transakcyjność funkcjonuje nawet, 25
gdy dojdzie do zawieszenia aplikacji, systemu czy braku zasilania. Ta cecha ma duże znaczenie dla bezpieczeństwa, szczególnie podczas operacji pieniężnych. W stworzonych przeze mnie skryptach PHP w celu operacji na bazach danych używam biblioteki PDO, czyli PHP Data Objects. PDO można używać od wersji 5.0 języka PHP. Biblioteka stanowi jednolity interfejs baz danych. Klasa PDO zawiera metody operacji na bazach danych, które są wspólne dla różnych silników baz danych(obsługiwanych przez tą bibliotekę). Połączenie z bazą danych przy pomocy tej biblioteki jest bardzo proste (Listing 1.). Szczegółowe informacje na temat wszystkich metod biblioteki są zawarte w obszernym poradniku [28]. W przypadku zmiany bazy danych musimy podać po prostu odpowiednie parametry przy tworzeniu obiektu PDO. W przypadku bardziej zaawansowanego projektu przydatny mógłby okazać się system ORM (Object-Relational Mapping), który odwzorowuje strukturę bazy danych w postaci obiektów. Najbardziej popularne systemy tego typu dla PHP to Doctrine oraz Propel. Listing 1. Tworzenie obiektu PDO dla bazy danych SQLite. Stworzone przeze mnie skrypty pobierają z bazy: podpowiedzi słów wpisywanych przez użytkownika, podstawowe informacje o wpisanym słowie i jego synsetach, definicję oraz słowa synsetu dla podanych identyfikatorów, relacje leksykalne i semantyczne oraz przykłady użycia słów należących do synsetu. Podział tych czynności na różne skrypty pozwala na wyświetlenie użytkownikowi części danych niemal natychmiast, a doładowanie kolejnych danych później. Dzięki temu użytkownik nie jest irytowany długim czasem oczekiwania na dane (tak jak było to w wersji 0.2 mojego projektu, dostępnej w repozytorium). Warto zaznaczyć, że stworzone przeze mnie skrypty mają bardzo podobną budowę. Przyjmują wysłane w żądaniu parametry(np. identyfikator synsetu, którego szczegółowe dane chcemy uzyskać). Parametry przekazywane są metodą GET, czyli przez umieszczenie danych w adresie żądania. Następnie skrypty pobierają(i ewentualnie przetwarzają) dane z bazy danych używając PDO. Wszystkie dane zapisywane są w jednej tablicy, która następnie jest zwracana przez skrypt po przejściu przez funkcję 26
json_encode(). Dzięki temu zwróconą tablicę asocjacyjną będzie można w JavaScript odczytać jako obiekt JSON(JavaScript Object Notation), czyli zwykły obiekt JavaScript. Natomiast zwykła(numerowana) tablica zostanie zwrócona w niezmienionej formie. Listing 2. Pobieranie podpowiedzi słów przy użyciu PDO. Na listingu (Listing 2.) przedstawiłem sposób pobierania danych przy pomocy PDO. Jest to część skryptu, który dostarcza podpowiedzi słów użytkownikowi. Jak widać stworzony przeze mnie skrypt umożliwia zwrócenie pięciu wartości, które zaczynają się od wpisanej frazy (używając operatora LIKE). Jest to dobre rozwiązanie dla prostych podpowiedzi wyświetlanych pod polem do wpisywania danych. Oczywiście takie rozwiązanie generuje bardzo ograniczoną funkcjonalność, ale w innym przypadku problemem byłby czas pobierania danych. W przypadku chęci sporządzenia pełnej listy słów, które są podobne do wpisanego można użyć odległości Levenshteina [29]. Odległość ta to najmniejsza liczba działań wstawienia, usunięcia i zamiany znaku, która pozwala przekształcić jeden wyraz w drugi. Inną możliwością ulepszenia tego algorytmu podpowiedzi jest zamiana wpisanego wyrazu na najprostszą formę(zwaną lemmą). Ten proces zwany lematyzacją jest przydatny, ponieważ WordNet zawiera tylko podstawowe formy słów. Przykładowo słowniku jest słowo car natomiast nie ma słowa cars. W celu rozwiązania tego problemu można zastosować przytaczaną już przeze mnie bibliotekę NLTK dla języka Python. Do uzyskania żądanego efektu wystarczą trzy linijki kodu (Listing 3.). Obecnie nie użyłem tego rozwiązania w swoim projekcie(głównie z powodu konieczności użycia języka Python na serwerze PHP, co wymagałoby dużo konfiguracji). Dobrym pomysłem na przyszłość byłaby próba najpierw znalezienia słowa w bazie WordNet, a dopiero w przypadku jego nie znalezienia wykonanie procesu lematyzacji i ponowne sprawdzenie bazy WordNet. W ten sposób, gdy użytkownik wpisze poprawne słowo, nie byłyby generowane dodatkowe opóźnienia. 27
Listing 3. Użycie biblioteki NLTK w celu zwrócenia podstawowej formy słowa. 5.2. Dynamiczne pobieranie treści technologia AJAX AJAX, czyli Asynchronous JavaScript and XML [30] pozwala na wymianę danych między stroną WWW, a serwerem. Operacje wykonywane są w tle, a przeładowanie strony nie jest konieczne. Dzięki temu strona zachowuje się jak normalny program (budowę tego typu aplikacji opisałem w rozdziale 4). Mimo tego co sugeruje nazwa, komunikacja asynchroniczna nie jest jedyną możliwością AJAX. Tak samo XML nie jest jedynym formatem przesyłanych danych. Dane często są przesyłane w postaci zwykłego tekstu albo formatu JSON, odpowiadającemu obiektowi JavaScript. Funkcje AJAX są dostępne bezpośrednio w JavaScript. W celu wysyłania prostego żądania HTTP z JavaScript, tworzy się obiekt XMLHttpRequest i przypisuje mu funkcje, która zostanie wykonana przy zmianie stanu żądania. Funkcja taka powinna sprawdzać parametr readystate obiektu XMLHttpRequest, w celu stwierdzenia czy dane zostały już pobrane oraz parametr status, który może informować o błędzie. Wysłanie żądania nie jest trudne, jednak występują różnice w implementacji XMLHttpRequest na różnych przeglądarkach. Szczególnie w przeglądarce Internet Explorer poniżej wersji 7, gdzie XMLHttpRequest jest obiektem ActiveX. Problem można rozwiązać używając biblioteki jquery. W ten sposób nie tylko uzyskamy kod działający tak samo na większości przeglądarek, ale również uprościmy nieco proces tworzenia zapytania. Biblioteki jquery używam niemal w całym programie. W tym rozdziale skupię się na użyciu jej do tworzenia żądań HTTP. jquery udostępnia wiele metod poświęconym technologii AJAX. Ja w projekcie używam metody getjson. Metoda ta pobiera obiekt typu JSON z pomocą żądania HTTP typu GET. Listing 4. Użycie metody getjson do pobrania informacji na temat synsetu. 28
Za każdym razem przechowuje obiekt XMLHttpRequest w globalnej zmiennej. Dzięki temu użytkownik może przerwać wykonanie żądania, gdy się na to zdecyduje. Operator $ służy do odwołania się do metody biblioteki jquery. Pierwszym parametrem metody getjson jest ścieżka do skryptu PHP, który pobiera dane z bazy SQLite. Kolejnym parametrem jest obiekt, który zostanie przekazanych jako parametr. Parametry GET będą dostępne w PHP dzięki zmiennej superglobalnej($_get). Po poprawnym wykonaniu żądania zostanie wykonana metoda zawarta w trzecim parametrze funkcji getjson. Metoda ta powinna zawierać parametr data, który będzie zawierał pobrane dane. W moim programie nie pobieram wszystkich danych w jednym żądaniu. Po wykonaniu jednego żądania, sprawdzeniu danych i przypisaniu danych do struktur, program generuje kolejne żądanie. W przypadku błędu w żądaniu, kolejne żądanie nie zostanie wywołane. Kod przedstawiony na listingu (Listing 5.) pozwala przerwać obecny łańcuch żądań, zanim rozpocznie się nowy. Taka sytuacja może wystąpić, gdy użytkownik wymusi nową wizualizację, gdy dane poprzedniej nie są jeszcze całkowicie załadowane. Bez tego prostego kodu mielibyśmy do czynienia z trudnymi do przewidzenia błędami. Listing 5. Zatrzymanie żądania Dane są pobierane zawsze w ustalonej kolejności. Szczegółowy schemat pobierania danych moim programie przedstawia schemat (Rys.8.). W przyszłości dobrym pomysłem byłoby napisanie jednego głównego obiektu, który nadzorowałby wykonanie wszystkich żądań i podejmował decyzje w przypadku błędów. 29
Rys.8. Schemat pobierania danych z pomocą technologii AJAX podzielony na konkretne etapy. 30
6. Struktury przechowujące dane 6.1. JavaScript jako język zorientowany obiektowo JavaScript jest językiem zorientowanym obiektowo [31, 32]. Warto zauważyć, że w języku tym nie ma klas, są tylko obiekty. Tworzenie własnego obiektu można zacząć od utworzenia pustego obiektu i dodania do niego odpowiednich właściwości. Obiekt to zbiór nazwanych właściwości. Stanowi on listę par klucz-wartość. Właściwości obiektu, które są funkcjami nazywamy metodami. Warto wspomnieć, że w JavaScript również funkcja jest obiektem i może mieć właściwości. Przyzwyczajenie się do braku klas dla programisty używającego wcześniej języków obiektowych takich jak Java czy C# może wymagać czasu, jednak brak klas czyni programy krótszymi. Istnieją również pewne konstrukcje przypominające schemat tworzenia klasy. Obiekty mogą być tworzone za pomocą funkcji konstruujących, w których będą zdefiniowane pola i metody. Na poniższym przykładzie konstruktorem jest funkcja Node (Listing 6.). Listing 7. Tworzenie obiektu przy pomocy konstruktora. Taki sposób tworzenia obiektów używam również w mojej aplikacji. JavaScript umożliwia dużą dowolność programowania. Istnieje wiele sposób realizacji zadań związanych z obiektowością. Przykładowo JavaScript używa obiektu zwanego prototypem w celu implementacji dziedziczenia. Do obiektu prototypu będącego właściwością konstruktora, dodaje się pola obiektu rodzica. Właściwości należące do prototypu zostaną dodane do tworzonego przy pomocy konstruktora obiektu i będzie można z nich korzystać. Nic nie stoi jednak na przeszkodzie, aby zrealizować dziedziczenie w inny sposób (na przykład poprzez proste kopiowanie właściwości). W tym podrozdziale chciałem 31
przedstawić podstawowe cechy JavaScript jako języka obiektowego, których używam do tworzenia struktur danych w moim programie. 6.2. Struktury danych przechowujące dane do wizualizacji Do przechowywania danych pobranych z bazy oraz implementacji fizyki używam zestawu stworzonych obiektów. Obiektem pomocniczym, który jest wykorzystywany do implementacji fizyki jest pvector. Obiekt ten jest dwuwymiarowym wektorem. Pozwala na wykonywanie podstawowych operacji matematycznych między dwoma wektorami lub wektorem i stałą, a także umożliwia policzenie długości wektora, jego normalizacji czy negacji. Dzięki istnieniu obiektów tego typu kod algorytmu rozkładu będzie łatwiejszy do zrozumienia. Obiekt typu Node (Rys.9.), czyli po prostu dowolny węzeł grafu stanowi punkt materialny dla algorytmu rozkładu grafu opartego na siłach. Posiada położenie, które może ulec zmianie podczas wykonywania metody Eulera. Metoda Eulera jest metodą rozwiązywania równania różniczkowego na podstawie jego interpretacji geometrycznej. W celu uzyskania nowej wartości położenia, obiekt reprezentujący węzeł przechowuje wypadkową sił działających na węzeł oraz obecną prędkość. Oprócz danych fizycznych obiekt węzła musi zawierać listę swoich dzieci oraz węzłów, z którymi połączony jest relacją. Ważnym polem obiektu jest pole typu, które definiuje jakiego rodzaju węzłem jest obiekt. Natomiast pole hang pozwala stwierdzić czy obiekt ma brać udział w algorytmie rozkładu. Jeśli węzeł jest korzeniem lub jest przemieszczany przez użytkownika, wtedy pole ma wartość 1, a algorytm rozkładu nie zmienia położenia węzła. Istnieje również pole, które pozwala nie wyświetlać odpowiednio oznaczonego węzła, co przydaje się podczas filtrowania danych. 32
Node id hang type vposition vvelocity vtension mass datatype isshowed childs[] relation[] relationids[] addchild(node) addrelation(node,relation,linktype) addforce(vforce) coulombrepulsion() solveeuler() ishavechild(node) Rys.9. Schemat zawartości obiektu Node. Ponieważ istnieje parę typów węzłów(korzeń, lemma, synset), to dla każdego z nich zdefiniowałem osobny konstruktor obiektu. Użyłem dziedziczenia prototypowego, aby te obiekty miały dostęp do metod i pól zdefiniowanych w obiekcie Node. Oczywiście nadpisują one niektóre pola rodzica odpowiednimi dla siebie wartościami(pola hang i type). Definiują również zestaw własnych danych. Dla synsetu będzie to na przykład definicja, domena leksykalna, przykład użycia oraz część mowy. Dzięki istnieniu takich szczegółowych obiektów nie trzeba przypisywać tych szczególnych właściwości węzłowi w momencie tworzenia grafu. W swoim programie do połączenia powiązanych ze sobą węzłów używam sprężyn. Konstruktor Spring (Rys.10.) przyjmuje w parametrach dwa obiekty węzłów. Obiekt sprężyny będzie posiadał referencje do tych obiektów. Będzie również zawierał informacje jakimi relacjami są one połączone. Sprężyna posiada ustaloną długość oraz współczynnik sprężystości. Wartości te przydzielane są na podstawie opcji ustalonych w programie. Obiekt sprężyny bierze udział w algorytmie rozkładu grafu. 33
Spring node1 node2 springiness springlength linktype[] solvespring() halfpoint() Rys.10. Schemat zawartości obiektu Spring Obiektem zbiorczym przechowującym odwołanie do wszystkich węzłów oraz sprężyn jest obiekt Director (Rys.11.). W programie istnieje tylko jedna instancja takiego obiektu. Zawiera on tablice nodes oraz springs oraz umożliwia szereg operacji na nich. Do tych operacji należą na przykład znalezienie węzła o konkretnych właściwościach, zsumowanie węzłów spełniających przyjęty warunek czy pobranie listy nieukrytych obiektów połączonych z węzłem przekazanym w parametrze. Director przechowuje również odwołanie na korzeń, czyli słowo wpisane przez użytkownika. Istnienie obiektu przechowującego wszystkie dane w postaci list(a nie struktur hierarchicznych) ułatwia stworzenie niektórych algorytmów. Utworzenie takiego zbiorczego obiektu jest lepszym rozwiązaniem niż przechowywanie zawartych w nim danych w przestrzeni globalnej. Director nodes[] springs[] root addnode(node) addspring(node1,node2, getdetailednode(type, id) getdetailedspring(node1,node2) listofleftconnections(rightnode) countactiveleftconnections(rightnode) Rys. 11. Schemat zawartości obiektu Director Również opcje algorytmu rozkładu przechowywane są w jednym obiekcie. Istnieją dwie instancje stworzone przy pomocy konstruktora AlgorithmOptions. Jeden obiekt przechowuje bieżącą konfigurację, a drugi domyślną. W razie czego na podstawie tego drugiego obiektu można przywrócić początkowe ustawienia programu. 34
7. Wizualizacja elementów na grafie 7.1. Algorytm rozkładu grafu na bazie sił skierowanych Graf to zbiór wierzchołków, które mogą być połączone skierowanymi lub nieskierowanymi krawędziami, w taki sposób, że każda krawędź zaczyna się w jednym z wierzchołków. W stworzonej przeze mnie aplikacji przedstawiam pobrane z WordNet dane za pomocą tej struktury. W przypadku takiej wizualizacji ważnym problemem jest rozłożenie wierzchołków grafu. Istnieje wiele metod rozkładu grafu. Jedną z grup takich metod są metody sił skierowanych [33]. Metody tego typu traktują graf jako zbiór obiektów, które oddziałują na siebie wybranymi siłami. Analogia do układu fizycznego czyni takie algorytmy prostymi do zrozumienia. Teoretycznym celem algorytmu jest znalezienie takich pozycji dla węzłów, aby suma sił działających na każdy węzeł była równa zero. Dzięki temu graf powinien być czytelnie rozłożony, węzły nie powinny na siebie nachodzić. Czas uzyskania wynikowej pozycji jest w algorytmach tego typu zwykle dość długi(można go wyrazić w potrzebnej ilości iteracji). Tego typu metody składają się zwykle z dwóch elementów: Systemu ciał o ustalonych właściwościach fizycznych Algorytmu, który poszukuje pozycji wynikowej Jedną z łatwiejszych i bardziej popularnych metod opartych na siłach skierowanych jest metoda używająca sprężyn (prawo Hooke a) oraz sił elektrycznych [33]. Algorytm opiera się na dwóch założeniach: Węzły wchodzące ze sobą w relacje są połączone sprężynami. Algorytm wykorzystuje tu prawo Hooke a. Sprężyny mają ustaloną długość, do której dążą. Sumę sił wynikających z połączeń sprężyną dla składowej x, węzła v przedstawia wzór (1). k (1) (d(p, p ) l ) x x v u uv u v uv (u,v) E d(p u, p v ) (1) 35