Budoucnost vektorové grafiky na webu, 5. část

Minule jsme si předváděli jak využít technologie XSLT k velkosériové výrobě standardní vektorové grafiky z tabulkových dat ve formátu XML. Dnes budeme pokračovat ve stejném stylu - nebudu vás trápit suchou a otravnou teorií, namísto toho se formou podrobných komentářů a popisu funkce reálného příkladu budu snažit ukázat další zajímavé možnosti moderní technologie pro web budoucnosti.

XSLT podruhé

Výstupem minulého cvičného příkladu byl statický vektorový graf. Jako slibované třešničky navrch přidáme něco animací podle receptury SMIL. Aneb trocha pohybu nikdy neuškodí...



Opera 9: Vektorový animovaný graf vygenerovaný technikou XSLT (XML ukázka)

Firefox 1.5 SMIL animace bohužel ještě neumí, pro vyzkoušení příkladu proto prosím použijte Operu 9! Nepodporované prvky by měly být prohlížeči prostě ignorovány, proto tu existuje bezproblémová zpětná kompatibilita a příklad se zobrazí samozřejmě i ve Firefoxu - ovšem staticky.

SMIL: No scripting, please!

Toto je přesně ten případ, kdy se ukazuje síla deklarativních animací SVG-SMIL. Žádné skripty, nic tak komplikovaného. Pro demonstraci jsem použil asi nejjednodušší variantu: Prvek animate attributeName="height" - tím prohlížeči řekneme že má animovat hodnotu atributu "height".

Časování SMIL animace

Tyto atributy definují časování: begin="column{$pos - 1}.end" dur="1s". Vaší pozornosti se doporučuje výraz nastavující hodnotu atributu "begin". Ten je nastaven tak, že aktuální animační prvek bude spuštěn po ukončení animace předcházejícího sloupečku grafu. Jinými slovy: Sloupečky postupně, jeden po druhém, "rostou" z nuly až na maximální hodnotu uvedenou v tabulce. (Zápis ve složených závorkách je výrazem jazyka XSLT.)

Povšimněte si i toho, že první sloupec grafu má start (atr. "begin") pomocí podmínkové konstrukce when test="$pos = 1" nastaven odlišně - na nulovou hodnotu. Je to vcelku logické, neboť není žádný předcházející prvek, na který bychom mohli časově navazovat.

Meze animovaných hodnot

Následující dva parametry elementu animate říkají v jakých mezích se bude měnit hodnota animovaného atributu: from="0" to="{$colHeight}". (Znovu: Ve složených závorkách je výraz XSLT - v tomto případě v kódu o něco výše nadefinovaná proměnná obsahující výšku sloupce.)
Kompletní XSLT kód generující na výstupu jeden animovaný obdélník vypadá takto:

<!-- animovaný sloupec pro kladnou hodnotu -->
<rect x="{3*$pos}" y="{50-$colHeight}" width="2" height="{$colHeight}"
 fill="green" opacity=".5" stroke="none">
  <set begin="0s" attributeName="height" to="0"/>
  <xsl:choose>
  <xsl:when test="$pos = 1">
  <animate id="column{$pos}" begin="0.01s"
   attributeName="height" fill="freeze"
   dur="0.3s" from="0" to="{$colHeight}"/>
  </xsl:when>
  <xsl:otherwise>
  <animate id="column{$pos}" begin="column{$pos - 1}.end"
   attributeName="height" fill="freeze"
   dur="0.3s" from="0" to="{$colHeight}"/>
  </xsl:otherwise>
  </xsl:choose>
  <animate begin="column{$pos}.begin"
   attributeName="fill" fill="freeze"
   dur="1.5s" from="white" to="green"/>
</rect>

Co si počneme bez animací?

Naším původním kreativním záměrem bylo nechat sloupce postupně objevovat ("vyrůstat" z nuly) - současně ovšem musíme vygenerovat sloupečky se správnou (nenulovou) výškou pro prohlížeče, jež neumí SMIL. Z těchto příčin bylo nutno dodat do SVG kódu navíc jeden zdánlivě nadbytečný SMIL prvek set begin="0s" attributeName="height" to="0", který všechny prvky v čase 0 s skryje (resp. zmenší na výšku 0) a umožní tak, aby animování datových sloupků probíhalo původně zamýšleným způsobem.

SVG-SMIL: Variabilita bez omezení

Pravěpodobně je všem dobře znám fakt, že norma SVG resp. SMIL umožňuje prakticky libovolné kombinování animačních elementů, které přitom mohou měnit téměř jakýkoliv atribut. V tuto chvíli je všem nejspíše zřejmé, že lze dosáhnout v podstatě nekonečné množství různých pohybových, barvových a dokonce i interaktivních efektů. Atribut begin můžete nadefinovat klidně třeba i takto: begin="mouseover" - a není třeba asi ani dodávat, že taková animace se spouští při ukázání myší na dotyčný objekt.

Výpočet správného souřadnicového systému

V posledku se podíváme na možnost automatického výpočtu souřadnicového systému.

Na výběr máme dokonce dvě možnosti. Krom klasické "programátorské" metody přepočtu souřadnic tak, aby se vešly do zvoleného rozsahu hodnot, máme k dispozici ještě SVG atribut "viewBox", který nám umožní nastavit souřadnice uvnitř SVG prostoru zcela libovolně a naprosto nezávisle na fyzickém rozlišení použitého zobrazovacího zařízení. O přepočet na reálné obrazové body, například displeje mobilního telefonu, se postará prohlížeč, aniž bychom se o to vůbec museli zajímat.

Nastavení šířky grafu

Tímto XPath výrazem spočítáme řádky v tabulce. Přizpůsobení je v demonstrační ukázce provedeno tak, že se mění proporce (šířka) grafu, ale nyní už budete zcela jistě schopni si sami kód upravit třeba tak, aby poměr stran grafu zůstal stejný při jakémkoliv počtu údajů v tabulce.

<xsl:variable name="width"
  select="3*(2+count(//ss:Worksheet[1]//ss:Table[1]/ss:Row))" />

Nalezení hodnotového minima a maxima

Znalost minimální a maximální hodnoty nám umožní automaticky přizpůsobit měřítko osy Y a využít tak celý dynamický rozsah hodnot.
Na tomto místě se předem poctivě přiznávám - nejsem vševědoucí odborník na XSLT, takže mé řešení nemusí být optimální. Nekamenujte mne za něj prosím. Ale pokud nabídnete lepší řešení, jistě to ocení spousta čtenářů.

K řešení jsem použil schopnost XSLT řadit sekvence hodnot. Instrukce řazení sort data-type="number" order="ascending" musí být umístěna uvnitř "smyčky" for-each. Atribut select="//ss:Worksheet[1]//ss:Table[1]/ss:Row/ss:Cell[2]/ss:Data[1]" smyčky definuje rozsah vstupních hodnot, které je třeba seřadit. (V tomto konkrétním případě: V první tabulce na prvním listu druhý sloupec hodnot.) Výsledná programová konstrukce proto vypadá následovně:

<xsl:variable name="ymin">
<xsl:for-each select="//ss:Worksheet[1]//ss:Table[1]/ss:Row/ss:Cell[2]/ss:Data[1]">
  <xsl:sort data-type="number" order="ascending" />
  <xsl:if test="position()=1">
    <xsl:value-of select="."/>
  </xsl:if>
</xsl:for-each>
</xsl:variable>

Uvnitř smyčky je test if test="position()=1", který navrátí první hodnotu srovnané datové série. Jelikož data jsou v tu chvíli seřazena od nejmenší k největší hodnotě, tak navrácená první hodnota bude hledaným minimem.

Docela důležitým detailem, na který byste měli pamatovat při vytváření vlastního kódu, je umístění celého poměrně složitého algoritmu uvnitř XSLT proměnné:

<xsl:variable name="ymin">
...
</xsl:variable>

Rozhodně není náhoda, že proměnnou nepřiřazujeme uvnitř podmíněné instrukce if test="position()=1", k čemuž by nás mohly svádět např. zkušenosti s JavaScriptem. Takto definovaná proměnná by podle normy XSLT platila pouze uvnitř podmínkového bloku.

Hledání maximální hodnoty je dle předpokladu plně analogické - pouze vezmeme poslední hodnotu v seřazené řadě: if test="position()=last()".

Spočítané hodnoty bychom pak mohli zužitkovat třeba při výpočtu výšky a polohy sloupků grafu, popř. už při nastavování souřadnicového systému uvnitř SVG bloku: svg viewBox="0 {$ymin} {$width} {$ymax - $ymin}" xmlns="...".

Shrnutí

Toť prozatím vše. Snažil jsem se vám v dnešním textu prakticky dokázat, jak můžete pomocí poměrně málo známé a využívané technologie XSLT získat moc nad nepřehlednou záplavou dat z tabulkových kalkulátorů a databází. Jakkoli málo známá, XSLT je dospělou technologií pro web budoucnosti schopnou reálného nasazení v praxi již dnes.

Příště se podíváme na zoubek praktickému problému číslo 1 - totiž jak zařídit, aby SVG obsah byl dostupný maximálnímu procentu prohlížečů. Budeme přitom nuceni svést souboj s majoritním windowsovským prohlížečem Explorer.

Odkazy, zdroje

1. Standard SVG (EN): http://www.w3.org/Graphics/SVG/
2. Podrobný kurz SVG: http://interval.cz/serialy/kurz-svg-tvorba-vektorove-grafiky-v-xml/
3. SVG animace: http://interval.cz/clanky/kurz-svg-neni-to-flash-a-prece-se-toci/
4. XSLT výuka:  http://www.zvon.org/xxl/XSLTutorial/Output/example1_ch1.html
5. Podrobné informace o XSLT: http://www.kosek.cz/clanky/swn-xml/xsl.html
6. Open Office 2: http://openoffice.cz/
7. Opera 9: http://snapshot.opera.com/
8. Firefox 1.5: http://www.czilla.cz/produkty/firefox/stahnout.html
9. Safari 2 + SVG: http://webkit.opendarwin.org/projects/svg/index.html

Váš názor Další článek: Časopis Connect! pro profesionály celý rok zdarma

Témata článku: , , , , , , , , , , , , , , , , , , , , , ,