18
Sep/09
0

Accès des Google Charts via Erlang

Le système utilise fortement la représentation visuelle des données sous forme de graphes. Pour cela, le plus efficace reste de capitaliser sur les services déjà disponibles et notamment l’API Google chart.

Le système de création de graphe par requêtage d’URL est simple mais reste compliqué à maitriser à cause de la notation utilisée et des nombreux paramètres disponibles.

Il devient nécessaire de fournir à l’application cliente une abstraction suffisante afin de réaliser plus rapidement les graphiques nécessaires.

Une API à minima peut être construite, via un module spécifique, ici src/chart.erl :

%% @doc Google chart client
 
-module(graph).

Tout d’abord, il est nécessaire de prendre en compte le formatage des données. Pour nos graphiques, la hauteur finale de la zone de graphe sera faible, aussi peut on utiliser le formatage simple sur une échelle de 100. Chaque valeur devra être transformée via une simple règle de 3.

encoding(simple, Data) ->
  Max = lists:max(Data),
  Ratio = 100 / Max,
  lists:map(fun(X)-> integer_to_list(round(X * Ratio)) end, Data).

Les données sont transformées en entier (arrondies) car sinon la transformation en string par Erlang utilise par défaut une notation sous forme exponentielle qui fait que la requête vers le service Google n’est plus fonctionnelle.

Plusieurs formes d’encodage existent, c’est pourquoi on préfixe cette méthode de l’atome « simple » (pas vraiment YAGNI pour le coup, mais j’assume).

Les données peuvent être transmises selon la conversion suivante :

convert(simple, Data) ->
  "&chd=t:" ++ join(encoding(simple, Data), ",").

Ici, un point important doit être soulevé : il n’existe pas de méthode simple (via des BIF) pour concaténer des listes sous forme de string avec des séparateurs! Il faut passer du temps sur Internet pour trouver des cas d’implémentation comme la méthode join/2 utilisée ici. Ce n’est peut être pas la façon la plus efficace en Erlang, mais ce n’est pas un problème pour l’instant :

join([], _) -> [];
join([List|Lists], Separator) ->
  lists:flatten([List | [[Separator,Next] || Next <- Lists]]).

On peut alors construire le graphique qui nous intéresse en fonction de son type. Par exemple, ici on crée un histogramme vertical avec des axes et des labels :

bar(Data, Labels, Options) ->
  "&cht=bvg" ++ convert(simple, Data) ++ axis(Data, Labels).
 
axis(Data, Labels) ->
  "&chxt=x,y" ++ "&chxl=0:|" ++ join(Labels, "|").

Options est une variable qui pourra être utilisée ultérieurement (encore un écharde dans le YAGNI).

Enfin, on construit l’URL finale, et on ajoute également les paramètres propres au viewport et non pas au graphe lui même :

url(medium, Params) ->
  url("400x150", Params);
url(square, Params) ->
  url("150x150", Params);
url(Size, Params) ->
  list_to_binary("http://chart.apis.google.com/chart?" ++ "chs=" ++ Size ++ colors() ++ Params).

La construction d’un graphe peut se faire de cette manière (après avoir exporté les méthodes correctement) :

graph:url(medium, graph:bar([235,134,98],["A","B","C"],{}))

Il ne reste plus qu’à ajouter les méthodes manquantes par rapport à ses besoins.

Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.