Magazine

Sondage coding : results...with jQuery, RSS, XML and Google charts...no IE inside

Publié le 31 mars 2009 par Olivier Duval

Merci à la vingtaine de réponses au récent sondage. Le sondage reste accessible, on pourra y répondre via cette page ou dans la colonne de droite s'il apparait encore.

Comme on me l'a gentiment fait remarquer :

mais elle est conne ta question, ça dépend...

auquel j'aurais pu répondre :

padawan, n'oublie pas que je suis maître Jedi, ne vois-tu donc pas l'ours derrière la brindille ?

Anyway, allons explorer de suite les résultats.

Polldaddy

Polldaddy offre la possibilité de faire des sondages ou des enquêtes en ligne. Malheureusement, ils n'offrent pas d'API publique, mais seulement une privée, réservée aux partenaires. La seule possibilité d'obtenir des données afin d'en effectuer des traitements c'est d'utiliser le flux RSS disponible pour le sondage en cours.

Parmi les méthodes d'échanges, il reste possible de transporter de la donnée dans un flux RSS / Atom, dans la partie description / content par exemple, dans laquelle on pourra injecter du XML ou du HTML pour échanger de l'information.

Le flux Polldaddy pour ce mini-sondage fournit un tableau HTML (dans la partie description du flux) qui résume les réponses. Il a cette forme là :

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Poll Report: Combien d'ann&#233;es avant de devenir un
bon codeur / codeuse ?</title>
<link>http://www.polldaddy.com</link>
<description>This feed is generated by PollDaddy.com and
updated every hour, and is based on the results of your
survey.</description>
<pubDate><span title="27/Mar/09 17:03 (-6 GMT)">27/Mar/09
17:03:48</span></pubDate>
<generator>http://www.polldaddy.com</generator>
<language>en</language><ttl>62</ttl>
<item>
<title>Poll Report: Combien d'ann&#233;es avant de devenir un
bon codeur / codeuse ? (<span title="27/Mar/09 17:03 (-6
GMT)">27/Mar/09 17:03:48</span>)</title>
<link>
http://www.polldaddy.com/App/Polls/pollResults.aspx?id=1489134</link>
<pubDate><span title="27/Mar/09 17:03 (-6
GMT)">27/Mar/09 17:03:48</span></pubDate>
<category>Poll Report</category>
<description>
<table xmlns:pd="http://api.polldaddy.com/pdapi.xsd">
<tr><td>Combien d'ann&#233;es avant de devenir un bon codeur / codeuse ?</td></tr>
<tr><td>
<table>
<tr><td><b>Answer</b></td><td> <b>Votes</b></td></tr>
<tr><td>5 ans:</td><td>8</td></tr>
<tr><td>100 ans (la vie):</td><td>6</td></tr>
<tr><td>10 ans:</td><td>5</td></tr>
<tr><td>2 ans:</td><td>2</td></tr>
<tr><td>1 an:</td><td>0</td></tr>
<tr><td>15 ans:</td><td>0</td></tr>
<tr><td>20 ans:</td><td>0</td></tr>
</table>
</td></tr>
</table>
</description>
</item>
</channel>
</rss>

Que doit-on faire comme opérations ?

Objectif : afficher un graphe des résultats en %

  • lire le flux,
  • prendre le contenu de la description : on utilisera la fonction find et les selectors pour filtrer (notamment dans la hiérarchie avec > et ~),
  • filtrer dans le tableau uniquement les <td> avec les libellés des questions (1 an, 2 ans, ...) et les réponses attachées,
  • afficher un graphe des % à l'aide de google charts

Lire le flux : utilisation de la fonction $.get : le domaine de l'URL du flux étant différent de celui du présent blog, on ne peut aller interroger directement le flux RSS. Il faut passer par un script hébergé sur le même domaine olivier-duval.info qui ira chercher le flux et le renverra au $.get().

Pour cela, un micro script PHP (!) a été écrit, avec une utilisation de cURL :

<?php
$site = curl_init("http://polldaddy.com/pollRSS.aspx?id=23D44F88D7AF81BA");
$return = curl_exec($site);
curl_close($site);
 
return $return;
?>

sur la page Web, il reste à écrire le script javascript pour traitement le résultat du flux.

Utilisation de find sur la description, puis sur son contenu, sélectionnera les <td> contenant les libellés ans et le nombre de votes associés. On utilisera le chaînage de fonctions (makeArray().map().join()) pour construire les paramètres lors de l'appel à l'API charts Google.

<script language="javascript" type="text/javascript">
var j = jQuery.noConflict();
j(document).ready(function() {
j.get("pollresults.php", function(data) {
var votes = [];
var libs = [];
var tot = 0;
var d = j(data);
d.find('item').find('description').each(function(i) {
var desc = j(this);
var regex = /^(\d{1,3}).+/;
/* on prend tous les <td> contenant 'an',
on commence à partir du 2è */

var cell = desc.find("tr > td:contains('an'):gt(1)");
libs = cell.map(function(i,v) {
return j(v).text().replace(regex,"$1");
});
/* on prend le <td> suivant, qui contient le
nombre de votes */

votes = cell.map(function(i,v) {
var value = j(v).find('~ td').text();
tot+=parseInt(value);
return value;
});
});
var gchart = 'http://chart.apis.google.com/chart?chm=N*p0*,000000,0,-1,11&cht=bvs&chds=0,0.5&chco=4D89F9&chd=t:'+j.makeArray(votes).map(function(v){ return (v*100/tot)/100;}).join(',')+'&chs=300x200&chl='+j.makeArray(libs).join('|');
  // on crée une image qui pointe sur l'API charts, qu'on ajoute à un élément existant div d'id display
j("<img/>").attr('src',gchart).appendTo('#display');
 
});
});
</script>

Cela ne fonctionnera pas sous IE (toutes versions), il semble que cela vient du find, pas eu le temps de creuser.

Bon, sinon il y a plus court et moins prise de tête en visitant les résultats ici.

Conclusion

On ne s'avance pas trop en affirmant que traiter du XML / HTML n'est pas la méthode la plus simple, on lui préférera le JSON, bien plus simple à lire et à traiter (voir un exemple ici ou là).

...et on pourrait passer des heures à déboguer pour que ce simple exemple fonctionne sous Internet Explorer, étonnant ?


Retour à La Une de Logo Paperblog

A propos de l’auteur


Olivier Duval 4 partages Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte