Masarykova univerzita Fakulta}w¡¢£¤¥¦§¨  informatiky !"#$%&'()+,-./012345

Portlet pro 3D vizualizaci časových řad

Diplomová práce

Bc. Petr Jelínek

Brno, Jaro 2014 Prohlášení

Prohlašuji, že tato diplomová práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a li- teraturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.

Bc. Petr Jelínek

Vedoucí práce: RNDr. Radek Ošlejšek, Ph.D.

ii Poděkování

Na tomto místě bych rád poděkoval vedoucímu práce RNDr. Radku Ošlejšekovi, Ph.D. a celému vizualizačnímu týmu projektu Kyberne- tický polygon za cenné rady a příjemný pracovní kolektiv. Děkuji i li- dem v mém nejbližším okolí za pomoc při vypracování textové části a trpělivost při ukázkách grafického výstupu této práce.

iii Shrnutí

Diplomová práce popisuje možnosti zobrazení prostorové grafiky přímo v internetovém prohlížeči pomocí WebGL s využitím knihovny Three.js. Dále popisuje implementaci portletu pro 3D vizualizaci pro Liferay portál v rámci projektu Kybernetický polygon. Výsledná apli- kace se aktivně využívá a bude na ní navazováno v dalších diplomových pracích.

iv Klíčová slova

3D grafika, interaktivní grafika, WebGL, Three.js, JavaScript, port- let, Liferay portál

v Obsah

1 Úvod3

2 Projekt Kybernetický polygon4 2.1 Architektura Kybernetického polygonu...... 4 2.2 Bezpečnostní scénáře...... 6 2.3 Simulace infrastruktury...... 7 2.3.1 Požadavky na infrastrukturu...... 7 2.3.2 Navržené řešení...... 7 2.4 Měření a analýza provozu ...... 8 2.4.1 Části měřící infrastruktury...... 8 2.5 Vizualizace ...... 9

3 WebGL 10 3.1 Podpora WebGL v prohlížečích ...... 11 3.2 Ukázka přímé práce s WebGL...... 12 3.2.1 Canvas element a vykreslovací kontext ...... 12 3.2.2 Nastavení hranice vykreslování...... 13 3.2.3 Vykreslovací data...... 14 3.2.4 Transformační matice...... 15 3.2.5 Implementace shaderu ...... 16 3.2.6 Vykreslení...... 18 3.3 JavaScriptové knihovny...... 19

4 Knihovna Three.js 20 4.1 Jednoduchá stránka...... 21 4.1.1 Černý čtverec...... 21 4.1.2 Rotující krychle se stínem a texturou ...... 23 4.2 Kamery ...... 25 4.2.1 Perspektivní kamera ...... 25 4.2.2 Ortografická kamera ...... 27 4.3 Geometrie...... 28 4.3.1 Předdefinované geometrie ...... 28 4.3.2 Tvorba vlastní geometrie...... 30 4.4 Materiály ...... 32 4.5 Světla ...... 34

1 4.6 Shrnutí kapitoly...... 35

5 Implementace vizualizace 36 5.1 Vizuální návrh ...... 36 5.2 Návrh zdrojového kódu...... 38 5.2.1 Struktura souborů zdrojových kódů ...... 41 5.2.2 Zprovoznění aplikace...... 42 5.3 Vybrané implementační detaily ...... 42 5.3.1 Obarvování povrchu vizualizace...... 43 5.3.2 Přizpůsobení vstupních dat ...... 44 5.4 JavaScriptové postupy použité v aplikaci...... 45 5.4.1 Definice tříd...... 45 5.4.2 Definice vlastností ...... 46 5.4.3 Callback funkce...... 47 5.4.4 Jmenné konvence...... 47 5.5 Vytvoření portletu pro Liferay portál...... 47

6 Závěr 49

Seznam obrázků 50

Seznam zdrojových kódů 51

Seznam použité literatury 52

A Ukázky WebGL aplikácí 53 A.1 Zygote body...... 53 A.2 Wannaplan ...... 54 A.3 Chrome World Wide Maze...... 54

B Virtualizační portlety 55

C Dokumentace 57

2 1 Úvod

Vlivem pokroku informačních technologií stále roste množství dat, která mohou být bez dalšího zpracování nepřehledná. Vizualizace těchto dat umožňuje rychle a efektivně získávat požadované informace. Pro- jekt Kybernetický polygon produkuje data z různých měření nad si- mulovanou počítačovou sítí, kde se provádí bezpečnostní experimenty. Právě díky vizualizaci získaných hodnot jsou výsledky měření přehledné a snadno tak dále zpracovatelné. Cílem této práce je vytvořit prostorovou vizualizaci, která dokáže zobrazovat časové řady získané v rámci experimentů projektu Kyber- netický polygon. Vizualizace musí umožňovat přímou 3D interakci (ro- tace, přibližování apod.) a další funkcionalitu dle potřeb projektu. Dále dle zadaných požadavků je cílem práce vytvořit vizualizaci v podobě portletu pro Liferay portál. Pro zobrazování musí být použita technologie WebGL, která umožňuje vykreslovat hardwarově akcelero- vanou prostorovou grafiku v prostředí webového prohlížeče bez nutnosti instalovat rozšíření. Portlet s vizualizací se musí také synchronizovat s ostatními portlety na stejné stránce tak, aby všechny vizualizace zob- razovaly stejná data.

3 2 Projekt Kybernetický polygon

Jedním z důležitých cílů a závazků České republiky je zajistit ky- bernetickou bezpečnost. To má za úkol Národní bezpečnostní úřad, rezort Ministerstva vnitra a bezpečnostní týmy (vládní CERT1 a ná- rodní CSIRT2). Při plnění tohoto úkolu vznikají potřeby, na které svým řešením reaguje projekt Kybernetický polygon (KYPO). Cílem navrhovaného Kybernetického polygonu je vznik prostředí pro vývoj a výzkum metod, které budou sloužit jako ochrana proti ky- bernetickým útokům. Metodou dosažení tohoto cíle je provádět kom- plexní kybernetické útoky na reálné síťové infrastruktuře ve virtualizo- vaném prostředí cloudu3. Jednotlivé útoky pak bude možné analyzovat a vyhodnocovat, a to jak v samotném průběhu, tak i po jejich skon- čení. Vytvořené prostředí může dále sloužit pro vývoj bezpečnostních nástrojů a pro školení ze strany bezpečnostních týmů. V současné době dostupná řešení mají dle provedených pozorování a porovnání jistá omezení snižující jejich použitelnost, která brání uspo- kojivě řešit problematiku předloženou v požadavcích kladených na pro- jekt KYPO. V následujících kapitolách je probrána architektura Kybernetického polygonu, podrobněji je popsána v technické zprávě viz [1].

2.1 Architektura Kybernetického polygonu

Ve své podstatě je KYPO fyzická síť simulovaná v cloudovém pro- středí, kde se simuluje síťový provoz včetně kybernetických útoků. Tento provoz a další projevy sítě a uzlů se poté měří a následně analyzují a vi- zualizují.

1. Bezpečnostní tým, do jehož kompetence spadají sítě státní správy, samosprávy a kritické infrastruktury ČR. 2. Bezpečnostní tým pro koordinaci řešení bezpečnostních incidentů v počítačo- vých sítích provozovaných v České republice. Tento tým aktuálně provozuje správce české národní domény, sdružení CZ.NIC. 3. Obecně se jedná o poskytování služeb či programů, které běží na vzdálených serverech a uživatelé se k nim mohou připojovat např. pomocí webového prohlížeče.

4 2. Projekt Kybernetický polygon Architektura Kybernetického polygonu se skládá ze čtyř modulů, přičemž každý představuje jednotlivou funkční část polygonu. Graficky tuto architekturu znázorňuje obrázek 2.1. Moduly řeší své přidělené okruhy problémů a komunikují spolu zasíláním zpráv.

• Správa scénářů je hlavní a řídicí modul polygonu. Jeho úkolem je vytvářet a spravovat celkovou konfiguraci a příslušné části pak předávat dalším modulům k implementaci.

• Správa cloudu vytváří a zabezpečuje správu cloudového pro- středí. Podle konfigurace síťové topologie zapíná a vypíná virtu- ální stroje a vytváří mezi nimi síťovou infrastrukturu.

• Správa měření je modul pro řízení měřící infrastruktury, který má za úkol nastavovat a spouštět měření.

• Správa vizualizace zajišťuje grafickou prezentaci síťové topo- logie a vizualizaci dat, které předává správa měření.

Scénář 1 LAN 1 Scénář

.... Správa LMN 1 .... scenáře Konfigurace Routing 2 LMN scénáře Node Zpracování LMN n dat

Vstupní portál Uzel správy scénáře LAN 2

... LAN n

Vizualizace Scénář n

Uzel správy scénáře

Databáze Simulace & Měření

Obrázek 2.1: Architektura Kybernetického polygonu [1]

5 2. Projekt Kybernetický polygon Následující podkapitoly se věnují podrobnějšímu popisu jednotli- vých modulů. Správou scénářů se zabývá podkapitola 2.2, správu cloudu popisuje podkapitola 2.3, správou měření se zabývá podkapitola 2.4 a správu vizualizace popisuje podkapitola 2.5.

2.2 Bezpečnostní scénáře

Hlavní podstata bezpečnostního scénáře je popsat konfiguraci sítě a uzlů (hardwarová a softwarová výbava, propustnost sítě atd.) a popsat průběh bezpečnostního experimentu. Scénář se proto skládá z následu- jících částí:

Popisná část obsahuje vysvětlení celého scénáře.

Varianta scénáře popisuje odchylky scénáře se zachováním popisu a hlavního cíle. Variantou může být např. změna umístění měřících prvků.

Technická část obsahuje informace pro realizaci a skládá se z těchto dalších částí:

• Konfigurace uzlů popisuje vlastnosti a konfigurace všech zaří- zení, které jsou zapojeny do scénáře.

• Síťová topologie definuje rozložení uzlů v počítačové síti a její konfiguraci.

• Logická topologie říká, který uzel má jakou roli (oběť, útočník atd.) a v jakém časovém okamžiku se která role aktivuje. Uzel může zastávat v jeden okamžik pouze jednu roli. Dále se po- mocí logické topologie rozdělují uzly do skupin představujících organizace.

• Konfigurace měřící infrastruktury definuje vlastní měřící uzly, jejich typ a umístění.

6 2. Projekt Kybernetický polygon 2.3 Simulace infrastruktury

Pro simulaci bezpečnostního scénáře je nutné prostředí, ve kterém lze s daným scénářem dále pracovat a produkovat tak monitorovací data. Několik takových prostředí již existuje, ale každé má jistá ome- zení, např. projekt Emulab má možnost využívat pouze protokol IPv4 a má omezení na operační systém a hardware. Další projekty jako ViSe a LVC jsou zase spustitelné jen na platformě VMware.

2.3.1 Požadavky na infrastrukturu

Bezpodmínečný požadavek na síť je možnost simulovat libovolnou síťovou topologii. Tento požadavek zahrnuje jak jeden stroj s jakýmkoli běžným operačním systémem, tak i třeba propojení několika sítí. Po- třebná vlastnost, která ve většině infrastruktur není dostupná, je plná kontrola nad třetí síťovou vrstvou ISO/OSI modelu4 (L3). Nutné je také podporovat modifikaci charakteristik sítě, aby se dala simulovat síť typu ADSL nebo mobilní sítě. Samozřejmostí pak je po- skytování monitorovacích dat, samotné monitorování nesmí být dete- kovatelné a nesmí ovlivňovat výsledná data. Infrastruktura musí být přenositelná mezi různými poskytovateli cloudů, nesmí tedy vyžadovat žádné speciální vlastnosti konkrétních cloudových prostředí.

2.3.2 Navržené řešení

Každý bezpečnostní scénář je v cloudu spouštěn v uzavřeném pro- středí, útoky tak neovlivňují zbytek infrastruktury a mohou byt spouš- těny paralelně na libovolném počtu virtuálních prostředí. Aby infrastruktura nebyla závislá na vybraném cloudovém prostředí, nebyla použita žádná speciální funkce, kterou toto prostředí nabízí pro danou vrstvu. Vytvořil se koncept LAN Management Node (LMN), který zajišťuje abstrakci LAN sítě, díky které je možné budovat linky s volitelnými vlastnostmi s možností kompletního monitoringu. LMN

4. Jedná se o referenční model, který popisuje všeobecné principy (funkce, služby) sedmivrstvé síťové architektury.

7 2. Projekt Kybernetický polygon je spojen s virtuálními stroji na úrovni sítě L25, to umožňuje uživateli mít pod kontrolou celou síťovou vrstvu L36. KYPO ke každému scénáři vytváří i tzv. řídicí síť, která je určena pro komunikaci s LMN a ostatními důležitými uzly. Využívá se i pro přenos monitorovacích dat, aby nebyl ovlivněn datový tok měřené linky.

2.4 Měření a analýza provozu

Měřící infrastrukturu tvoří nástroje získávající relevantní data z po- lygonu pro další zpracování. Tyto nástroje se dají rozdělit na infrastruk- turu sítě a infrastrukturu stanic. První jmenovaná slouží výhradně na monitorování provozu sítě, zatímco infrastruktura stanic slouží na mě- ření provozu a stavu virtuálních zařízení. Data získaná měřící infrastrukturou je potřeba dále zpracovat a ana- lyzovat k získání požadovaných informací.

2.4.1 Části měřící infrastruktury

Monitorování síťových toků je založeno na agregaci informací ze zá- hlaví jednotlivých paketů v síti. Detailnější informace je pak možné získat hloubkovou analýzou paketů. Měřící infrastruktura pro monito- rování toků se skládá z následujících částí:

• Pozorovací bod je místo, kde se monitoruje síťový provoz, např. port nebo skupina portů směrovače.

• Měřící sonda je zařízení, které nepřetržitě monitoruje provoz v pozorovacím bodě za účelem získání požadovaných informací. Data jsou přeposílána na kolektor nebo ukládána přímo v sondě.

• Kolektor přijímá a dále zpracovává data od měřících sond. Hlavní funkcí je agregace a uložení těchto dat.

5. Poskytuje komunikaci mezi dvěma sousedními prvky sítě. 6. Slouží ke směrování a adresování. Poskytuje komunikaci mezi prvky, které spolu nesousedí.

8 2. Projekt Kybernetický polygon Monitorováním zařízení pomocí infrastruktury stanic je možné zís- kat např. využití procesoru, paměti nebo disku. Tato infrastruktura se dělí do dvou částí:

• Podřízený uzel je proces běžící přímo na monitorovaném zaří- zení. Získané informace o jeho stavu dále předává ke zpracování hlavnímu uzlu.

• Hlavní uzel je proces, který má za úkol řídit podřízené uzly a získávat od nich informace, ty poté vyhodnocuje a ukládá. Umí také upozornit na některé ze sledovaných událostí.

2.5 Vizualizace

Modul vizualizace poskytuje uživatelům možnost rychle a přehledně sledovat a vyhodnocovat bezpečnostní scénáře, a to díky několika vizu- alizacím, kde každá se specializuje na danou problematiku. Aktuálně jsou v modulu zahrnuty čtyři druhy vizualizací. Vizualizace topologie zobrazuje síťovou a logickou topologii. Po- mocí animací také znázorňuje toky na jednotlivých linkách. Hvězdicový graf má za úkol zobrazovat hodnoty vybraných měře- ných informací v jednom daném časovém okamžiku. V anglickém jazyce je vizualizace označována jako spider chart nebo radar chart. Sekvenční hvězdicový graf je trojrozměrná varianta hvězdicového grafu, zobrazuje více časových okamžiků formou prostorového objektu. Tato vizualizace je cílem této práce a detailněji je popsána v kapitole5. Spojnicový graf zobrazuje vždy jen jednu měřenou informaci v po- žadovaném časovém rozsahu. Na stránce je zobrazen větší počet těchto grafů v závislosti na počtu vybraných měřených informací.

Modul je postaven na webových technologiích a portálu Liferay (viz kapitola 5.5), díky tomu je celá aplikace modulární a spustitelná za pomocí moderního webového prohlížeče bez dalších doplňků. Ukázky jednotlivých vizualizací jsou v přílozeB.

9 3 WebGL

Oblast implementace interaktivní grafiky se stále vyvíjí, to je za- příčiněno zejména širokou škálou operačních systémů a zařízení, které mohou danou grafiku zobrazovat. Základním stavebním kamenem se stal OpenGL, již dlouhou dobu uznávaný standard [4]. Byl vyvinut koncem osmdesátých let a za tu dobu, co odolává konkurenčnímu Di- rectX od Microsoftu, se z něj stal nesporný standard pro programování 3D grafiky. Všechny implementace OpenGL ale nejsou stejné, kvůli různorodo- sti všech možných platforem, jako jsou osobní počítače, mobilní tele- fony, tablety, televizní set-top boxy, musely být vyvinuty různé verze OpenGL. OpenGL ES je verze pro běh na malých zařízeních, jako jsou např. mobilní telefony. Tento standard se stal také ideálním jádrem pro WebGL, je malé a díky tomu lehce konzistentně implementovatelné ve všech prohlížečích. Aplikace napsané pro jeden prohlížeč tak budou funkční ve všech ostatních prohlížečích podporující WebGL. Více viz [8] a [2]. Největším přínosem WebGL je jistě hardwarová akcelerace, tedy o samotné vykreslování prostorové grafiky se stará přímo grafická karta namísto procesoru, který běžně vykonává skripty obsažené na webové stránce. To vše navíc bez jakékoli instalace dodatečných rozšíření do prohlížeče. Ve spojení s dalšími technologiemi z rodiny HTML5, jako jsou např. Web Workers1 nebo Web Socket2, se webový prohlížeč stává platformou pro rozsáhlejší aplikace než jen webová prezentace. Všechny tři výše zmíněné grafické standardy (WebGL, OpenGL, OpenGL ES) jsou vyvíjeny a spravovány neziskovým konsorciem Khro- nos Group [5]. Jejich hlavním cílem je vytvářet otevřené standardy pro paralelní výpočty, grafiku a digitální média pro širokou škálu platforem a zařízení.

V této kapitole bude dále rozebrána podpora v prohlížečích a ukázka práce přímo s knihovnou. Nakonec bude popsáno několik základních

1. Javascript běžící na pozadí v odděleném vlákně, nemá tak vliv na výkon hlav- ního vlákna. 2. Protokol pro obousměrnou komunikaci pomocí TCP spojení. 10 3. WebGL knihoven pro usnadnění práce s WebGL. V přílozeA jsou vybrané ukázky aplikací pro demonstraci možností této technologie.

3.1 Podpora WebGL v prohlížečích

V dnešní době podporují WebGL všechny hlavní webové prohlížeče, některé mají ale různá omezení. Mezi mobilními prohlížeči se najdou takové, které již podporují tento standard, ve většině případů je ale potřeba tuto funkcionalitu dodatečně zapnout. Chrome podle [11] podporuje WebGL od verze 8.0 vydané koncem roku 2010, bylo zde však možné omezení, uživatel musel mít aktuální ovladače pro grafickou kartu. Tedy ne vždy knihovna fungovala. Tento problém vyřešila verze 18.0 vydaná v březnu roku 2012, kdy již Chrome podporoval WebGL bez omezení. V případě Opery je v historii [7] uvedeno, že zařadila do svého prohlížeče experimentální podporu akcelerace 3D grafiky od verze 12.0 v červnu roku 2012. O necelý rok později, v květnu 2013, se Opera od základu změnila a začala používat nové vykreslovací jádro a s ním přišla i plná podpora pro WebGL stejně jako u Chrome. Od konce března roku 2011 podporuje WebGL i Firefox ve verzi 4, avšak v závislosti na hardwaru může prohlížeč ve výchozím stavu pod- poru zakázat, týká se to zejména starších grafických karet. Více infor- mací v přehledu verzí na stránkách prohlížeče [6]. Safari podporuje WebGL ve verzi 5.1 vydané v červenci 2011 insta- lovaných na Mac OS X 10.6 a od verze 6.0 na všech novějších verzích Mac OS X. Ve výchozím stavu je podpora vypnuta. Více v rámcovém přehledu [10]. Internet Explorer částečně podporuje WebGL od verze 11 vydané v říjnu 2013. Částečně proto, že neprošel kompletně testem specifikace3 na oficiální stránce Khronos Group. Dle [3] z mobilních prohlížečů podporuje WebGL Opera Mobile ve verzi 16.0 a Blackberry Browser ve verzi 10.0. Android verze prohlížečů Chrome ve verzi 33.0 a Firefox ve verzi 26.0 jsou uvedeny

3. https://www.khronos.org/registry/webgl/sdk/tests/ -conformance-tests.html

11 3. WebGL s částečnou podporou.

3.2 Ukázka přímé práce s WebGL

Ve své podstatě je WebGL jen vykreslovací knihovna, ale posílená grafickým hardwarem. Pro vykreslení 3D grafiky do webového prohlí- žeče využívá HTML5 canvas element, který slouží pro přímé vykreslo- vání jednoduché grafiky pomocí JavaScriptu. Tento element má několik metod pro vykreslování textů, kruhů, čtverců, čar a přidávání obrázků. Pro vykreslení WebGL do webové stránky musí aplikace splnit ale- spoň následující kroky:

1. Vytvořit canvas element. 2. Získat vykreslovací kontext pro canvas element. 3. Nastavit viewport (hranice vykreslování). 4. Předat alespoň jedna data k vykreslení (typicky vrcholy). 5. Definovat alespoň jednu matici pro transformaci vrcholů na pro- stor obrazovky. 6. Napsat alespoň jeden shader implementující algoritmus pro vy- kreslování. 7. Spustit shader s parametry. 8. Vykreslit.

V této podkapitole bude postupně popsán každý výše zmíněný bod s ukázkou kódu. Podrobněji je vše popsáno v [8].

3.2.1 Canvas element a vykreslovací kontext

Vykreslování probíhá v kontextu, který je nejprve potřeba získat. K tomu poslouží JavaScript a HTML DOM (Document Object Model), což je objektový model stránky, kde jsou HTML elementy reprezento- vány objekty.

12 3. WebGL Pro získání objektu canvas elementu stačí zavolat metodu document.getEelementById(id), kde id je id atribut požadova- ného elementu. Předáním získaného objektu do funkce v ukázce 3.1, pak získáme WebGL kontext, což je objekt poskytující kompletní WebGL rozhraní (API). Při získávání kontextu je důležité ověřit, zda je to v daném pro- středí možné. Některé prohlížeče nemusí podporovat WebGL (viz kapi- tola 3.1). V ukázce 3.1 je ověření řešeno blokem try/catch a vyho- zením chybové hlášky.

1 function initWebGL(canvas){ 2 var gl; 3 try 4 { 5 gl= canvas.getContext("webgl"); 6 } 7 catch (e) 8 { 9 var msg="Error creating WebGL Context!"+ 10 e.toString(); 11 alert(msg); 12 throw Error(msg); 13 } 14 return gl; 15 } Zdrojový kód 3.1: Získání WebGL kontextu

3.2.2 Nastavení hranice vykreslování

Po úspěšném získání WebGL kreslícího kontextu je potřeba nastavit čtvercovou hranici pro vykreslování. Ve WebGL se tato hranice nazývá viewport. Pro nastavení stačí v kontextu získaného z ukázky 3.1 zavolat metodu viewport() a předat ji požadované rozměry.

1 function initViewport(gl, canvas){ 2 gl.viewport(0, 0, canvas.width, canvas.height); 3 } Zdrojový kód 3.2: Nastavení hranice vykreslování

13 3. WebGL Kód v ukázkce 3.2 popisuje nastavení viewport kontextu, který po- kryje celou zobrazovací plochu canvas elementu. První dva parame- try funkce viewport() nastavují začátek čtverce, další dva pak šířku a výšku.

3.2.3 Vykreslovací data

Vykreslování ve WebGL je provedeno pomocí primitivních typů, jsou to objekty jako triangle sets (kolekce trojúhelníků), triangle strips4, body a čáry.

1 function createSquare(gl){ 2 var vertexBuffer; 3 vertexBuffer= gl.createBuffer(); 4 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 5 var verts=[ 6 .5, .5, 0.0, 7 -.5, .5, 0.0, 8 .5, -.5, 0.0, 9 -.5, -.5, 0.0 10 ]; 11 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), 12 gl.STATIC_DRAW); 13 var square={buffer:vertexBuffer, vertSize:3, nVerts:4, 14 primtype:gl.TRIANGLE_STRIP}; 15 return square; 16 } Zdrojový kód 3.3: Vytvoření dat pro vykreslení

Jak je vidět v ukázce 3.3, která popisuje funkci pro vytvoření dat čtverce, výsledek je JavaScriptový objekt obsahující buffer, počet hod- not pro jeden vrchol, počet vrcholů a typ primitiva, který se použije pro vykreslení. V této ukázce je délka vrcholu tři, což pokrývá všechny osy trojrozměrného prostoru a jako primitivum je použit triangle strip.

4. Několik propojených trojúhelníků, které sdílejí stejné vrcholy pro efektivnější využití paměti. První trojúhelník je vykreslený celý a každý další se pak vykreslí přidáním jednoho bodu.

14 3. WebGL V ukázce je také použit typ Float32Array5. Je to nový datový typ přidaný do prohlížečů pro použití s WebGL. Pracuje se s ním jako s každým jiným datovým polem, ale je rychlejší a méně náročnější na paměť. Použití je tedy vhodné pro místa s velkým požadavkem na vý- kon.

3.2.4 Transformační matice

Tyto matice slouží k transformaci objektů, která je potřebná pro přípravu scény. Aby bylo možné veškeré grafické operace (rotace, změna měřítka, posun, zkosení atd.) reprezentovat jako násobení matic, bylo nutné zavést další souřadnici tzv. homogenní. Pokud je dána souřadnice P = [X,Y,Z], pak rozšířením o ω vznikne homogenní souřadnice Ph = [ωX, ωY, ωZ, ω]. Je vidět, že ω ovlivňuje všechny ostatní hodnoty, proto se také nazývá jako váha bodu a nejčas- těji je její hodnota rovna jedné. Díky homogenní souřadnici lze trans- formaci vyjádřit pomocí jediné matice. Více o homogenní souřadnici a transformacích viz [9]. Ne vždy je další homogenní rozměr potřebný, transformaci rotace a změnu měřítka lze provést bez dalšího rozměru a tak se do pravého dolního rohu uvádí hodnota 1, tak aby nebyl ovlivněn výsledek. 1 0 0 0 0 cos(α) −sin(α) 0   Transformační matice rotace: R =   0 sin(α) cos(α) 0 0 0 0 1

Pro transformaci posunutí podle vektoru ~p = [Px,Py,Pz], který říká, kterým směrem a jak daleko se má objekt posunout, je již potřeba homogenní rozměr v matici.   1 0 0 Px 0 1 0 P   y Transformační matice posunutí: T =   0 0 1 Pz  0 0 0 1 V ukázce 3.4 je jako první definovaná matice ModelView matrix,

5. https://developer.mozilla.org/en-US/docs/Web/API/ Float32Array 15 3. WebGL která popisuje postavení objektu vzhledem ke kameře. Jedná se tedy o transformaci posunu, ale vzhledem k tomu, že je potřeba posunout pouze z-souřadnici, nepotřebujeme vektor. Posun se provede přidáním hodnoty −3.333 (posune objekt dál od kamery, tak aby byl lépe vidět) na poslední řádek sloupce souřadnice z.

1 function initMatrices() 2 { 3 // ModelView matrix 4 modelViewMatrix= new Float32Array( 5 [1, 0, 0, 0, 6 0, 1, 0, 0, 7 0, 0, 1, 0, 8 0, 0, -3.333, 1]); 9 10 // Projection matrix (45 degree) 11 projectionMatrix= new Float32Array( 12 [2.41421, 0, 0, 0, 13 0, 2.41421, 0, 0, 14 0, 0, -1.002002, -1, 15 0, 0, -0.2002002, 0]); 16 } Zdrojový kód 3.4: Definice transformačních matic

Další transformační matice v ukázce je projection matrix, kterou potřebuje shader k projekci. Obecně je projekce proces zobrazení více- rozměrného objektu do prostoru s méně rozměry. V případě počítačové grafiky se jedná o zobrazení trojrozměrných objektů do rovinné plo- chy. Projekce je tedy nezbytná a je nutné tuto matici definovat. Matice v ukázce definuje 45stupňový prostor z pohledu kamery. Protože na- psat tuto matici není triviální záležitost, používají se různé pomocné knihovny (např. glMatrix viz kapitola 3.3).

3.2.5 Implementace shaderu

Jak již bylo zmíněno, shader je program zabezpečující vykreslování. Pro každý objekt ve WebGL musí být přidělen shader, který ale může být použit pro více objektů a tak stačí nadefinovat pouze jeden pro celou scénu a tento shader jen případně modifikovat pomocí parametrů.

16 3. WebGL Typicky se shader skládá ze dvou částí:

• Vertex shader je zodpovědný za již zmiňovaný převod do dvou- rozměrného prostředí obrazovky a veškeré operace týkající se změn souřadnic. Tento shader tak kombinuje dříve ukázané trans- formační matice modelViewMatrix a projectionMatrix.

• Fragment shader (nebo také shader) se stará o genero- vání finální barvy jednotlivých bodů (pixel) podle vstupu jako je barva, textura nebo osvětlení. V ukázce 3.5 tento shader pro jednoduchost vždy vrací bílou barvu.

Samotný program shaderu se píše pomocí speciálně navrženého ja- zyka GLSL (OpenGL Shading Language), který je velice podobný ja- zyku C, nepodporuje ale všechny jeho prvky jako např. ukazatele. Navíc má ale vestavěnou podporu pro jednosložkové až čtyřsložkové vektory, podporu pro práci s maticemi o velikosti 2x2 až 4x4 (matice nemusí být čtvercová) a další speciální datové typy. Podrobně je jazyk popsán v oficiální dokumentaci6. V ukázce 3.5 jsou zobrazeny oba výše popsané shadery.

1 var vertexShaderSource= 2 "attribute vec3 vertexPos;\n"+ 3 "uniform mat4 modelViewMatrix;\n"+ 4 "uniform mat4 projectionMatrix;\n"+ 5 "void main(void){\n"+ 6 " gl_Position= projectionMatrix * modelViewMatrix\n"+ 7 " * vec4(vertexPos, 1.0);\n"+ 8 "}\n"; 9 var fragmentShaderSource= 10 "void main(void){\n"+ 11 "gl_FragColor= vec4(1.0, 1.0, 1.0, 1.0);\n"+ 12 "}\n"; Zdrojový kód 3.5: Vertex a fragment shader

6. http://www.opengl.org/documentation/glsl/

17 3. WebGL 3.2.6 Vykreslení

Jakmile je definováno vše, co popisují předchozí podkapitoly, zbývá už jen vykreslit dříve vytvořený čtverec. V ukázce 3.6 je pro tento pří- pad vytvořena funkce draw(), která na vstupu bere WebGL kontext a objekt čtverce. Funkce nejprve vyčistí pozadí černou barvou, poté předá vertex buffer čtverce, nastaví shader a připojí vertex buffer s ma- ticemi k shaderu jako vstupy. Poté stačí zavolat metodu drawArrays() k vykreslení čtverce, které je ještě potřeba předat typ primitiva a po- čet vrcholů (tyto informace jsou již obsaženy v nachystaném objektu čtverce).

1 function draw(gl, obj){ 2 // clear the background 3 gl.clearColor(0.0, 0.0, 0.0, 1.0); 4 gl.clear(gl.COLOR_BUFFER_BIT); 5 // set the vertex buffer 6 gl.bindBuffer(gl.ARRAY_BUFFER, obj.buffer); 7 // set the shader to use 8 gl.useProgram(shaderProgram); 9 // connect up the shader parameters 10 gl.vertexAttribPointer(shaderVertexPositionAttribute, 11 obj.vertSize, gl.FLOAT, false, 0, 0); 12 gl.uniformMatrix4fv(shaderProjectionMatrixUniform, false, 13 projectionMatrix); 14 gl.uniformMatrix4fv(shaderModelViewMatrixUniform, false, 15 modelViewMatrix); 16 // draw the object 17 gl.drawArrays(obj.primtype, 0, obj.nVerts); 18 }

Zdrojový kód 3.6: Finální vykreslení čtverce

Na obrázku 3.1 je výsledný vykreslený bílý čtverec na černém po- zadí. Kompletní zdrojové kódy této ukázky jsou v elektronické příloze této práce.

18 3. WebGL

Obrázek 3.1: Čtverec vykreslený s WebGL

3.3 JavaScriptové knihovny

Jak je vidět v předchozí kapitole, práce se samotným WebGL je nízkoúrovňová a dělat větší projekt nemusí být zrovna pohodlné, navíc by nastávalo velké opakování kódu. Proto je vhodné používat pomocné knihovny. Existují malé pomocné knihovny, které jen pomáhají s jedním kro- kem v postupu při vytváření aplikace, příkladem může být již zmíněná knihovna glMatrix7, která usnadňuje práci s transformačními maticemi. Dále existují větší knihovny, které nabízí širší abstrakci a odstínění uživatele (programátora, který knihovnu využívá) od detailů WebGL. Často tak je k dispozici např. základní sada shaderů, objektů nebo osvětlení. S těmito knihovnami se pak v principu pracuje podobně jako s aplikacemi pro tvorbu trojrozměrné grafiky. Na webu Khronos Group8 je uveden seznam celé řady takových knihoven. Mezi ně patří např. GLGE, SceneJS, PhiloGL a Three.js. Poslední jmenovaná je mezi vývojáři velice oblíbená a má tak velikou uživatelskou základnu, což byl jeden z důvodů, proč se tato knihovna stala nástrojem pro tvorbu vizualizace, která je cílem této práce. Po- drobněji se knihovnou Three.js zabývá kapitola4.

7. Autorem knihovny je Brandon Jones, který také do prostředí WebGL předělal známou hru Quake. 8. http://www.khronos.org/webgl/wiki/User_Contributions

19 4 Knihovna Three.js

Three.js je JavaScriptová knihovna pro práci s WebGL, která je použita k vypracování této práce. Tvůrce knihovny je Mr.doob, vlast- ním jménem Ricardo Cabello Miguel ze Španělska. Projekt má ote- vřené zdrojové kódy a je hostován na GitHubu, veškeré zdrojové kódy jsou tak lehce k nahlédnutí. První veřejná verze knihovny byla nahrána 24. 4. 2010 a nyní po čtyřech letech vyšla již 67. revize. Knihovna se tak stále aktivně vyvíjí. Hlavním cílem projektu bylo vytvořit malou knihovnu, která skryje detaily samotného vykreslování přes rozhraní WebGL a bude tak lehce použitelná bez hlubších znalostí počítačové grafiky. Díky využití celé řady správných postupů je knihovna rychlá a navíc nabízí mnoho před- vytvořených objektů, které jsou v prostorové grafice často používány (krychle, plochy, koule a různé). Dále knihovna nabízí různé funkce a objekty, jako jsou matice a vektory, používané ve výpočtech v pro- storové grafice. Důležité je také podotknout, že knihovna Three.js není primárně určená po tvorbu her. Nejsou podporovány výpočty pro fyziku1 nebo např. vzdálená komunikace po počítačové síti, která je nutná pro hry více hráčů. Tento nedostatek lze však vyřešit přidáním další speciálně určené knihovny, která tak lehce rozšíří základní funkcionalitu, případně vlastním doprogramováním. Samotná dokumentace knihovny není tak obsáhlá a obsahuje jen zá- kladní seznámení práce s knihovnou. Je ale dostupných mnoho ukázko- vých aplikací, které jsou pro pochopení práce s knihovnou velice dobré. Jedna sada příkladů je přímo na stránce knihovny2 a další rozsáhlá sada příkladů3 je od profesora matematiky a počítačových věd na Adelphi University jménem Lee Stemkoski.

1. Např. Physijs je knihovna, která přidává podporu fyziky a je určena přímo pro Three.js. 2. http://threejs.org/ 3. http://stemkoski.github.io/Three.js/

20 4. Knihovna Three.js 4.1 Jednoduchá stránka

Pro využití knihovny Three.js je potřeba mít připravenou základní kostru HTML dokumentu, jak znázorňuje ukázka 4.1 s napojením na zdrojový soubor knihovny. Canvas element (viz podkapitola 3.2), do kterého se samotná grafika vykresluje, vytváří přímo knihovna a uži- vatel pouze tento element přidá do některého kontejneru v dokumentu (např. DIV element). Na závěr kostry dokumentu je přidán obslužný skript formou souboru script.js.

1 2 3 4 Three.js HTML sceleton 5 6 7 8

9 10 11 Zdrojový kód 4.1: Základní kostra HTML dokumentu pro Three.js

4.1.1 Černý čtverec

V ukázce 4.2 je zdrojový kód skriptu pro zobrazení čtverce, stejného jako byl ukázán v předchozí kapitole pouze s pomocí WebGL. V první části je vytvořena proměnná reprezentující kontejner pro canvas ele- ment, který poskytne následně vytvořený THREE.WebGLRenderer objekt. Přidáním canvas elementu do kontejneru vznikne spojení mezi rendererem (vykreslovací objekt) a vykreslovacím plátnem, nyní stačí předat rendereru objekty k vykreslení a překreslit scénu. Překreslení se provádí metodou render(), kde parametry jsou objekt scény a ob- jekt kamery. Scéna je objekt nejvyšší úrovně, který obsahuje všechny ostatní grafické objekty nebo ty objekty, které mají vliv na vykreslování (kamera, světla, objekty). Pro vykreslení čtverce se tedy musí do scény přidat kamera a samotný čtverec. Grafický objekt se vytváří za pomocí geometrie a materiálu, kde geometrie určuje tvar objektu a materiál

21 4. Knihovna Three.js vlastnosti povrchu. Díky Three.js není problém vytvořit základní ob- jekty pomocí již předpřipravených geometrií a čtverec se tak v ukázce lehce vytvoří pomocí objektu THREE.PlaneGeometry. Více o geo- metriích a materiálech v následujících podkapitolách. Poté, co je scéna připravena, stačí už jen zavolat metodu render() a scénu s kamerou jí předat jako parametry. Objekt renderer se již postará o překreslení do canvas elementu. Výsledek je stejný jako na obrázku 3.1, bylo však použito znatelně méně kódu.

1 // container div 2 var container= document.getElementById("container"); 3 4 // renderer 5 var renderer= new THREE.WebGLRenderer(); 6 renderer.setSize(container.offsetWidth, container.offsetHeight) ; 7 8 // append canvas element to container 9 container.appendChild(renderer.domElement); 10 11 // create scene 12 var scene= new THREE.Scene(); 13 14 // createa camera 15 var camera= new THREE.PerspectiveCamera(45, container. offsetWidth/ container.offsetHeight, 1, 4000); 16 camera.position.set(0,0,3.333); 17 scene.add(camera); 18 19 // create rectangle object 20 var geometry= new THREE.PlaneGeometry(1,1); 21 var mesh= new THREE.Mesh( geometry, 22 new THREE.MeshBasicMaterial()); 23 scene.add(mesh); 24 25 // render 26 renderer.render(scene, camera);

Zdrojový kód 4.2: Čtverec pomocí knihovny Three.js

22 4. Knihovna Three.js 4.1.2 Rotující krychle se stínem a texturou

Pro změnu předchozí ukázky na trojrozměrný objekt stačí jednoduše změnit typ objektu z THREE.PlaneGeometry na THREE.Cube- Geometry, tím se vytvoří trojrozměrná geometrie. Aby objekt prosto- rově vynikal, je vhodné pracovat se stínováním a osvětlením tak, aby objekt přirozeně měnil odstín barvy podle směru světla. V ukázce 4.3 jsou popsané jen potřebné modifikace minulé ukázky. Protože základní materiál THREE.MeshBasicMaterial nepod- poruje práci se světlem a krychle by měla na všech stěnách stejný odstín barvy, nebyly by hranice těchto stěn patrné. Proto je v ukázce použit materiál THREE.MeshPhongMaterial, který používá Phongovo stí- nování a povrch tak bude přirozeně stínovaný. Phongovo stínování tedy počítá výslednou barvu každého bodu na základě světla, které se musí do scény také přidat, jinak by byl výsledný objekt černý (neosvětlený). Světelný zdroj v ukázce reprezentuje objekt THREE.Directional- Light, nastavený na pozici kamery. Pozice u tohoto typu světla nezna- mená výchozí bod pro paprsky osvětlení, ale nastavuje směr, ze kterého paprsky přicházejí. Tyto paprsky pak přicházejí rovnoběžně (analogie k lidskému prostředí je slunce, kde kvůli velké vzdálenosti paprsky do- padají na objekty prakticky ve stejném úhlu).

1 // light 2 var light= new THREE.DirectionalLight( 0xffffff, 1.25); 3 light.position.set(0, 0, 2.3); 4 scene.add( light); 5 6 // texture 7 var mapUrl="logo_fi.gif"; 8 var map= THREE.ImageUtils.loadTexture(mapUrl); 9 10 // cube 11 var material= new THREE.MeshPhongMaterial({ map: map }); 12 var geometry= new THREE.CubeGeometry(1, 1, 1); 13 cube= new THREE.Mesh(geometry, material); 14 cube.rotation.x= Math.PI / 5; 15 cube.rotation.y= Math.PI / 5; 16 scene.add(cube); Zdrojový kód 4.3: Modifikace pro zobrazení krychle se stínem a texturou

23 4. Knihovna Three.js Knihovna Three.js podporuje také texturování, tedy mapování např. obrázku na povrch krychle. Ve výchozím nastavení se na každou stěnu krychle vloží předaný obrázek. Stačí tedy pomocí metody .load- Texture() v objektu THREE.ImageUtils načíst obrázek jako tex- turu a tento objekt poté předat materiálu jako map parametr. V ukázce je na krychli zobrazeno logo Fakulty informatiky Masarykovy univer- zity. Předcházející kroky stačí k vykreslení požadované krychle, ale aby bylo vidět stínovaní v akci a objekt opravdu prostorově vynikl, je v ukázce přidána objektu i rotace. Pro rotaci krychle lze použit objekt rotation a měnit hodnoty pro jednotlivé osy v radiánech. Tento objekt spadá pod objekt krychle a pracuje jako transformační matice. Pro naklonění ob- jektu ke kameře tak stačí nastavit osu x a y (jedná se o horizontální π a vertikální osu z pohledu kamery) třeba na hodnotu 5 . Nyní stačí po každém překreslení změnit rotaci na ose y a tím vznikne otáčení kolem vertikální osy krychle.

Obrázek 4.1: Rotující krychle se stínem a texturou

24 4. Knihovna Three.js Vykreslovací cyklus je reprezentovaný funkcí animate() zobrazené v ukázce 4.4. Samotný cyklus volání této metody je realizován pomocí metody requestAnimationFrame(), která je podporována přímo prohlížečem a zavolá znovu metodu animate() s takovou frekvencí, kterou uzná za vhodnou (nejčastěji 60krát za vteřinu v závislosti na výkonu zařízení a obnovovací frekvenci obrazovky). Tím se dosáhlo vý- sledné animace rotace. Snímek aplikace je na obrázku 4.1.

1 function animate() { 2 cube.rotation.y += 0.01; 3 renderer.render(scene,camera); 4 requestAnimationFrame(animate); 5 } Zdrojový kód 4.4: Fuknce pro pro cyklus animovaného vykreslování

4.2 Kamery

Nejzákladnější kameru v knihovně Three.js představuje abstraktní třída THREE.Camera. Sám o sobě objekt není funkční a představuje pouze základ pro vytvoření vlastní kamery nebo pro další kamery ob- sažené v knihovně. Rozhraní tohoto objektu obsahuje pouze metodu lookAt(), které se pomocí vektoru předává směr záběru kamery. Knihovna obsahuje dvě předpřipravené kamery pro perspektivní a or- tografické (také pravoúhlé) promítání.

4.2.1 Perspektivní kamera

Objektem THREE.PerspectiveCamera je reprezentována per- spektivní kamera. Využívá perspektivní promítání, kde objekty jsou vykreslovány na plochu pomocí přímek, které vycházejí ze společného bodu, který nesmí ležet ve vykreslovací ploše (průmětna) [9]. Protože vzdálenější plocha je větší a musí se zobrazit do stejně velkého okna stejně jako bližší plochy, je nutné ji při vykreslování zmenšit. To má za následek, že objekty vzdálenější od pozorovatele se tak jeví jako menší. Toto promítání tak simuluje reálný pohled člověka, kde paprsky světla dopadají na oko do prakticky stejného bodu.

25 4. Knihovna Three.js Na obrázku 4.2 je graficky znázorněno perspektivní promítání, kde jsou tři plochy. První je obrazovka, která reprezentuje plochu s finálním vykreslením scény. Další dvě jsou hraniční plochy, které určují prostor k vykreslení (tento prostor se nazývá view frustum). Vše, co je mezi těmito plochami, bude tedy zobrazeno na obrazovce. Vertikální zorné pole je úhel určující jak moc se přímky rozcházejí, šířka se pak dopočítá podle poměru stran výsledné obrazovky.

Vzdálenější hraniční plocha

Bližší hraniční plocha Objekty

Obrazovka

Vertikální zorné pole Obrázek 4.2: Perspektivní projekce

Pro vytvoření kamery je zapotřebí zavolat konstruktor zmiňovaného objektu THREE.PerspectiveCamera a předat mu následující čtyři parametry v tomto pořadí:

1. fov - úhel vertikálního zorného pole, 2. aspect - poměr stran, vypočítá se jako šířka zobrazované plochy vydělená výškou, 3. near - vzdálenost bližší hraniční plochy vykreslení, 4. far - vzdálenost vzdálenější hraniční plochy vykreslení.

26 4. Knihovna Three.js Dále perspektivní kamera nabízí rozdělení vykreslovaného obrazu na více částí pomocí metody .setViewOffset(). Metoda bere šest parametrů, kde první dva tvoří celkový rozměr, další dva začátek dílčí vykreslovací plochy a další dva její velikost. Pomocí více takto nastave- ných kamer lze dosáhnout obrazu rozděleného např. do více monitorů. Důležitá metoda je také .updateProjectionMatrix(). Je po- třeba ji zavolat při každé změně parametrů kamery.

4.2.2 Ortografická kamera

Objektem THREE.OrthographicCamera je reprezentována ka- mera využívající ortografickou (neboli pravoúhlou) projekci. Jedná se o projekci, kde jsou přímky od plochy obrazovky (průmětna) vždy na tuto plochu kolmé (svírají s průmětnou úhel 90 °) a navzájem jsou tedy rovnoběžné [9]. Vlivem toho jsou všechny další plochy stejně velké a ne- vzniká tak rozdíl mezi objekty různých vzdáleností od pozorovatele. Názorně toto promítání zobrazuje obrázek 4.3.

Bližší hraniční plocha Vzdálenější hraniční plocha

Obrazovka Objekty

Obrázek 4.3: Ortografická projekce

Využití této projekce je vhodné např. pro získání různých pohledů na daný objekt z více stran současně. Nejčastěji se využívají tři navzá- jem kolmé průmětny pro pohled zepředu, z boku a horní nebo dolní pohled. Může se jednat o různé technické nákresy, kde i vzdálenější

27 4. Knihovna Three.js rozměr musí být vykreslený stejnou délkou jako tentýž rozměr blíže k pozorovateli. Objekt kamery se vytvoří konstruktorem podobně jako u předchozí kamery, ten má šest parametrů, kde první čtyři představují velikost ploch a poslední dva jsou vzdálenosti hraničních ploch. Přesněji řečeno, v případě spojení hraničních ploch pomocí dalších čtyř ploch vznikne kvádr, kde právě první čtyři parametry určují posunutí těchto ploch od středové přímky. Pořadí ploch v parametrech je z pohledu pozorovatele první levá, poté pravá, vrchní a spodní. V ukázce 4.5 je obecný postup pro vytvoření ortografické kamery, kde width je šířka výsledné vykreslovací plochy a height je její výška.

1 var camera= new THREE.OrthographicCamera( 2 width / - 2,//left 3 width / 2,//right 4 height / 2,//top 5 height / - 2,//bottom 6 1,//near 7 1000 );//far Zdrojový kód 4.5: Obecné vytvoření ortografické kamery

4.3 Geometrie

Pro vytvoření grafického objektu je zapotřebí mít geometrii a ma- teriál (viz ukázky 4.2a 4.3). Právě geometrií se hlouběji zabývá tato podkapitola, materiál je pak rozebrán v následující podkapitole 4.4.

4.3.1 Předdefinované geometrie

Již bylo naznačeno, že knihovna Three.js obsahuje některé předde- finované geometrie. Jedná se o základní ploché i trojrozměrné objekty, ale i složitější geometrie. Mezi ploché objekty (tedy ty, které nemají třetí rozměr) patří THREE.PlaneGeometry a THREE.CircleGeometry, kde první představuje plochu obdélníkového tvaru a druhý kruh nebo kruhovou

28 4. Knihovna Three.js výseč. Konstruktor plochy má čtyři parametry, první dva určují šířku a výšku, další dva pak počet segmentů, na který se plocha rozdělí (vý- chozí hodnoty jsou 1). Konstruktor kruhu má opět čtyři parametry, první je průměr a druhý počet segmentů říkající z kolika hran se bude výsledný kruh skládat (výchozí hodnota je 8). Pro kruhovou výseč jsou určeny další dva parametry, které určují zadáním úhlu v radiánech za- čátek a délku otáčení. Výchozí hodnota začátku je 0, která představuje pozici na třetí hodině, délka otáčení je pak hodnota 2π, která před- stavuje celý kruh. Podobný kruhu je objekt THREE.RingGeometry, který má však v parametrech ještě jeden poloměr určující velikost vnitř- ního kruhového otvoru, vznikne tak plochý prstenec.

(a) Cylinder (b) Torus (c) Sphere

Obrázek 4.4: Ukázky geometrií

Základní trojrozměrný objekt je např. THREE.CubeGeometry (v aktuální verzi přejmenováno na THREE.BoxGeometry). Parame- try konstruktoru jsou podobné jako u plochy, jen je přidán třetí rozměr, jak pro samotnou hloubku, tak pro počet segmentů hloubky. Další ob- jekt je THREE.SphereGeometry představující kouli (viz obr. 4.4c), kde jsou parametry opět podobné jako u kruhového objektu. Po polo- měru se tedy uvádí počet segmentů na šířku a výšku a dále pak pro trojrozměrnou výseč dvakrát počáteční úhel a délka otáčení. Poslední geometrie je např. THREE.CylinderGeometry, která má tvar válce. Parametry tak jsou spodní a horní poloměr a výška mezi těmito zá- kladnami. Dále pak počet segmentů v základnách a obalovém plášti (na obrázku 4.4a je vidět cylinder s malým množstvím segmentů, proto lze u spodní základny vidět hrany), nakonec je parametr určující, zda je válec otevřen nebo uzavřen. Obecně platí, že veškeré parametry mají své výchozí hodnoty, a proto není potřeba je všechny nastavovat.

29 4. Knihovna Three.js Knihovna obsahuje také složitější trojrozměrné objekty, jako je např. THREE.TorusGeometry (viz obr. 4.4b), představující trojroz- měrný prstenec . Základní parametry jsou poloměr samotného prstence a poloměr tuby, která tvoří prstenec, dále pak tradičně počty segmentů a úhel pro určení výseče. Knihovna také nabízí různé čtyřstěny a mno- hostěny. Zajímavý objekt je THREE.ExtrudeGeometry, kterému se předá první parametr shapes představující rovinný tvar nebo pole těchto tvarů. Objekt tyto tvary spojí protáhnutím do jednoho objektu a vy- tvoří tak trojrozměrný objekt. Speciální kategorií může být např. trojrozměrné písmo reprezen- továno objektem THREE.TextGeometry. Pokud však uživatel nepo- třebuje mít písmo prostorové a využívá ve scéně různé popisky, exis- tuje trik jak vykreslit písmo dvojrozměrně a tak ušetřit mnoho výpo- četního času při vytváření textu. Více o této metodě je popsáno na konci podkapitoly 4.4. Výše zmíněný shape objekt, lze vytvořit pomocí THREE.ShapeGeometry a přidružených metod pro kreslení čar.

4.3.2 Tvorba vlastní geometrie

Když základní objekty nestačí, jsou dvě možnosti, jak vytvořit vlastní geometrii. První možností je vymodelovat si objekt ve vhodném edi- toru pro trojrozměrnou grafiku a v podporovaném formátu načíst po- mocí Three.js knihovny, druhá možnost pak je vytvořit geometrii přímo v obslužném kódu aplikace. Protože v této práci je potřeba dynamicky vytvářet geometrii na základě přijatých dat a žádná z předvytvořených geometrií neodpovídá požadavkům, byla zvolena druhá možnost tvorby vlastní geometrie. Pro vytvoření vlastní geometrie s podporou textur je potřeba dodr- žet několik základních kroků:

1. Vytvoření vrcholů a ty přidat do pole vertices.

2. Z vytvořených vrcholů sestavit stěny (face).

3. Nastavit UV souřadnice pro vrcholy v každé stěně.

4. Vypočítat normály.

30 4. Knihovna Three.js Základní objekt pro geometrii je THREE.Geometry. Začne se tedy vytvořením instance tohoto objektu (nebo lze vytvořit novou třídu, která dědí tento objekt). Objekt má v sobě pole vertices do kterého stačí přidávat vrcholy reprezentované objektem THREE.Vector3. Druhý krok je určit, které vrcholy tvoří stěnu. K tomu slouží pole faces. Stěna je reprezentována objektem THREE.Face3, který má tři parametry. Tyto parametry jsou indexy vrcholů z pole vertices. Stačí tedy vytvořit objekt stěny pomocí existujících indexů vrcholů a přidat tento objekt do pole faces, tím se definuje stěna (v závislosti na pořadí vrcholů se určuje přední a zadní strana stěny).

0; 1 ··· 0.5; 1 ··· 1; 1 ...... 0; 0.5 ··· 0.5; 0.5 ··· 1; 0.5 ...... 0; 0 ··· 0.5; 0 ··· 1; 0

Obrázek 4.5: UV souřadnice

Dále je potřeba nastavit tzv. UV souřadnice, jedná se o dvě hod- noty, které určují, jak bude na objekt nanesena textura. Vrcholy každé stěny mají tyto hodnoty a knihovna díky tomu pozná, kterou část tex- tury má na danou stěnu nanést. Typicky jsou hodnoty v rozsahu 0 až 1 pro horizontální a vertikální směr napříč celou geometrií, kde hod- noty U rostou doprava a hodnoty V nahoru. Na obrázku 4.5 je matice reprezentující tyto hodnoty pro hraniční a středové vrcholy. Hodnoty pro danou stěnu jsou reprezentovány polem, kde délka pole je počet vrcholů obsažených ve stěně a pořadí hodnot je podle toho, ja- kou hodnotu chceme přiřadit vrcholu na dané pozici. Toto výsledné pole se přidá do pole faceVertexUvs. Pořadí těchto polí musí odpovídat pořadí stěn v poli faces, protože podle toho se určí, které stěně patří které hodnoty. Posledním krokem je zavolání metod .computeFaceNormals() a .computeVertexNormals(), které spočítají normály pro všechny stěny a vrcholy vytvořené geometrie. Normála stěny je přímka, která je kolmá na danou stěnu. Vektor určující směr této přímky se pak na- zývá normálový vektor a slouží ke korektnímu osvětlení objektu. Na ob-

31 4. Knihovna Three.js

Normála vrcholu

Normála stěny

Obrázek 4.6: Normály stěn a vrcholu rázku 4.6 jsou znázorněny normály stěn a také normála vrcholu, která představuje průměr normál okolních stěn. Pokud vytvářená geometrie má duplicitní vrcholy, je nutné je sjednotit do jednoho, to se provede zavoláním metody .mergeVertices(). Metoda se musí zavolat před samotným počítáním normálových vektorů.

4.4 Materiály

Stejně jako u geometrií, knihovna Three.js pro vytváření objektů obsahuje i předdefinované materiály. Každý materiál má již naprogra- movaný svůj shader (viz 3.2.5), jehož chování se mění v závislosti na pa- rametrech předaných konstruktoru vybraného materiálu. Všechny sha- dery dostupné v knihovně jsou uloženy v kolekci THREE.ShaderLib. Pro všechny níže zmíněné materiály platí, že mezi parametry jsou tyto základní:

• shading, který určuje princip vykreslování jednotlivých stěn. Jedná se buď o hladké stínování (THREE.SmoothShading), kde stínování jednotlivých stěn zakřivené plochy na sebe hladce navazuje nebo ploché stínování (THREE.FlatShading), které

32 4. Knihovna Three.js vystínuje stěnu bez ohledu na okolí. Rozdíl stínování je zobrazen na obrázku 4.7.

• wireframe označuje, zda se vykreslí pouze hrany stěn objektu.

(a) SmoothShading (b) FlatShading

Obrázek 4.7: Rozdíl mezi SmoothShading a FlatShading

Mezi základní materiály patří THREE.MeshNormalMaterial a THREE.MeshBasicMaterial. První zmiňovaný nabízí pouze zá- kladní parametry, barva materiálu se určuje v shaderu podle hodnot normálových vektorů, nelze ji tedy ovlivnit. Druhý materiál již nabízí možnost změnit barvu a to jak globálně parametrem color, tak i přímo barvou vrcholu pomocí vertexColors. Při obarvování podle vrcholů se barvy ploch počítají jako přechod od jednoho vrcholu k dalšímu. Tento materiál není ovlivňovaný okolním světlem a barva se počítá bez ohledu na okolí. Knihovna obsahuje i pokročilejší materiály, které pracují se svět- lem a na základě dopadající intenzity světla a nastavené barvy počítají výslednou barvu pro vykreslení nebo dokáží na povrchu objektů vykres- lit texturu (viz podkapitola 4.1.2). THREE.MeshLambertMaterial je jednodušší z těchto materiálů a vypočítává výslednou barvu pro každý vrchol, přičemž barva plochy se dopočítá přechodem. Naproti tomu THREE.MeshPhongMaterial počítá hodnotu barvy pro každý bod plochy, navíc přidává i odlesk od světelného zdroje. Pomocí dalších parametrů lze tento odlesk dále upravovat (intenzita, barva).

33 4. Knihovna Three.js Dále jsou v knihovně obsaženy různé materiály pro plné nebo čárko- vané čáry, shader materiál pro použití vlastního shaderu nebo THREE.SpriteMaterial, který má speciální chování a používá se odlišně. Při použití tohoto materiálu je objekt vždy otočen směrem ke kameře. V této práci se využívá Sprite materiál na zobrazování po- pisků. Stačí vytvořit písmo ve virtuálním canvas elementu a tento ele- ment poté použít jako texturu pro SpriteMaterial, časová nároč- nost takto vytvořeného popisku je několikanásobně menší než v případě prostorového textu.

4.5 Světla

Osvětlovací objekty v knihovně Three.js se dají rozdělit na ty s glo- bálním efektem a ty, které ovlivňují pouze zadaný směr. Světla ovlivňují pouze objekty s takovým materiálem, který s nimi umí pracovat. THREE.AmbientLight je nejzákladnější světlo s globálním efek- tem, ovlivňuje tak všechny objekty ve stejné scéně. Toto světlo na- pomáhá vykreslit scénu realisticky a simulovat přirozený odraz světla všech objektů. Světlo se tak dostane i na objekty, které nejsou přímo nasvícené. Další světlo s globálním efektem je THREE.Hemisphere- Light, které ale ovlivňuje objekty z horní a spodní strany zvlášť. Obě strany dovolují nastavit vlastní barvu osvětlení. Pro další světla je již nutné určit jejich umístění ve scéně. Jedno ta- kové světlo již bylo zmíněno v podkapitole 4.1.2, jedná se o THREE.Di- rectionalLight. Jak již bylo řečeno, světlo se chová jako slunce v reálném světě. Všechny paprsky pochází z daného směru a jsou rov- noběžné. Dalším světelným objekt je THREE.PointLight, který se chová jako žárovka. Paprsky vychází z jednoho bodu do okolí. Poslední objekt THREE.SpotLight je podobný předchozímu, světlo ale vysílá paprsky jedním zvoleným směrem. Pouze THREE.DirectionalLight a THREE.SpotLight mo- hou vytvářet stín. Vrhání stínu se musí zapnout nastavením vlastnosti .castShadow na hodnotu true. Stejně tak se musí u objektů, které mají stín přijímat, nastavit vlastnost .receiveShadow také na hod- notu true.

34 4. Knihovna Three.js 4.6 Shrnutí kapitoly

Tato kapitola začala přímo ukázkou použití knihovny Three.js, nej- prve na jednoduchém příkladu, poté bylo ukázáno rozšíření na troj- rozměrný objekt s animovaným otáčením a texturou. V následujících podkapitolách byly vysvětleny základní pojmy a objekty pro přípravu scény, jako jsou kamery, geometrie, materiály a světla. Většina před- stavených postupů byla použita pro tvorbu této práce.

35 5 Implementace vizualizace

Cílem aplikace bylo vytvořit portlet pro Liferay portál zobrazující prostorovou vizualizaci dat s možností interakce. Data pro vizualizaci jsou přijímána z databáze, kterou plní Správa měření. Samotná komuni- kace mezi vizualizací a databází je zprostředkována pomocí REST1 roz- hraní a data, která mají být zobrazena, se určují speciálním portletem pro vizualizaci časové osy. Na základě obdržených informací z časového portletu pak vizualizace stáhne z databáze potřebná data k zobrazení. Samotné trojrozměrné zobrazování je provedeno pomocí WebGL s využitím knihovny Three.js. Interakce je zpracována formou ovlá- dání pozice kamery kurzorem při stisku tlačítka myši a ovládací ná- strojové lišty, která se zobrazí po přejetí kurzorem nad vizualizací. Ná- strojová lišta dovoluje posun po časové ose, přesun kamery do výchozí pozice a přepnutí do režimu celé obrazovky. Na rozdíl od ovládání kur- zorem, není ovládací lišta přímo součásti vizualizace, ale jedná se pouze o nástavbu, která komunikuje s rozhraním vizualizace. V následující podkapitole 5.1 je popsán vizuální návrh aplikace. Rozvržení zdrojového kódu a základní popis objektů jsou rozebrány v podkapitole 5.2. Podkapitola 5.3 popisuje vybrané implementační detaily. Dále podkapitola 5.4 se zabývá principy psaní JavaScriptového kódu v této aplikaci. Na závěr je pak v podkapitole 5.5 popsán Liferay portál a způsob, jak vytvořit portlet ze zdrojových kódu aplikace.

5.1 Vizuální návrh

Po vizuální stránce je aplikace navržena tak, aby zobrazovala více veličin měřených v jeden časový okamžik (časová řada) a zároveň vy- brané množství těchto časových okamžiků. Jednotlivé osy veličin jsou v kruhu tak, že osy vychází ze společného bodu ve středu dané plochy a úhly mezi nimi jsou vždy stejné tak, aby osy byly rovnoměrně roz- prostřeny. Velikost hodnoty je vizualizována vzdáleností od výchozího středního bodu. Tímto způsobem vznikne průřez, který znázorňuje je- den časový okamžik. Spojením těchto průřezů ve třetím rozměru pak

1. Slouží pro jednotný přístup k datům pomocí HTTP protokolu.

36 5. Implementace vizualizace

Obrázek 5.1: Vizualizace náhodně vygenerovaných dat vznikne výsledná prostorová vizualizace. Podle velikosti zobrazované veličiny, se také mění barva povrchu vizualizace. Červená barva tak značí přiblížení k maximální hranici, zelená naopak symbolizuje nízké hodnoty (viz obrázek 5.1). V předchozím odstavci byl popsán samotný objekt, který vizualizuje vstupní data. Dále jsou kolem tohoto objektu celkem tři poloprůhledné stěny. Jedna stěna se nachází v přední části a jejím úkolem je infor- movat o názvech veličin a zobrazovat osy pomocí čar. Další dvě stěny jsou po stranách (záleží na pohledu, stěny se přehazují podle polohy kamery) a popisují pomocí čar jednotlivé časové okamžiky s přísluš- nými popisky. Vizualizace zobrazuje rozmezí časových okamžiků tím způsobem, že aktuálnější konec je vždy vyobrazen v přední stěně. Výše popsané objekty lze vidět na obrázku 5.1, kde vizualizace zobrazuje náhodně vygenerovaná data.

37 5. Implementace vizualizace Prostor mezi jednotlivými průřezy je ve vizualizaci dopočítáván ku- bickou interpolací, díky tomu je povrch vyhlazen. Více o interpolacích viz [9]. Stejně se dopočítává i samotný průřez tak, aby vrcholy byly za- oblené. Počet dopočítávaných hodnot lze měnit pomocí rozhraní apli- kace stejně jako celá řada jiných parametrů (barva pozadí, barva skel, velikost vizualizace a prostoru mezi průřezy, velikost písma atd.). Veš- keré tyto parametry jsou popsané v přiložené dokumentaci (viz pří- lohaC). Během vývoje se vizualizace postupně měnila podle požadavků vi- zualizačního týmu. Např. finální podoba okolních stěn a popisků byla zvolena ze čtyř návrhů. Původně bylo plánováno, že popisky budou součástí stěny, pro lepší čitelnost se ale díky vlastnostem zvoleného materiálu otáčejí na kameru. Také byla navrhována jen spodní stěna, nakonec se přidala i boční s tím, že se stěny přizpůsobují podle polohy kamery.

5.2 Návrh zdrojového kódu

Pro psaní zdrojového kódu aplikace byl zvolen objektový návrh, který zvyšuje přehlednost kódu a jeho znovupoužitelnost. Kód aplikace je rozdělen do logických celků — objektů. Každý z těchto objektů plní svou úlohu a mezi sebou komunikují pomocí volání metod a callback funkcí, což je funkce předaná volané metodě, která může později tuto funkci zavolat a upozornit tak na danou událost. V této aplikaci to může být např. upozornění na připravená data pro vykreslení nebo zpráva o dokončení animace. Na obrázku 5.2 je diagram popisující hierarchii těchto objektů:

• Manager je hlavní objekt, který vytváří scénu a další objekty. Využívá služby ostatních objektů k potřebnému fungování celé aplikace a poskytuje hlavní rozhraní pro ovládání aplikace. Pro- tože obsahuje reference na ostatní objekty, může sjednocovat společné rozhraní jiných objektů. Např. při změně velikosti po- mocí objektu Manager, se změny provedou na rozhraní jednotli- vých objektů (v tomto případě ChartManager a GlassManager). • ChartManager je objekt reprezentující graf. Provádí veškeré

38 5. Implementace vizualizace

Obrázek 5.2: Diagram tříd

výpočty nutné pro zobrazení grafu a poskytuje rozhraní pro jeho ovládání a modifikaci (velikost, šířka mezi průřezy atd). Stará se také o to, v jakém měřítku budou data zobrazena. K upřesnění tohoto měřítka slouží speciální pole hodnot v datové struktuře. Pokud toto pole není definováno, ChartManager zobrazí maxi- mální hodnotu z přijatého rozsahu dat jako maximální hodnotu, kterou dokáže graf zobrazit.

• GlassManager představuje poloprůhledné stěny okolo grafu včetně popisků. Tento objekt opět nabízí rozhraní pro ovládání a modifikaci. Boční stěny reagují na pozici kamery tak, aby ni- kdy nepřekážely při pohledu na vizualizaci dat. Reakce na ka- meru je v podobě animovaného přesunu stěny na protější stranu. O jednotlivých událostech (jako začátek a konec animace) infor- muje objekt pomocí callback funkcí, které lze objektu volitelně přiřadit.

• CameraManager se stará o správnou pozici kamery. Nabízí ovládání pro pohyb okolo grafu, po časové ose a návrat na pů-

39 5. Implementace vizualizace vodní pozici. Dále nabízí rozhraní pro modifikaci různých para- metrů jako rychlost otáčení, délka animací atd. Pomocí callback funkcí opět informuje o různých událostech, zejména pak o změně kvadrantu, ve kterém se kamera nachází. Z této informace vy- chází přehazování stěn v objektu GlassManager. • IProvider předepisuje rozhraní pro objekt poskytující data a for- mát dat uvnitř aplikace. Aby aplikace fungovala s jiným dato- vým zdrojem, musí implementovat toto rozhraní. IProvider také předepisuje formát objektu, který je nositelem dat. Tento formát využívají interně jednotlivé objekty ve svých metodách a musí být proto dodržen, viz dokumentace v přílozeC. Jakmile jsou data připravena, volá se callback funkce. • KypoProvider implementuje rozhraní IProvider a poskytuje data z KYPO databáze pomocí REST služby. Po stažení po- třebných dat je tento objekt poté převede do interního formátu definovaného rozhraním IProvider. Dále upraví čas podle časové zóny získané z REST služby tak, že správný čas bude v pásmu UTC. Pokud se tedy někde v aplikaci vypisuje čas z těchto dat, musí se vždy vypisovat v UTC pásmu. Tímto krokem se vyře- šil problém se zobrazováním rozdílného času v různých časových zónách. • TestProvider také implementuje rozhraní IProvider a generuje náhodná data podle počtu zadaných veličin a rozsahu. Tento zdroj dat lze použít např. pro lokální testování bez přístupu do KYPO databáze nebo pro demonstrační účely. Pro aktivování testovacího zdroje dat je potřeba předat instanci tohoto objektu konstruktoru hlavního Managera.

Vykreslovací cyklus, který je řízen hlavním objektem, je navržen tak, aby scénu nevykresloval stále, ale pouze pokud je potřeba. Pomocí callback funkcí pro vynucení překreslení nebo pro oznámení o začátku a konci animace se tak řídí spouštění a zastavování tohoto cyklu. Pokud se s vizualizací nepracuje a je pouze zobrazena, neměla by na zobrazo- vacím zařízení snižovat výpočetní výkon. Vizualizace má svá omezení v podobě přijímaných dat. V aplikaci se předpokládá, že všechna přijatá data (hodnoty pro všechny osy) mají

40 5. Implementace vizualizace stejné časové okamžiky a lze je tak rozdělit do jednotlivých časových průřezů. V rámci vizualizačního týmu projektu KYPO případné ne- srovnalosti v datech řeší REST rozhraní, které chybějící data vybere z nejbližších možných. Samotné vizualizace se tak o tento problém ne- musí starat.

.js/ main.js libs/ jquery-1.8.3.min.js tween.js three.js spiderChart3D/ Utils.js namespace.js managers/ Manager.js CameraManager.js ChartManager.js Glassmanager.js dataProviders/ IProvider.js TestProvider.js KypoProvider.js

Obrázek 5.3: Struktura souborů

5.2.1 Struktura souborů zdrojových kódů

Veškeré JavaScriptové zdrojové soubory jsou ve složce js. Struk- turu popisuje obrázek 5.3. V kořenovém adresáři se nachází soubor main.js, který slouží pro inicializaci vizualizace vytvořením instance Managera, předání poskytovatele dat, navázání ovládacích prvků na rozhraní Managera a případné další úpravy pomocí rozhraní. Dále je ve stejném adresáři složka libs, ve které se nachází potřebné externí knihovny pro chod aplikace. Poslední složkou je spiderChart3D obsahující zdrojové soubory

41 5. Implementace vizualizace vizualizace. Názvy souborů v této složce odpovídají objektům popsa- ných v předchozí podkapitole. Navíc je zde i Utils.js, kde jsou pomocné globální funkce a dále pak namespace.js, který definuje jmenné prostory a tím i globálně dostupný objekt SpiderChart3D. Přes tento objekt jsou dostupné instance všech managerů. Ve zmíněném souboru main.js je definována i komunikace s hlav- ním portletem a to pomocí Liferay JavaScriptového rozhraní. Tento hlavní portlet má na starostí zobrazení časové osy společně s ovládá- ním ostatních portletů zasíláním zpráv. Při příchozí události se pouze zavolá příslušná metoda z rozhraní Managera. Ve složce libs se kromě knihovny Three.js a pomocné knihovny jQuery nachází také knihovna tween.js2. Tato knihovna slouží pro vytváření plynulých animací. Pro použití v této práci byla knihovna lehce modifikována přidáním metody end pro korektní ukončení ani- mace popsané v pull requestu3.

5.2.2 Zprovoznění aplikace

Pro spuštění aplikace je potřeba HTML kostra dokumentu (viz ukázka 4.1). Na prvním místě je nutné nalinkovat veškeré externí knihovny (knihovna jQuery se linkuje pouze v ukázkové aplikaci, v Liferay por- tálu je tato knihovna v rámci projektu nalinkována globálně). Poté se musí nalinkovat soubor namespace.js. Dále již na pořadí nezáleží, avšak soubor main.js musí být jako poslední.

5.3 Vybrané implementační detaily

V této podkapitole jsou zmíněny detaily implementace, které mají vliv na samotné zobrazování dat. Jedná se o obarvování povrchu vizu- alizace a o samotnou velikost objektu v jednotlivých průřezech.

2. https://github.com/sole/tween.js/ 3. https://github.com/sole/tween.js/pull/101

42 5. Implementace vizualizace 5.3.1 Obarvování povrchu vizualizace

Povrch vizualizace se obarvuje pomocí barev vrcholů vizualizačního objektu. V podkapitole 4.4 byla zmínka o vertexColors. Pokud se materiálu nastaví tento příznak, obarví se povrch podle barev nastave- ných jednotlivým vrcholům tím způsobem, že plochy se obarví pomocí přechodů barev mezi vrcholy. Pro nastavení barvy slouží pole colors v geometrii, kde index barvy musí odpovídat indexu vrcholu v poli vertices. Samotnou barvu reprezentuje objekt THREE.Color, který dovoluje nastavit barvu podle různých modelů. V této práci byl zvolen model HSL (viz obrá- zek 5.4).

Obrázek 5.4: Barevný model HSL4

Díky tomu, že požadované cílové barvy (červená až zelená) v HSL modelu sousedí, stačí hodnoty vrcholů zasadit do tohoto rozsahu. Hod-

4. Obrázek převzat z http://www.erinsowards.com/articles/2011/01/ colors.php s lehkou modifikací.

43 5. Implementace vizualizace

Obrázek 5.5: Detail obarvování povrchu a přizpůsobení dat notou vrcholu je v tomto případě myšlena vzdálenost vrcholu od středu plochy, ve které se nachází. Výpočet vzdálenosti je popsán v následu- jící podkapitole 5.3.2. Maximální možná hodnota ve vizualizaci se tedy podle obrázku zobrazuje na 0° a minimální na 120° HSL modelu. Na obrázku 5.5 je ukázka výsledku obarvení.

5.3.2 Přizpůsobení vstupních dat

Vstupní data pro vizualizaci mají různé rozsahy, které musí být upraveny pro korektní zobrazení. Jednotlivé hodnoty veličin se pro po- třeby vykreslení mění podle aktuální velikosti grafu. Upravují se vždy všechny hodnoty jedné veličiny v daném rozsahu, kde se vybere maxi- mální hodnota a ta je zobrazena jako maximum ve vizualizaci. Ostatní hodnoty se upraví poměrově vůči tomuto vypočítanému maximu. Tímto způsobem se zadané hodnoty s jakýmkoli rozsahem vždy zobrazí v me- zích vizualizace. Ve vizualizaci se vlivem interpolace mohou objevit i záporné hod- noty na které není vizualizace navrhována. V takovém případě by se hodnota zobrazovala v prostoru jiné veličiny. Z tohoto důvodu se tyto

44 5. Implementace vizualizace záporné hodnoty zobrazují jako nula. Maximální hodnotu lze ovlivňovat i ručně bez ohledu na to, jaká se vypočítá ze zadaných dat. Slouží k tomu pole maxValues v objetu data v poskytovateli. Pokud jsou předem známy maximální hodnoty, lze je takto definovat a algoritmus pro přizpůsobení dat namísto počí- tání vezme tyto hodnoty. Aktuálně nejsou z REST rozhraní maximální hodnoty dostupné a proto se toto pole v práci nevyužívá, je ale připra- veno v případě budoucího rozšíření.

5.4 JavaScriptové postupy použité v aplikaci

Jazyk JavaScript je dynamický jazyk, kde lze za chodu aplikace mě- nit nejen vlastnosti objektu, ale třeba i přepsat celou metodu. Lehce tak lze modifikovat cizí objekt (např. opravit chyby) záplatou bez zá- sahu do zdrojového souboru. Částečně tomuto přístupu do objektu lze zabránit různým maskováním vlastností do veřejně nedostupných pro- měnných. V této práci byl ale zvolen způsob, který je naopak otevřený a dovoluje tak naplno využít možnosti jazyka JavaScript. Více viz [12].

5.4.1 Definice tříd

Definovat třídu a vytvořit podle ní objekt lze více způsoby. Jednak lze simulovat zapouzdřenost, kde privátní proměnné jsou opravdu ne- dostupné (viz ukázka 5.1), nebo využít objekt prototype, tak jako v této práci.

1 var GlassManager= function (parameters){ 2 var innerParam= parameters.innerParam; 3 this.publicParam= parameters.publicParam; 4 5 this.countParams= function () { 6 return innerParam+ this.publicParam; 7 }; 8 }; Zdrojový kód 5.1: Vytvoření třídy jen konstruktorem

45 5. Implementace vizualizace Objekt prototype definuje výchozí stav a metody vytvářeného objektu. Výhodou je, že metody definované v tomto objektu se vytváří pouze jednou pro všechny instance objektu v aplikaci (viz ukázka 5.2). Pokud nastane nějaká změna v tomto objektu (úprava nebo přidání me- tody), projeví se jak již ve všech vytvořených instancích, tak i v těch, které se teprve vytvoří. Nevýhodou může být jen nemožnost vytvo- řit skutečně privátní proměnnou, pro odlišení veřejných vlastností od privátních tak slouží jmenné konvence popsané v podkapitole 5.4.4.

1 var GlassManager= function (parameters){ 2 this._innerParam= parameters.innerParam; 3 this.publicParam= parameters.publicParam; 4 }; 5 GlassManager.prototype={ 6 countParams: function () { 7 return this._innerParam+ this.publicParam; 8 } 9 } Zdrojový kód 5.2: Vytvoření třídy přes prototype

5.4.2 Definice vlastností

Některé vlastnosti objektů v aplikaci, které vyžadují např. zavo- lání určité metody tak, aby se daná změna projevila, jsou definované pomocí metody Object.defineProperties()5. Tato metoda de- finuje vlastnost pomocí get a set funkcí, chování je stejné jako např. v jazyku C#. Při nastavení některé vlastnosti (viz ukázka 5.3) se tak automaticky zavolá obslužná metoda a změna se ihned projeví.

1 SpiderChart3D.Manager.backgroundColor=0xffffff; Zdrojový kód 5.3: Změna barvy pozadí vizualizace

5. https://developer.mozilla.org/en-US/docs/Web/JavaScript/ Reference/Global_Objects/Object/defineProperties

46 5. Implementace vizualizace 5.4.3 Callback funkce

Jak bylo řečeno výše callback funkce jsou v aplikaci použity na signalizaci událostí. Při použití společně s metodami, které jsou defi- nované pomocí prototype objektu může nastat problém. Proměnná this uvnitř metody je odkaz na objekt, nad kterým je volána metoda. V případě callback funkcí se ale předává objektu funkce, kterou si uloží do své proměnné. Poté zavolá tuto proměnnou jako funkci a zde na- stává problém, neboť v proměnné this nyní není původní objekt, kde je funkce definována, ale objekt ze kterého je tato funkce volána. Řešit tento problém lze obalením callback funkce do anonymní funkce nebo přidáním volání .bind(this) při předávání callback funkce do objektu, tím se automaticky vytvoří anonymní funkce, kde se proměnná this nastaví na hodnotu danou v parametru.

5.4.4 Jmenné konvence

Pro rozlišení privátních a veřejných členů třídy jsou v této práci zavedeny kromě obecných také následující konvence:

• Názvy privátních členů objektů začínají vždy symbolem podtr- žítka. To platí jak pro proměnné, tak pro metody. • Názvy ostatních metod a vlastností začínají malým písmenem.

5.5 Vytvoření portletu pro Liferay portál

Portlety jsou webové komponenty ze kterých se vytváří obsah sa- motného portálu. Pro zobrazování vizualizací se v KYPO projektu vyu- žívá Liferay portál, kde každá vizualizace je tvořena vlastním portletem. Ukázky vizualizací jsou v přílozeB. Pro vytvoření portletu nabízí Liferay rozšíření pro vývojové pro- středí Eclipse. Stačí tak rozšíření nainstalovat do vývojového prostředí přidáním adresy repozitáře6 v položce Install New Software a násled- ným vybráním Liferay IDE ze zobrazeného seznamu. Po nainstalování

6. http://releases.liferay.com/tools/ide/latest/stable/

47 5. Implementace vizualizace rozšíření se v nabídce pro vytvoření nového projektu objeví projekt s názvem Liferay Plugin Project, kde je potřeba nastavit cestu k Plu- gin SDK, který je ke stažení na stránkách Liferay7. Dále je potřeba v položce Plugin type zvolit portlet. Ve vytvořeném projektu je složka docroot, ve které jsou zdro- jové soubory webové komponenty, tedy zdrojové kódy vizualizace a zá- kladní styly pro HTML kontejner definovaný ve view.jsp. Na rozdíl od běžné webové aplikace, kde se linkují zdrojové soubory v HTML souboru, se v portletu definují v souboru liferay-portlet.xml. Pro nahrání portletu do Liferay portálu stačí mít buď přidaný ser- ver přímo v Eclipse a přetáhnout portlet na server nebo z kontextové nabídky souboru build.xml vybrat položku Run as → Ant Build. Tato položka spustí proces, který vytvoří výsledný WAR balíček, ten poté stačí na serveru nahrát do složky deploy. Vytvořený balíček se nachází ve složce dist ve staženém Plugin SDK. Při vývoji portletu je vhodné jej synchronizovat s lokálním Liferay portálem, který je nastavený na vývojářský režim. Při tomto nastavení se neminimalizují zdrojové kódy ve výsledné webové aplikaci a používají se vždy ty nejaktuálnější. Díky tomu se změna v JavaScriptovém kódu projeví ihned po uložení.

7. http://www.liferay.com/downloads/liferay-portal/ additional-

48 6 Závěr

Cílem práce bylo vytvořit portlet pro Liferay portál obsahující pro- storovou vizualizaci časových řad, které jsou měřeny v rámci projektu Kybernetický polygon. Podmínkou bylo použití technologie WebGL a umožnit přímou 3D interakci jako je např. přibližování a rotace. Dále byla nutná synchronizace s ostatními portlety. Použitá technologie WebGL, díky které se vizualizace vykresluje pomocí hardwarové akcelerace, dovoluje používat animace, které zpří- jemňují práci s vizualizací. Pro usnadnění práce s WebGL byla použita knihovna Three.js. Interakce je řešena pohybem kamery okolo vizuali- zace pomocí kurzoru myši. Je umožněn i pohyb po časové ose a při- bližování či oddalování. Portlet také komunikuje s hlavním časovým portletem, který určuje rozsah a zdroj zobrazovaných dat. Tímto byly splněny veškeré základní požadavky a cíle. Výsledná vizualizace také obarvuje svůj povrch na základě velikosti zobrazovaných hodnot v rozsahu od zelené po červenou barvu. Dále nabízí široké možnosti modifikace pomocí definovaných vlastností a ve- řejného rozhraní pro ovládání vizualizace. Zdrojový kód aplikace je psán objektově s ohledem na přehlednost v případě nutnosti budoucí modi- fikace. Tyto jmenované vlastnosti společně s přiloženou dokumentací usnadní případné další rozšíření aplikace pro potřeby projektu Kyber- netický polygon. V textu práce je nejprve popsán projekt Kybernetický polygon a poté je probrána technologie WebGL s ukázkou pro vykreslení čtverce. Na konci kapitoly je zmínka o některých pomocných knihovnách, ze kte- rých byla vybrána knihovna Three.js. Této pomocné knihovně se věnuje celá čtvrtá kapitola, ve které jsou popsány základní principy pro její po- užití včetně ukázek. Na závěr je umístěna kapitola věnující se samotné implementaci vizualizace.

49 Seznam obrázků

2.1 Architektura Kybernetického polygonu...... 5 3.1 Čtverec vykreslený s WebGL...... 19 4.1 Rotující krychle se stínem a texturou...... 24 4.2 Perspektivní projekce...... 26 4.3 Ortografická projekce...... 27 4.4 Ukázky geometrií...... 29 4.5 UV souřadnice...... 31 4.6 Normály stěn a vrcholu...... 32 4.7 Rozdíl mezi SmoothShading a FlatShading ...... 33 5.1 Vizualizace náhodně vygenerovaných dat...... 37 5.2 Diagram tříd ...... 39 5.3 Struktura souborů ...... 41 5.4 Barevný model HSL ...... 43 5.5 Detail obarvování povrchu a přizpůsobení dat ...... 44 A.1 Model lidského těla v aplikaci Zygote body ...... 53 A.2 3D pohled na dům v aplikaci wanaplan...... 54 B.1 Časový porlet a portlet s 3D vizualizací...... 55 B.2 Portlet pro vizualizaci síťové topologie ...... 55 B.3 Portlet pro vizualizaci hvězdicového grafu...... 56 B.4 Portlet vizualizující spojnicové grafy ...... 56

50 Seznam zdrojových kódů

3.1 Získání WebGL kontextu...... 13 3.2 Nastavení hranice vykreslování...... 13 3.3 Vytvoření dat pro vykreslení...... 14 3.4 Definice transformačních matic...... 16 3.5 Vertex a fragment shader...... 17 3.6 Finální vykreslení čtverce...... 18 4.1 Základní kostra HTML dokumentu pro Three.js..... 21 4.2 Čtverec pomocí knihovny Three.js...... 22 4.3 Modifikace pro zobrazení krychle se stínem a texturou.. 23 4.4 Fuknce pro pro cyklus animovaného vykreslování..... 25 4.5 Obecné vytvoření ortografické kamery...... 28 5.1 Vytvoření třídy jen konstruktorem...... 45 5.2 Vytvoření třídy přes prototype...... 46 5.3 Změna barvy pozadí vizualizace...... 46

51 Seznam použité literatury

[1] Projekt kypo - analýza a návrh architektury, technická zpráva, 2013. Přiloženo v elektronické příloze.

[2] Andreas Anyuru. Professional WebGL Programming: Developing 3D Graphics for the Web. John Wiley & Sons, 2012.

[3] Caniuse.com. Can i use webgl?, 2014. URL http://caniuse. com/webgl. [Online; cit. 16.4.2014].

[4] Khronos Group. Opengl.org, 2014. URL http://www.opengl. org. [Online; cit. 18.4.2014].

[5] Khronos.org. The khronos group, 2014. URL https://www. khronos.org/. [Online; cit. 15.4.2014].

[6] Mozilla.org. Firefox releases, 2014. URL http://www. mozilla.org/en-US/firefox/releases/. [Online; cit. 18.4.2014].

[7] Opera.com. Opera history, 2014. URL http://www.opera. com/docs/history/. [Online; cit. 18.4.2014].

[8] Tony Parisi. WebGL: Up and Running. O’Reilly Media, 2012. ISBN 978-1-4493-2357-8.

[9] Jiří Žára, Bedřich Beneš, Jiří Sochor, and Petr Felkel. Moderní počítačová grafika. Computer Press, Praha, 2. edition, 2005. ISBN 80-251-0454-0.

[10] Wikipedia. Safari version history, 2014. URL http://en. wikipedia.org/wiki/Safari_version_history. [On- line; cit. 15.4.2014].

[11] Wikipedia.org. Wikipedia chrome, 2014. URL http: //en.wikipedia.org/wiki/Google_Chrome. [Online; cit. 18.4.2014].

[12] Nicholas C. Zakas. JavaScript pro webové vývojáře. Computer Press, 2009. ISBN 978-8-02-512509-0.

52 A Ukázky WebGL aplikácí

Některé WebGL aplikace jsou spíše ukázkou možností, co vše je možné v prostředí webového prohlížeče udělat. Jiné jsou naopak smys- luplné a náležitě plní svůj účel. Mnoho zajímavých ukázek WebGL lze najít např. na stránkách Chrome Experiments1.

A.1 Zygote body

Zygote body2 je webová aplikace zobrazující model člověka. Největší síla se však skrývá v posuvníku na levé straně, kde si uživatel může navolit hloubku, od které se mají zobrazovat orgány. Na obrázku A.1 je ukázka modelu bez kůže. Po kliknutí na daný orgán se zobrazí popi- sek s latinským názvem a samozřejmostí také je otáčení modelu, které zabezpečí detailní pohled ze všech úhlů.

Obrázek A.1: Model lidského těla v aplikaci Zygote body

1. http://www.chromeexperiments.com/webgl/ 2. http://www.zygotebody.com/

53 A. Ukázky WebGL aplikácí A.2 Wannaplan

Další zajímavá ukázka je aplikace Wanaplan3, která z prohlížeče udělá editor pro návrh domů a interiérů. Aplikace dovoluje vytvářet ná- kres půdorysu a z nich generuje trojrozměrný náhled (viz obrázek A.2), kde si uživatel může přidávat různé bytové doplňky a dekorace.

Obrázek A.2: 3D pohled na dům v aplikaci wanaplan

A.3 Chrome World Wide Maze

Aplikace od nazvaná Chrome World Wide Maze4 vytvoří ze zadané webové stránky trojrozměrné bludiště, úkolem je pro- jít skrz. Zajímavostí je také možnost ovládat aplikaci pomocí mobilního telefonu, který se s webem spáruje a lze jej poté používat jako herní ovladač. Aplikace svými možnostmi spíše demonstruje čeho je možné s vyu- žitím WebGL a dalších moderních technologií dosáhnout.

3. http://www.wanaplan.com/en/plan/ 4. https://chrome.com/maze/

54 B Virtualizační portlety

Obrázek B.1: Časový porlet a portlet s 3D vizualizací

Obrázek B.2: Portlet pro vizualizaci síťové topologie

55 B. Virtualizační portlety

Obrázek B.3: Portlet pro vizualizaci hvězdicového grafu

Obrázek B.4: Portlet vizualizující spojnicové grafy

56 C Dokumentace

Originál níže přiložené dokumentace je v elektronické příloze.

57 SpiderChart3D.Managers. Manager

M anager. js, line 47 new SpiderChart3D.Managers.Manager(parameters) Creates an instance of main Manager.

Na me Ty pe Descr iption parameters object Object for optional parameters. Na me Ty pe Descr iption provider IProvider Data provider. container String HTML container id. heightRatio number Defines height/width ratio, width scene is container width (default is 0.35). backgroundColor number Background color (default is 0xE6E6E6). size number General size for ChartManager and GlassManager. newDataRenderedCallback function Function that is called when new data are received.

Properties:

Na me Ty pe Descr iption newDataRenderedCallback function Function that is called when new data are received. chartManager ChartManager ChartManager instance. cameraManager CameraManager CameraManager instance. glassManager GlassManager GlassManager instance. heightRatio number Defines height/width ratio, width scene is container width (default is 0.35). backgroundColor number Background color (default is 0xE6E6E6). size number General size for ChartManager and GlassManager.

Author: Petr Jelínek (petaniss@.com)

Methods

M anager. js, line 263 private _cancelFullScreen() Disable fullscreen mode.

M anager. js, line 378 private _endRenderLoop() Ends render loop. When _startRenderLoop method is called more times, you need to call this method more times too.

M anager. js, line 288 private _goFullScreen() Activates fullscreen mode.

M anager. js, line 104 private _init() Main initial method. Calls all other initial methods and creates renderer object.

M anager. js, line 140 private _initCamera() Creates CameraManager instance.

M anager. js, line 129 private _initChart() Creates ChartManager instance.

M anager. js, line 157 private _initGlass() Creates GlassManager instance. M anager. js, line 178 private _initLight() Creates lights for scene.

M anager. js, line 301 private _initMouseEvents() Initialize mouse events and map them to the cameraManager.

M anager. js, line 252 private _isFullScreen() {boolean} Checks if fullscreen mode is activated.

M anager. js, line 280 private _quadrantChanged(q) Help method, called when camera quadrant is changed.

Na me Ty pe Descr iption q

M anager. js, line 228 private _render() Method that makes render cycle.

M anager. js, line 367 private _startRenderLoop() Starts render loop.

M anager. js, line 206 drawDataRange(from, to) Calls data preparing for a given data range.

Na me Ty pe Descr iption from number From timestamp. to number To timestamp.

M anager. js, line 218 drawProviderData() Draws current data in the provider.

M anager. js, line 342 fixHeight() Fixes height according to the width

M anager. js, line 191 setNewPhenomenons(phenomenons) Sets new phenomenons. Updates provider and calls method for new data preparing.

Na me Ty pe Descr iption phenomenons

M anager. js, line 239 toggleFullScreen() Toggle full screen mode. This method must be called by user activity (button click, etc). SpiderChart3D.Managers. ChartManager

C hartM anager. js, line 45 new SpiderChart3D.Managers.ChartManager(parameters) Creates an instance of ChartManager.

Na me Ty pe Descr iption parameters object Object for optional parameters. Na me Ty pe Descr iption spaceBetweenCrossSections Number Space between cross-sections. maxSize Number Max chart size. renderCallback function Function that is called when ChartManager needs render scene.

Properties:

Na me Ty pe Descr iption spaceBetweenCrossSections number Space between cross-sections. maxSize number Max chart size. renderCallback function Function that is called when ChartManager needs render scene. sceneObject object Object of the chart for THREE.Scene.

Author: Petr Jelínek ([email protected])

Methods

C hartM anager. js, line 198 private _addCloseVertex(matrix) Help method that adds closing vertex for calculating closed spline.

Na me Ty pe Descr iption matrix Array. Matrix of vertices.

C hartM anager. js, line 91 private _countPlaneMesh(points) {THREE.Mesh} Creates opening or closing plane for chart.

Na me Ty pe Descr iption points Array Array of THREE.Vertex3 points.

Returns: Closing or opening plane.

C hartM anager. js, line 214 private _countVertices(data, angles, lastCountedIndex) {Array.} Calculates final vertices positions.

Na me Ty pe Descr iption data Array. Rescaled values. angles Array Counted angles. lastCountedIndex number Last index to count.

Returns: Calculated vertices.

C hartM anager. js, line 269 private _geomVertexColor(geom) Sets colors for each vertex in geometry.

Na me Ty pe Descr iption geom Object THREE.Geometry object

C hartM anager. js, line 334 private _getChartMesh(vertices) {THREE.Object3D} Creates final chart object.

Na me Ty pe Descr iption vertices Array. Prepared vertices.

Returns: chart object.

C hartM anager. js, line 295 private _getGeometry(vertices) {THREE.Geometry} Calculates geometry from given vertices.

Na me Ty pe Descr iption vertices Array. Prepared vertices.

Returns: Calculated chart geometry.

C hartM anager. js, line 140 private _getPointColor(point) {THREE.Color} Calculates color for given point. This color is used for coloring the whole chart by the vertex coloring mechanism.

Na me Ty pe Descr iption point THREE.Vector3 Point for coloring.

Returns: Color of point.

C hartM anager. js, line 363 private _getRescaledValues(data) {Array.} Rescales given data to fit to chart size. Rescaling is counting by max value for each phenomenons or by data.maxValues array if not empty.

Na me Ty pe Descr iption data SpiderChart3D.Managers.IProvider.data

Returns: rescaled values

C hartM anager. js, line 121 private _getSplinePoints(points, closed) {Array} Creates spline from given points.

Na me Ty pe Descr iption points Array Array of THREE.Vertex3 points. closed boolean spline is closed (circle).

Returns: Array of spline points.

C hartM anager. js, line 249 private _getWireMaterial(crossLength, chartLength) {Object} Creates wired material for chart.

Na me Ty pe Descr iption crossLength number Number of cross-section vertices. chartLength number Number of vertices in length.

Returns: THREE material object.

C hartM anager. js, line 161 private _horizontalSplineMatrix(matrix, closed) {Array} Makes spline from horizontal lines of matrix.

Na me Ty pe Descr iption matrix Array. Matrix of vertices. closed boolean spline is closed (circle).

Returns: Matrix with horizontal splines.

C hartM anager. js, line 180 private _splineMatrix(matrix) {Array.} Makes spline from horizontal and vertical lines of matrix.

Na me Ty pe Descr iption matrix Array. Matrix of vertices.

Returns: Matrix Matrix of vertices.

C hartM anager. js, line 393 recountChart(data) Recalculates chart. Chart is the child of the mainObject so it is not necessary to add it to the scene again.

Na me Ty pe Descr iption data SpiderChart3D.Managers.IProvider.data SpiderChart3D.Managers. GlassManager

G lassM anager. js, line 68 new SpiderChart3D.Managers.GlassManager(parameters) Creates an instance of GlassManager.

Na me Ty pe Descr iption parameters object Object for optional parameters. Na me Ty pe Descr iption animEasing TWEEN.Easing Animation effect. animTime number Wall animation length. timelineGlassLength number Timeline walls length. glassOpacity number Opacity of walls material (value 0 to 1). glassColor number Walls color (0x004050 is default). lineColor number Lines color (0x000000 is default). fontColor number Fonts color (0x000000 is default). spaceBetweenCrossSections number Space between cross-sections. fontResolutionMultiplier number Multiplier of font resolution. size number Edge size of front wall. Others sizes are calculated from this value. cameraQuadrant SpiderChart3D.Utils.Quadrant Quadrant of camera position for correctly setting walls. axisLabelSize number Axis label size defined in percentage of main size. timestampLabelSize number Timestamps label size defined in percentage of main size. font String Labels font (Arial is default). onAnimStartCallback function Function that is called on any animation start. onAnimEndCallback function Function that is called on any animation end. renderCallback function Function that is called when GlassManager needs render scene.

Properties:

Na me Ty pe Descr iption onAnimStartCallback function Function that is called on any animation start. onAnimEndCallback function Function that is called on any animation end. renderCallback function Function that is called when GlassManager needs render scene. animEasing TWEEN.Easing Animation effect. animTime number Wall animation length. quadrant SpiderChart3D.Utils.Quadrant Quadrant of camera position for correctly setting walls. size number Edge size of front wall. Others sizes are calculated from this value. fontResolutionMultiplier number Multiplier of font resolution. spaceBetweenCrossSections number Space between cross-sections. timelineGlassLength number Timeline walls length. glassOpacity number Opacity of walls material (value 0 to 1). glassColor number Walls color (0x004050 is default). lineColor number Lines color (0x000000 is default). fontColor number Fonts color (0x000000 is default). axisLabelSize number Axis label size defined in percentage of main size. timestampLabelSize number Timestamps label size defined in percentage of main size. font String Labels font (Arial is default). sceneObject object Object of the walls for THREE.Scene.

Author: Petr Jelínek ([email protected]) Members

readonly DestEnum number Destination enum. Properties:

Na me Ty pe Def a ult Descr iption TOP number 0 BOTTOM number 1 LEFT number 2 RIGHT number 3

Methods

G lassM anager. js, line 552 private _createLabel(text, size) {THREE.Sprite} Creates label object.

Na me Ty pe Descr iption text String size number

Returns: Label object

G lassM anager. js, line 286 private _fixFrontLabelPosition(label) Fixes positions of labels around front wall.

Na me Ty pe Descr iption label

G lassM anager. js, line 474 private _getAxisLabels(axis, endPoints) {THREE.Object3D} Makes object with axis labels.

Na me Ty pe Descr iption axis Array String array of labels. endPoints Array Array of end points.

Returns: Object with labels.

G lassM anager. js, line 450 private _getAxisLines(endPoints) {THREE.Object3D} Makes object with axis lines.

Na me Ty pe Descr iption endPoints Array Array of end points.

Returns: Object with lines.

G lassM anager. js, line 501 private _getLine(pointA, pointB) {THREE.Line} Makes line from pointA to pointB

Na me Ty pe Descr iption pointA THREE.Vector3 Start point. pointB THREE.Vector3 End point. Returns: Created line.

G lassM anager. js, line 331 private _getLineEndPoint(angle) {THREE.Vector2} Calculates the end point of the line in the front wall at given angle.

Na me Ty pe Descr iption angle Array Line angle.

Returns: End of line.

G lassM anager. js, line 372 private _getLineEndPoints(angles) {Array.} Same as _getLineEndPoint but for array.

Na me Ty pe Descr iption angles Array Line angles array.

Returns: End of lines array.

G lassM anager. js, line 426 _makeGlassMesh() Makes object of front glass wall.

G lassM anager. js, line 306 _makeGlassWall() {THREE.Mesh} Makes basic timeline wall. From this wall is created the horizontal and the vertical wall.

Returns: Glass wall

G lassM anager. js, line 642 private _moveHorizontalWall(dest) Moves the horizontal wall to given destination.

Na me Ty pe Descr iption dest DestEnum Destination.

G lassM anager. js, line 593 private _moveVerticalWall(dest) Moves the vertical wall to given destination.

Na me Ty pe Descr iption dest DestEnum Destination.

G lassM anager. js, line 238 _objectsInit() Initialization function that sets basic objects (front wall, horizontal and vertical wall and positions). This function must be called at the end of the constructor.

G lassM anager. js, line 219 private _removeAllChildren() Clears all inner objects in the main object of the scene.

G lassM anager. js, line 386 _setInitPositions() Fixes initial wall position which depends on this._quadrant and sets default positions of labels and lines.

G lassM anager. js, line 519 private _swapLinesAndLabels(lines, labels) Swaps old lines and labels with new ones. Na me Ty pe Descr iption lines New lines. labels New labels.

G lassM anager. js, line 229 private _updateLinesAndLabels() Recalculates all lines and labels. This method is automatically called when some font properties change.

G lassM anager. js, line 188 private _updateQuadrant(newValue) This method is automaticaly called when quadrant property changes.

Na me Ty pe Descr iption newValue new quadrant

G lassM anager. js, line 694 removeChartInfo() Removes axis lines, axis labels, timeline lines and timeline labels.

G lassM anager. js, line 790 updateAllObjects() Updates and recalculates all objects in this main object.

G lassM anager. js, line 703 updateAxis(axis) Updates lines and labels on front wall.

Na me Ty pe Descr iption axis Array. Array of new labels.

G lassM anager. js, line 739 updateTimestamps(timestamps) Updates timeline lines and labels.

Na me Ty pe Descr iption timestamps Array. SpiderChart3D.Managers. CameraManager

C ameraM anager. js, line 74 new SpiderChart3D.Managers.CameraManager(camera, parameters) Creates an instance of CameraManager.

Na me Ty pe Descr iption camera THREE.PerspectiveCamera Required Three.js camera object. parameters object Object for optional parameters. Na me Ty pe Descr iption radius Number Default camera radius. alpha Number Default alpha camera angle. theta Number Default theta camera angle. z Number Default z position of the camera. cameraMoveMultiplier Number Multiplier of the camera move. cameraMoveTimeZ Number Length of the camera move animation over z position. cameraResetTime Number Length of the camera move to default position. cameraZoomTime Number Length of the camera zoom. cameraZoomMultiplier Number Multiplier of the camera zoom. onAnimStartCallback function Function that is called on any animation start. onAnimEndCallback function Function that is called on any animation end. onQuadrantChangeCallback function Function that is called on camera quadrant change. (SpiderChart3D.Utils.Quadrant first param) renderCallback function Function that is called when CameraManager needs render scene.

Properties:

Na me Ty pe Descr iption defaultRadius number Default radius for reset camera animation. defaultAlpha number Default alpha angle for reset camera animation. defaultTheta number Default theta angle for reset camera animation. defaultZ number Default z position for reset camera animation. cameraMoveMultiplier number Multiplier of the camera move. cameraMoveTimeZ number Length of the camera move animation over z position. cameraResetTime number Length of the camera move to default position. cameraZoomTime number Length of the camera zoom. cameraZoomMultiplier number Multiplier of the camera zoom. alpha number Current camera alpha angle. theta number Current camera theta angle. radius number Current camera radius. z number Current camera z position. onAnimStartCallback function Function that is called on any animation start. onAnimEndCallback function Function that is called on any animation end. onQuadrantChangeCallback function Function that is called on camera quadrant change. (SpiderChart3D.Utils.Quadrant first param) renderCallback function Function that is called when CameraManager needs render scene.

Author: Petr Jelínek ([email protected])

Example

var cameraController = new CameraManager(camera, { onAnimStartCallback: startRenderLoop, onAnimEndCallback: endRenderLoop });

Methods

C ameraM anager. js, line 195 private _cameraUpdate() Calculates the camera coordinates using the alpha and theta angles, radius and z property.

C ameraM anager. js, line 227 private _endAllAnim() Ends move and zoom animation. This method is called by reset animation method.

C ameraM anager. js, line 147 private _fixAngles() Fixes angles overflow, negative angles and blocks forbidden angles.

C ameraM anager. js, line 166 private _fixDefaultAnglesOverflow() Same as _fixAngles method, but it fixes default angles.

C ameraM anager. js, line 266 private _getCorrectedResetAngle(defaultAngle, currentAngle) {Number} Detects the shortest path and prepares the default angle for the animation to use it.

Na me Ty pe Descr iption defaultAngle Number Default alpha or theta angle. currentAngle Number Current alpha or theta angle.

Returns: Corrected default angle.

C ameraM anager. js, line 238 private _getQuadrant() {SpiderChart3D.Utils.Quadrant} Detects by the angle in which quadrant the camera is located

Returns: Quadrant

C ameraM anager. js, line 185 private _propertyUpdate() Helper method called when changing some properties.

C ameraM anager. js, line 313 cameraMove(x, y) Move with camera position. Parameters affects alpha and theta angle of the camera. cameraMoveStart method must be called before this method. To end the movement of the camera you have to call cameraMoveStop method.

Na me Ty pe Descr iption x Number Value that affects theta angle. y Number Value that affects alpha angle.

C ameraM anager. js, line 293 cameraMoveStart(x, y) After calling this method you can move the camera with cameraMove method. This method sets initial values for the movement of the camera. You cannot move the the camera when the animation of the camera reset is in progress.

Na me Ty pe Descr iption x Number Initial x coordinate. y Number Initial y coordinate.

C ameraM anager. js, line 334 cameraMoveStop() Ends the movement of the camera. It is called after the cameraMoveStart method. cameraMoveToZ(z) C ameraM anager. js, line 348 Starts animation of the movements over z axis to given z coordinate. When you call this method again before end of the animation, the previous animation is automatically terminated and a new one will start. This method does nothing when the animation of the camera reset is in progress.

Na me Ty pe Descr iption z Number The z coordinates of the destination.

C ameraM anager. js, line 377 cameraResetPosition() Starts animation of the movement of the camera to default coordinates. Default coordinates are calculated by parameters in the constructor. This method terminates all other animations (because of conflict of parameters of the animation).

C ameraM anager. js, line 421 cameraZoom(increment) Starts animation which changes the radius of the camera by adding increment to the current radius. When you call this method again before end of the animation, the previous animation is automatically terminated and a new one will start. This method does nothing when the animation of the camera reset is in progress.

Na me Ty pe Descr iption increment Number Increment of the radius. SpiderChart3D.DataProviders. IProvider

IPro vider. js, line 36 abstract new SpiderChart3D.DataProviders.IProvider() A data provider interface. Properties:

Na me Ty pe Descr iption data Object Data holder. Properties

Na me Ty pe Descr iption phenomenons Array. Array of phenomenons. timestamp Array. Array of timestamps. values Array. Array of values. maxValues Array. Array of maxValues (for better data scaling).

Methods

IPro vider. js, line 53 prepareData(from, to, prepared) Starts preparing data. When data will be ready callback prepared function will be called.

Na me Ty pe Descr iption from Number timestamp to Number timestamp prepared function

IPro vider. js, line 59 setNewPhenomenons(phenomenons) Sets new phenomenons. The change takes effect after calling prepareData method.

Na me Ty pe Descr iption phenomenons Array. SpiderChart3D.DataProviders. KypoProvider

Kypo Pro vider. js, line 36 new SpiderChart3D.DataProviders.KypoProvider() Kypo project data provider. This class implements SpiderChart3D.DataProviders.IProvider. Properties:

Na me Ty pe Descr iption data Object Data holder. Properties

Na me Ty pe Descr iption phenomenons Array. Array of phenomenons. timestamp Array. Array of timestamps. values Array. Array of values. maxValues Array. Array of maxValues (for better data scaling).

apiUrl String Kypo api server url. link Number Link indicates, which link we want from kypo api.

Methods

Kypo Pro vider. js, line 60 private _formatNewData(data) Formats received data to application format described by IProvider.

Na me Ty pe Descr iption data Object from Kypo REST api.

Kypo Pro vider. js, line 81 private _makeRangeUrl(startTimestamp, endTimestamp) {string} Makes url for data request.

Na me Ty pe Descr iption startTimestamp Number start timestamp. endTimestamp Number end timestamp.

Returns: for data request.

Kypo Pro vider. js, line 95 prepareData(from, to, prepared) Starts preparing data. When data are ready callback prepared function will be called.

Na me Ty pe Descr iption from Number Start timestamp. to Number End timestamp. prepared function Callback function.

Kypo Pro vider. js, line 124 setNewPhenomenons(phenomenons) Sets new phenomenons. The change takes effect after calling prepareData method.

Na me Ty pe Descr iption phenomenons Array. Array of phenomenons. SpiderChart3D.DataProviders. TestProvider

TestPro vider. js, line 35 new SpiderChart3D.DataProviders.TestProvider() Generator of random values. Values ​are generated according to input range and phenomenons. This class implements SpiderChart3D.Managers.IProvider. Properties:

Na me Ty pe Descr iption data Object Data holder. Properties

Na me Ty pe Descr iption phenomenons Array. Array of phenomenons. timestamp Array. Array of timestamps. values Array. Array of values. maxValues Array. Array of maxValues (for better data scaling).

Methods

TestPro vider. js, line 55 prepareData(from, to, prepared) Starts preparing data. When data will be ready callback prepared function will be called.

Na me Ty pe Descr iption from Number Start timestamp. to Number End timestamp. prepared function Callback.

TestPro vider. js, line 75 setNewPhenomenons(phenomenons) Set new phenomenons. The change takes effect after calling prepareData method.

Na me Ty pe Descr iption phenomenons Array. Array of phenomenons.