Flash graph.

Generowanie wykresów na stronach Internetowych jest problemem który możemy rozwiązać na kilka sposobów. Od rozwiązań po stronie serwera - czyli generowanie obrazków z wykresem przez nasz skrypt, po rozwiązania po stronie klienta. Albo stosujemy jakieś zewnętrzne narzędzia - np. Google API, albo próbujemy sami. Możemy to zrobić np. wyginając niesemantycznie kilka warstw (lub ładniej obiektem <canvas>, ale niestety nie zawsze wspieranym) lub podać dłoń technologii Flash - której się przyjrzę.

Poszukując dla swojego projektu rozwiązania, głównym kryterium był wymóg prostej interakcji z użytkownikiem. Mam na myśli, wyświetlenie bardziej precyzyjnych danych pozycji wykresu po najechaniu na nią myszką. Dlatego generowania obrazkowych wykresów kategorycznie się nie nadawało. Wybór technologii Flash spowodowany był tylko jednym argumentem - większa dostępność w stosunku do młodego obiektu canvas.

  • Tak trochę odbiegając, generowanie po stronie klienta wykresów ma spory plus, oszczędza moc naszego serwera...

Open Flash Chart 1.9.7

Jako, że z technologią Flash miałem dawno krótką przygodę postanowiłem poszukać jakiegoś gotowego rozwiązania. Odnalazłem projekt o nazwie Open Flash Chart który został opublikowany na bazie licencji GPL. Projekt aktualnie jest rozwijany w wersji 2.x - która dla mojego dosyć purystycznego oka, posiada dosyć sporą wadę: plik Flash waży ponad 250KB. Na szczęście w serwisie SourceForge odnalazłem, ostatnią wersję projektu z linii 1.x w której plik Flash nie przekracza 65KB a zarazem spełnia wszystkie moje oczekiwania.

Wersja z linii 1.x niestety dopuszcza tylko dwa sposoby wprowadzenia danych do wykresu - i nie ma możliwości zrobienia tego za pomocą JavaScriptu (co ciekawe w linii 2.x zostało to wprowadzone, ale było by za łatwo). Pierwszy to przez podanie parametru ze ścieżką z danymi do wykresu wraz ze ścieżką do pliku Flash, np.:

  1. <embed ... src="open-flash-chart.swf?data=SCIEZKA_DO_PLIKU_Z_DANYMI" ...

Oraz metoda druga (nie ujęta w dokumentacji), pozwalająca pozbyć się - w mojej opinii niepotrzebnej, konieczności łączenia się ponownie z serwerem aby pobrać dane - które przecież łatwiej dostarczyć wraz z dokumentem wyświetlającym wykres. Nie wspominając o generowaniu słupków przez dane dostarczone AJAX'em.

  1. <embed ... src="open-flash-chart.swf?variables=1¶met1=¶metr2=" ...

Metoda - właściwie metody te, mają dosyć sporą wadę. Za każdym razem ładując inny wykres przez zmianę parametru w adresie do pliku Flash przeglądarka pobiera w kółko ten sam plik. Można to rozwiązać na dwa sposoby, albo stosując parametr flashvars dla tagu dokującego obiekt Flasha albo zmodyfikować odrobinę nasz mechanizm tak aby wspierał wczytywanie danych przez JavaScript. Tak też zrobiłem...

mod by b4rtaz

Już bez zbędnych słów. Podsumowując zmiany mojej modyfikacji w stosunku do wersji oficjalnej; obsługa ładowania danych wykresu z poziomu JavaScriptu, wycofanie wsparcia dla metod ładowania przedstawionych powyżej, wycofanie z menu kontekstowego opcji "drukuj wykres" oraz zmiana domyślnego tła wykresu na odcień szarego (z okropnego żółtego).

Aby cokolwiek dodać do naszego wykresu musimy znaleźć obiekt Flasha z wykresem i "skontaktować się" z nim metodą: .loadJS(). Na przykład:

  1. var data = "title=Size+Example,{font-size:15px}&x_axis_steps=1&y_ticks=5,10,5&line=3,#87421F&values=2,19,20,19,1,0,20,5,10&x_labels=2,19,20,19,1,0,20,5,10&y_min=0&y_max=20";
  2. var charts = document.getElementById("mygraph");
  3. charts.loadJS(data);

Format danych dostarczanych do wykresu jest identyczny jak w wersji oficjalnej.

Trochę praktyki

Jako, że Adobe się nie popisało - albo po prostu nie mam szczęścia aby OnReadyStateChange zadziałało, trudno jest się dowiedzieć na jakim etapie film Flash został załadowany. Co za tym idzie, zaraz po załadowaniu dokumentu ciężko jest ładnie - jak na porządnego kodera przystało, załadować wykres. Dlatego dołożyłem pewne usprawnienie. Gdy dostarczymy parametr js=1 naszemu wykresowi (może być przez ścieżkę, np. ofc.swf?js=1, lub parametrem flashvars) w momencie gdy wykres będzie gotowy do pracy wywoła zewnętrzną funkcję ofc_ready().

Wystarczy odpowiednio zaprojektować mechanizm dodawania danych, i problem ładowania danych zaraz po wczytaniu strony nie będzie nam spędzał sen z powiek.

var _ofc_ready = false;
var _ofc_buffer = false;

function ofc_ready() {
	_ofc_ready = true; // OFC jest gotowe.
	ofc_set();
}

function ofc_set(data) {
	if(typeof(data) != 'undefined')
	{
		if(_ofc_ready == false) {
			_ofc_buffer = data;
		} else {
			var ofc = document.getElementById("mygraph");
			for(var i = 0; i < 2; i++) {
				try {
					ofc.loadJS(data);
					break;
				} catch(e) {
					// Opera FIX.
					ofc.outerHTML = ofc.outerHTML;
					ofc.set_title('');
				}
			}
		}
	}
	else {
		if(_ofc_ready == true && _ofc_buffer != false) {
			ofc_set(_ofc_buffer);
		}
	}
}

Przedstawiony powyżej algorytm polega na dosyć prostej zasadzie. Gdy chcemy dodać dane do wykresu, a jeszcze nie zwrócił on gotowości, skrypt "zapamiętuje" dostarczone informacje. W momencie gdy wykres powiadomi nas o gotowości (przypomnę, wywoła ofc_ready()), przesyłamy wcześniej zapamiętane dane.

Powyższa metoda posiada także drugi plus. Gdy obiekt Flasha nam się zresetuje (np. poprzez ukrycie warstwy z filmem i późniejsze jej odsłonięcie) z moich obserwacji wynika, że film ładuję się od początku - i co za tym idzie, wcześniej wygenerowany wykres zostaje skasowany. Powyższy kod w takiej sytuacji załaduje ostatnio dostarczone dane.

  • Na temat zastosowanej poprawki dla Opery nie będę się za dużo rozwodził. Generalnie jest jakiś problem z komunikacją Opera - Flash. Zainteresowanym polecam lekturę na forum Opery.

Download

Kończąc, publikuje moją modyfikacje także na licencji GPL. Skompilowany plik Flash wraz ze źródłami .fla można pobrać stąd. Wraz z paczką dostarczam własną implementację JavaScriptowej metody osadzania Flasha na stronach WWW, oraz w wersji mocno podstawowej JavaScriptowe API budujące dane wykresu. Klasa jest prosta i myślę, że nie tylko weterani sobie z nią poradzą.

Dla pozostałych przygotowałem mały przykład, jak można w bezsensowny sposób zastosować wykres.

Komentarze do wpisu "Generowanie wykresów Flash za pomocą JavaScriptu":

1. Mr B. napisał(a):
11 marca 2010, 17:19:45

Bardzo ciekawy Artykuł - szkoda, że Flash jest tak hermetyczny. Wymiana informacji między bazą, a aplikacją w action scripcie to droga przez mękę...
Swoją drogą, ostatnio męczyłem się próbując wyeksportować dane z wykresami do Excela...

Życie programisty do orka na ugorze!

Dodaj komentarz: