Utility a widgety pro práci s grafikou v knihovně JAK

Na této stránce jsou zobrazeny ukázky využití utilit a widgetů pro práci s grafikou ve stránkách při použití knihovny JAK.

Plátno SVG a VML

Čím se internetové aplikace zesložiťují, tím častěji je nutné vizualizovat data jinak než textovou reprezentací. Pokud jsou data často měněny, není vhodné je vizualizovat na straně serveru a pak přenášet ke klientovi jako výsledný obrázek, ale je daleko lepší tyto data vizualizovat na klientovi přímo. Většinou se jedná o různé grafy, ale zobrazovat můžeme např. trasu na mapě, nebo graf reprezentující síť, aj.

Pro vizualizaci jsme použili standard SVG a pro Internet Explorer je použita technologie VML. Tyto technologie jsou reprezentovány soubory svg.js a vml.js a funkčnost v nich obsažená je definována rozhraním v souboru vector.js (SZN.Vector.Canvas). V SZN.Vector je také jedna statická metoda SZN.Vector.getCanvas(), která přejímá jako parametry rozměry plátna a vrací reprezentaci plátna (SVG nebo VML element) s ohledem na prohlížeč.

Pro použití VML v Internet Exploreru musí stránka definovat VML jmenný prostor a také defaultní VML styl. Bohužel tyto údaje jsou závislé na verzi prohlížeče a proto nedoporučujeme nastavovat jmené prostor a styl ručně. O přidání správných hodnot do stránky se postará přímo knihovna.

Po vytvoření plátna můžeme do něj začít kreslit jednotlivá primitiva pomocí metod definovaných v rozhranní SZN.Vector.Canvas. Ukažme si příklad:

 var canvas = SZN.Vector.getCanvas(100,100);
 SZN.gEl('canvas1').appendChild(canvas.getContainer());
 var circle = new SZN.Vector.Circle(canvas, new SZN.Vec2d(50,50), 20, {color: '#ff0000'});
 var circle1 = new SZN.Vector.Circle(canvas, new SZN.Vec2d(50,75), 20, {color: '#ff00ff', opacity: 0.7});
 var circle2 = new SZN.Vector.Circle(canvas, new SZN.Vec2d(75,50), 20, {color: '#ff00ff', opacity: 0.7});
 var circle3 = new SZN.Vector.Circle(canvas, new SZN.Vec2d(25,50), 20, {color: '#ff00ff', opacity: 0.7});
 var circle4 = new SZN.Vector.Circle(canvas, new SZN.Vec2d(50,25), 20, {color: '#ff00ff', opacity: 0.7});

V příkladu je vidět na prvních dvou řádcích vytvoření plátna a jeho připnutí do dokumentu. Na obrázku je vykresleno 5 kruhů. Vše co je možno vykreslit je definováno ve jmeném prostoru SZN.Vector jako třídy:

Prvním parametrem konstruktoru každé z tříd primitiv je reference na vytvořené plátno. V dalším příkladu zobrazíme polygon (trojúhelník) a čáru u které půjde měnit dynamicky křivost.

 var canvas = SZN.Vector.getCanvas(150,150);
 SZN.gEl('canvas2').appendChild(canvas.getContainer());
 //vykresleni cerveneho trojuhelniku
 var polygon = new SZN.Vector.Polygon(canvas,
 		[ new SZN.Vec2d(10,10),
 		  new SZN.Vec2d(10,70),
 		  new SZN.Vec2d(40,70)
		 ],
		 {color: '#bb3333', outlineColor: '#ff0000', outlineWidth: 2}  
 );
 
 var line = new SZN.Vector.Line(canvas,
 		[ new SZN.Vec2d(120,100),
 		  new SZN.Vec2d(120,50),
 		  new SZN.Vec2d(80, 50),
 		  new SZN.Vec2d(55, 75),
 		  new SZN.Vec2d(80,100),
 		  new SZN.Vec2d(120,100)
		 ],
		{title: 'šipka', color: '#00dd00', outlineWidth: 2} 
 );

Výběrem stupně zakřivení bude měnit zelená šipka svůj tvar.

Při vytváření křivek, nebo definování středu kruhu, definujeme body pomocí SZN.Vec2d třídy. V souboru geometry.js jsou definovány třídy, které popisují vektory v N rozměrném prostoru:

Volitelné parametry tříd Circle, Line, Polygon a Path

Jak bylo zmíněno výše, prvním parametrem konstruktoru všech těchto tříd je reference na objekt vektorového plátna. Další parametry se již liší třída od třídy.

Circle

Třída Circle vyžaduje tyto parametry:

Parametr options můžeme ovlivnit tyto vlastnosti instance třídy SZN.Vector.Circle:

Line

Třída Line vyžaduje tyto parametry:

Parametr options můžeme ovlivnit tyto vlastnosti instance třídy SZN.Vector.Line:

Při kreslení zakřivené čáry (curvature > 0) je možné si vybrat parametrem symetricCP metodu, kterou budou počítány kontrolní body křivky. Ve výchozím nastavení jsou kontrolní body vypočítávány symetricky kolem prostředního bodu:

 var canvas = SZN.Vector.getCanvas(200,200);
 SZN.gEl('controlPoints1').appendChild(canvas.getContainer());

 var points = [ new SZN.Vec2d(40,40),
 	new SZN.Vec2d(150,100),
 	new SZN.Vec2d(100, 160) ];
 var line = new SZN.Vector.Line(canvas,
 			points,
 			{title: 'Čára', color: '#00dd00', outlineWidth: 3, curvature: 30}
 );
	

Hodnota curvature udává 1/2 vzdálenosti kontrolních bodů od středového bodu křivky. Kontrolní body jsou umístěny na úsečce rovnoběžné se spojnicí počátečního a koncového bodu. Body křivky jsou červené a kontrolní body zelené. Kontrolní body u počátečního a koncového bodu jsou umístěny na spojnici tohoto bodu s bodem středovým. To zajišťuje přimykání křivky k této spojnici.

Pro volbu symetricCP = false neudává parametr curvature vzdálenost kontrolních bodů od prostředního bodu křivky, ale poměrnou vzdálenost krajního bodu křivky k prostřednímu bodu. Tedy vzdálenost krajního bodu k prostřednímu na té straně, na které je kontrolní bod vykreslen, je přenásobena procentním koeficientem a výsledek je vzdálenost kontrolního bodu od středního budu křivky. Kontrolní body opět leží na rovnoběžce se spojnicí počátečního a koncového bodu křivky.

 var canvas = SZN.Vector.getCanvas(200,200);
 SZN.gEl('controlPoints1').appendChild(canvas.getContainer());

 var points = [ new SZN.Vec2d(40,40),
 	new SZN.Vec2d(150,100),
 	new SZN.Vec2d(100, 160) ];
 var line = new SZN.Vector.Line(canvas,
 			points,
 			{title: 'Čára', color: '#00dd00', outlineWidth: 3, curvature: 30, symetricCP: false}
 );

Polygon

Třída Polygon vyžaduje tyto parametry:

Parametr options můžeme ovlivnit tyto vlastnosti instance třídy SZN.Vector.Polygon:

Path

Třída Path vyžaduje tyto parametry:

Parametr options můžeme ovlivnit tyto vlastnosti instance třídy SZN.Vector.Path:

Požadované knihovny:

Stáhnout skripty pro práci s plátnem vector.zip.

Grafy

Kreslení čar a objektů je jen předzvěst větších widgetů a to widgetů pro kreslení koláčového grafu a čárového/sloupcového grafu. Pro kreslení grafu je potřeba načíst skripty pro práci s plátnem a dále soubor se skriptem grafu (piechart.js, lbchart.js).

Pro vykreslení grafu musíme zabezpečit element, který bude mít definovány rozměry, do kterého bude graf vykreslen a data. První ukázka je koláčový graf:

 var piechart = new SZN.PieChart('pieChartDiv', [
 					{label: 'IE', data: 74}, 
					{label: 'Firefox', data: 23}, 
					{label: 'Opera', data: 2}, 
					{label: 'Ostatní', data: 1}
					]);

Vzhled grafu lze ovlivnit třetím parametrem, kterým je konfigurační objekt. Ovlivnitelné vlastnosti jsou:

Pokud chceme vykreslovat 2D graf zobrazující např. z čeho se skládá cena 1l benzínu, který stojí 30,50 Kč, nakonfigurujeme graf takto:

 var piechart = new SZN.PieChart('pieChartDiv2', 
 					[{label: 'Cena bez daní', data: 13.79}, 
					{label: 'DPH 19%', data: 4.87 }, 
					{label: 'Spotřební daň', data: 11.84}],
					{depth:0, skew:1, suffix:" Kč", legendWidth:20, legend: 'bottom', padding: 10, legendDistance: 35, labelDistance:28});

Ovlivnit vzhled textů v legendě a v popiscích výsečí jde pomocí CSS tříd, které jsou jim přiřazeny. Tyto třídy jsou legend a label.

Vytvoření sloupcového nebo čárového grafu je stejně snadné jako grafu koláčového. Jediný rozdíl je v tom, že lze předat více řad hodnot a navíc předáváme hodnoty pro osu X:

 var lbchart = new SZN.LBChart('lbChart',
 			[	{label: "Nezaměstnanost", data: [6,4,5]},
 				{label: "Růst DPH", data: [2.8, 3.2, 4.8] }
 			],
 			/*popisky osy X*/
 			['2005','2006','2007']);

Samozřejmě lze graf konfigurovat. Popisky osy X lze předávat pomocí konfiguračního objektu, kde kromě vlastního popisku můžeme definovat barvu a tloušťku svislé čáry. Na následujícím grafu zobrazíme svislou mřížku:

 var lbchart = new SZN.LBChart('lbChart',
 			[	{label: "Nezaměstnanost", data: [6,4,5]},
 				{label: "Růst DPH", data: [2.8, 3.2, 4.8] }
 			],
 			/*popisky osy X*/
 			[	{label:'2005', color: '#000', width: '0px'},
 				{label:'2006', color: '#000', width: '1px'},
 				{label:'2007', color: '#000', width: '1px'}
 			]);

Dále bychom mohli chtít vykreslit některé sloupce sloupcovým grafem. Pak stačí do definice řady přidat vlastnost type s hodnotou bar. Dále lze u čárových řad (type = line) přidávat značky, jakou budou vykresleny body a to tak, že do definice řady přidáme vlastnost marker. Tato vlastnost musí obsahovat konstrukor dané značky a na výběr jsou třídy definované v souboru lbchart.js, popřípadě vlastní:

Většina nastavení grafu ohledně paddingu a legendy je shodná s koláčovým grafem. Přibyly navíc tyto vlastnosti:

Při vykreslení grafu je nejdříve vykreslena legenda a poté do zbylého místa graf. Ve výchozím nastavení je rozdíl minimální a maximální vykreslované hodnoty podělen výškou vymezeného prostoru a tím je získán krok pro vykreslení počtu vodorovných čar rows. Nicméně pokud jsou data plochá, algoritmus se tímto nastavením nemusí řídit. Důležitým nastavením je vlastnost zero. Pokud máme hodnoty např. mezi 10 až 100, tak při automatickém nastavení graf nevykreslí nulovou hodnotu. Pak je nutné nastavit zero na true, abychom vykreslovali graf mezi hodnotami 0 až 100.

Níže vykreslený graf je vytvořen tímto nastavením:

 var labels = [2000,2001,2002,2003,2004,2005,2006,2007];

 //nastaveni dat, kde d1 az d5 jsou pole s daty
 var data = [
		{
			data:d1,
			label:"leonard",
			type:"bar"
		},
		
		{
			data:d2,
			label:"sheldon",
			type:"bar"
		},
		
		{
			data:d3,
			label:"howard",
			type:"line",
			marker: SZN.Marker.Circle
		},

		{
			data:d4,
			label:"rajesh",
			type:"bar"
		},
		
		{
			data:d5,
			label:"penny",
			type:"bar"
		}

	];

 //nastaveni grafu
 var o = {
		barWidth: 10,
		lineWidth: 3,
		outlineWidth: 1,
		min: 0,
		max: 130,
		rows: {count: 10}
	};	
	
 //vytvoreni grafu
 window.l = new SZN.LBChart("lbChart", data, labels, o);
Požadované knihovny:

Stáhnout skripty pro tvorbu grafů charts.zip.

Animace CSS parametrů

Velice často se v internetových aplikacích používá animace CSS vlastnosti, aby aplikace vypadala více dynamická. Často jsou animovány průhlednosti boxů, nebo jejich pozice pro jejich objevování a mizení. Ve všech popsaných widgetech jsme se bez animací obešli, a pokud byly použity (widget pro řazení), pak jsou přímo naprogramovány ve widgetu. Vlastní animace je trochu magie, neboť je masivně využíváná funkce setInterval a dále je vhodné jednoduše umožnit animaci různými křivkami - lineárně, po sinusovce, atd.

Pokud z vlastní animace extrahujeme nosnou myšlenku, jde vlastně o interpolaci vlastnosti v čase mezi mezními hodnotami. Interpolace je prováděna podle předem zadané funkce.

V souboru interpolator.js jsou definovány dvě třídy:

Ve většině případů budeme animovat CSS vlastnosti, proto se zaměříme na CSS interpolátor. Jeho konstruktor vyžaduje tři parametry. Prvním je element, který bude animován, druhým parametrem je doba v ms, po kterou má animace trvat, a třetím je konfigurační literálový objekt s volitelnými parametry pro nastavení animace:

Dále je důležitá metoda addProperty, které předáváme název CSS vlastnosti, počáteční a koncovou hodnotu a případnou jednotku. Kód níže zobrazí po kliknutí na skrytý ostavec s textem.

Lorem ipsum dolor sit amet consectetuer metus lobortis orci enim congue. Malesuada fames eros hendrerit eleifend Pellentesque Integer leo metus nec venenatis. Interdum Nullam nec Suspendisse morbi et dictumst urna justo condimentum mi. Semper nulla Donec ante non felis mauris penatibus et cursus sit. Sed eget elit dolor id purus ipsum consequat Donec commodo urna. Eu magna congue mauris vel vel fringilla non lacus convallis eu. Urna.

 //zobrazeni odstavce
 var i = new SZN.CSSInterpolator(SZN.gEl('hiddenParagraph'), 1000, {});
 i.addProperty('height', 0, 87, 'px');
 i.start();

Samozřejmě po jeden časový úsek (jednu instanci interpolátoru) mužeme animovat více CSS vlastností najednou. Po stisknutí se objeví odstavec textu a bude podbarven žlutě, po čase bude spuštěn druhý interpolátor, který podbarvení zruší.

Lorem ipsum dolor sit amet consectetuer metus lobortis orci enim congue. Malesuada fames eros hendrerit eleifend Pellentesque Integer leo metus nec venenatis. Interdum Nullam nec Suspendisse morbi et dictumst urna justo condimentum mi. Semper nulla Donec ante non felis mauris penatibus et cursus sit. Sed eget elit dolor id purus ipsum consequat Donec commodo urna. Eu magna congue mauris vel vel fringilla non lacus convallis eu. Urna.

 function showParagraph2() {
 	var i = new SZN.CSSInterpolator(SZN.gEl('hiddenParagraph2'), 700, {endCallback: ligheBackground});
 	i.addProperty('height', 0, 87, 'px');
 	i.addColorProperty('backgroundColor', '#ffffff', '#ffff00');
 	i.start();
 	SZN.gEl('showText2').disabled = true;
 }
 
 function ligheBackground() {
 	var i = new SZN.CSSInterpolator(SZN.gEl('hiddenParagraph2'), 500, {endCallback: fadeBackground});
 	i.addColorProperty('backgroundColor', '#ffff00', '#ffff77');
 	setTimeout(function(){i.start()}, 500);
 }
 
 function fadeBackground() {
 	var i = new SZN.CSSInterpolator(SZN.gEl('hiddenParagraph2'), 700);
 	i.addColorProperty('backgroundColor', '#ffff77', '#ffffff');
 	setTimeout(function(){i.start()}, 2000);
 }
	
Požadované knihovny:

Stáhnout skripty pro tvorbu animací interpolators.zip.