skok na hlavní menu | menu sekce Aktuality

Úvod » Aktuality » Dynamicky generované interaktivní grafy na vašem webu

Dynamicky generované interaktivní grafy na vašem webu

V tomto článku popisujeme své praktické zkušenosti s generováním grafů pro prezentaci statistických dat na webech. Popisovány jsou možnosti na straně klienta.


Klasické a serverem generované obrázky

Internet je plný obrázků prezentovaných na webu např. pomocí elementu img. Obvykle vznikají mimo server (vyfotografováním, nakreslením apod.) a jsou pak na serveru jednoduše uloženy. S technologickým vývojem se stále častěji objevují obrázky, které bychom na serveru jako uložený soubor JPG hledali těžko – máme zde na mysli především grafy a další matematicky popsatelné struktury. Vývojáři serverových aplikací mají v PHP dostupnou např. knihovnu GD, která obrázek generuje pomocí jimi napsaného algoritmu, tedy matematického popisu, jak na kreslicí plátno vyskládat různé grafické objekty.

Generování obrázků na straně klienta

Tento článek se zabývá technologiemi, u kterých se kód pro generování obrázku vykonává až na straně klienta, tedy mimo webový server. Generování obrázků na straně klienta umožňuje JavaScript. S ním pak existují řešení, díky kterým lze generovat širokou škálu krásných interaktivních grafů.

Článek jsme sice mohli nazvat např. Google grafy (popisovány níže), které na první pohled umí úplně všechno, ovšem v praxi je situace taková, že některou funkcionalitu nalezneme pouze u jiných knihoven. Podle našich zkušeností často po hodinách ladění kódu splňujícího 95 % požadavků narazíme na vlastnost, kterou daná technologie buď vůbec nepodporuje, nebo ji nejde v dokumentaci či návodech a diskusích v rozumném čase najít. Často pak nezbývá, než dosavadní práci opustit a použít knihovnu jinou.

Google grafy

Společnost Google k velké radosti vývojářů uvolnila rozsáhlé API pro generování grafů. Je tak velké, že bychom každé funkčnosti mohli věnovat zvláštní článek. Proto zde pouze v základu nastíníme jeho možnosti s příklady.

Uvedené API poskytuje funkcionalitu pro generování:

V praxi je nejlepší najít si na uvedených oficiálních stránkách příklad grafu, který nejvíce odpovídá našim představám, a zjistit, zda je možné ho parametrizovat přesně tak, jak potřebujeme.

Obrázkové grafy

Obrázkové grafy jsou takové, které vykreslujeme pomocí elementu img. Ačkoliv tyto grafy nejsou interaktivní, je dobré o nich vědět už kvůli tomu, abychom je nezaměňovali s grafy interaktivními. Ne všude se totiž používají pojmy Google Visualization API či Google Chart API. Často narazíte právě na obecný pojem Google grafy. V době psaní tohoto článku se na dotaz „Google grafy“ v Googlu na prvním místě objevovala stránka k „Chart API“, tedy k obrázkovým grafům.

Tyto obrázky mají specifické URL: odkazuje na zvláštní stránku u Google, jíž v parametrech předáme hodnoty, pomocí kterých Google vygeneruje obrázek. Ten se pak zobrazí na našem webu.

Z praktických zkušeností lze zmínit:

  • Názvy parametrů v URL jsou úsporné, což ztěžuje práci s nimi. Programátorovi může dělat problémy zapamatovat si, jaký je rozdíl např. mezi chs, chd, chco či chm.
  • Může být užitečné, aby pomocné osy na ploše grafu vedly k číslům na hlavní ose a ne mimo ně, anebo aby byla osa y invertovaná.
  • Při velkém počtu hodnot se popisky os začnou překrývat, což vede k nepřehlednosti. Je to motivace k použití interaktivních grafů, kde se konkrétní hodnoty zobrazují až při najetí myší na daný bod.
  • Obrázek si můžeme standardně uložit z kontextového menu.

Příklad:

<img src="http://chart.apis.google.com/chart?cht=lxy&chs=400x125&chd=t:10,30,40,50,65,90,95,99|20,30,40,50,55,60,65,65|-1|5,10,22,35,85&chco=3072F3,ff0000,00aaaa&chls=2,4,1&chm=s,000000,0,-1,5|s,000000,1,-1,5&chdl=A|B&chdlp=t" alt="Obrázek" />

Interaktivní grafy (Visualization API)

Tyto grafy se nerealizují elementem img s vhodně formátovaným parametrem src, ale plnohodnotným javascriptovým kódem. Vykonáním tohoto kódu v prohlížeči se zobrazí obrázek v elementu se specifikovaným id.

Má-li tento kód zobrazovat např. aktuální stav databáze, bývá zapotřebí jej generovat např. pomocí PHP. Vhodné je inspirovat se kódy ukázkových obrázků v oficiální dokumentaci. Opět v bodech uvedeme několik praktických zkušeností, konkrétně s grafem Area Chart.

  • Pokud zobrazujeme příliš mnoho bodů, mohou být i zde popisky na dolní ose problém. Lze tedy zobrazovat pouze prázdný text a konkrétní hodnoty ukazovat jen v bodu, nad který najedeme myší.
  • U Area Chart se nám v létě 2010 nedařilo u projektu VŠ LIGY invertovat osu Y, byli jsme tedy nuceni použít jiné řešení. Invertování je zapotřebí např. při zobrazování výsledků sportovních zápasů, kdy chceme vítěze zobrazovat nahoře.
  • V Internet Exploreru se grafy nezobrazovaly, pokud se za posledním číslem v poli s daty (v příkladu níže data.addRows()) nacházela čárka.

Příklad:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
  google.load("visualization", "1", {packages:["corechart"]});
  google.setOnLoadCallback(drawChart);
  function drawChart() {
    var data = new google.visualization.DataTable();
    data.addColumn("string", "Month");
    data.addColumn("number", "A");
    data.addColumn("number", "B");
    data.addRows([
         [{v: "-"}, 0,0]
         ,["August",100,150]        ]);

        var chart = new google.visualization.AreaChart(document.getElementById("chart_div"));
        chart.draw(data, {width: 700, height: 500, title: "Příklad",
                          hAxis: {title: "Year", titleTextStyle: {color: "#0000FF"}}
                         });
}
</script>
<div id="chart_div"></div>

Flot

Flot je jQuery knihovna (oficiální web), kterou jsou úspěšně využili např. v projektu zmiňované VŠ LIGY. Zdá se, že se knihovna už dále nevyvíjí. V TOVÁRNĚ jsme k ní vytvořili aktualizaci jednoho ze souborů, díky které lze v grafech invertovat jejich osy. Pomocí této knihovny lze vygenerovat graf, kde lze např.:

  • nad konkrétními body zobrazovat bubliny s nápovědou
  • nastavovat velikost kroku, po kterém se zobrazují na osách popisky
  • invertovat osy, tj. 1 není blíž k průsečíku os, ale dál

Příklad zdrojového kódu vygenerovaného pro jednoho hráče z VŠ LIGY:

<div id="tabs-3">
<div id="placeholder" style="width:655px;height:330px;"></div>
<div><script id="source" type="text/javascript">
var enableTooltip =true;

$("#tabs-1-1").tabs();
$("#tabs-1-1").bind("tabsshow",function(event,ui){
 if(ui.index==2){
        $(function () {
           var d2 = [ [0,10],[1,10],[2,11],[3,11],[4,11],[5,11],[6,12],[7,11],[8,11],[9,12],[10,12],[11,13],[12,11],[13,11],[14,12],[15,13],[16,5],[17,6],[18,7],[19,6],[20,12] ];

    $.plot($("#placeholder"),
                        [ d2],{
                        series: {
         lines: { show: true },
         points: { show: true }
      },
      grid: { hoverable: true, clickable: true } ,
                        yaxis: {min:4, invert:true, max:14,minTickSize:1,autoscaleMartin:null,tickDecimals:0 ,ticks:},
                        xaxis: {min:0, max:20,minTickSize:1,tickDecimals:0,ticks: } ,
                        legend: { position: "swplot" }
                });

    function showTooltip(x, y, contents) {
        $("<div id="tooltip"> " + contents + " </div>").css( {
            position: "absolute",
            display: "none",
            top: y + 5,
            left: x + 5,
            border: "1px solid #fdd",
            padding: "2px",
            "background-color": "#fee",
            opacity: 0.80
        }).appendTo("body").fadeIn(200);
    }

                var hodnoty=new Array();
                hodnoty[0]="Liga 10, Zimní semestr 2008 1. kolo";hodnoty[1]="Liga 10, Zimní semestr 2008 2. kolo";hodnoty[2]="Liga 11, Zimní semestr 2008 3. kolo";hodnoty[3]="Liga 11, Zimní semestr 2008 4. kolo";hodnoty[4]="Liga 11, Letní semestr 2009 1. kolo";hodnoty[5]="Liga 11, Letní semestr 2009 2. kolo";hodnoty[6]="Liga 12, Letní semestr 2009 3. kolo";hodnoty[7]="Liga 11, Letní semestr 2009 4. kolo";hodnoty[8]="Liga 11, Zimní semestr 2009 1. kolo";hodnoty[9]="Liga 12, Zimní semestr 2009 2. kolo";hodnoty[10]="Liga 12, Zimní semestr 2009 3. kolo";hodnoty[11]="Liga 13, Zimní semestr 2009 4. kolo";hodnoty[12]="Liga 11, Letní semestr 2010 1. kolo";hodnoty[13]="Liga 11, Letní semestr 2010 2. kolo";hodnoty[14]="Liga 12, Letní semestr 2010 3. kolo";hodnoty[15]="Liga 13, Letní semestr 2010 4. kolo";hodnoty[16]="Liga 5, Léto 2010 1. kolo";hodnoty[17]="Liga 6, Léto 2010 2. kolo";hodnoty[18]="Liga 7, Léto 2010 3. kolo";hodnoty[19]="Liga 6, Léto 2010 4.kolo";hodnoty[20]="Liga 12, Podzimní sezóna 2010 1. kolo (Říjen)";;

    var previousPoint = null;
    $("#placeholder").bind("plothover", function (event, pos, item) {
        $("#x").text(pos.x.toFixed(2));
        $("#y").text(pos.y.toFixed(2));

        if (enableTooltip) {
            if (item) {
                if (previousPoint != item.datapoint) {
                    previousPoint = item.datapoint;

                    $("#tooltip").remove();
                    var x = item.datapoint[0].toFixed(2),
                        y = item.datapoint[1].toFixed(2);

                    showTooltip(item.pageX, item.pageY,
                                hodnoty[parseInt(x)]);
                }
            }
            else {
                $("#tooltip").remove();
                previousPoint = null;
            }
        }
    });

    $("#placeholder").bind("plotclick", function (event, pos, item) {
        if (item) {
            plot.highlight(item.series, item.datapoint);
        }
    });



  });
  }

});


</script></div>
<p>Při najetí na křivku si prohlédněte podrobnosti.</p>
</div>

Flot je relativně jednoduchá knihovna, která neumí zdaleka tolik, co grafová API od Google. V některých případech však bohatě stačí. Výhodou je, že je v programátorových silách na ní v rozumném čase něco změnit. Problém jí dělá, pokud se graf zobrazuje v záložkách, při jejichž aktivaci se nenačítá nová stránka, ale stále zůstáváme na stejné stránce. Toto lze ale ošetřit tak, že obrázek načteme až tehdy, když se aktivuje záložka, která jej obsahuje.

Závěrem

Článek poukazuje na skutečnost, že v dnešní době existují řešení, kterými lze vygenerovat obrázky i mimo server, na kterém se nachází prohlížený web. Řešení sice existuje řada, ale nemusí být snadné vygenerovat právě takový obrázek, který je potřeba. Jako nejnadějnější se zdají Google grafy, které jsou velmi rozsáhlé a stojí za nimi velký hráč. Přesto někdy potřebujeme graf, který se vám pomocí nich nebude dařit vygenerovat. V takovém případě lze z různých knihoven použít např. jQuery Flot.




Poslat článek Nahoru



TOVARNA.CZ, s.r.o.

E-mail: info@tovarna.cz
Telefon: +420 274 776 344
Mobil: +420 739 654 469

Kancelář Praha

Doubravčická 1474/21
100 00 Praha 10
Telefon: +420 274 776 344