Archivo del autor

Incluyendo Simile Timeline en una aplicación ADF Faces.

Escenario

El MIT (Instituto Tecnológico de Massachussetts) ofrece herramientas de manejo y visualización de datos fáciles de usar y, en principio integrables en aplicaciones web cliente, a través del proyecto SIMILE.  Concretamente, para cubrir la necesidad de visualizar eventos en una línea temporal, dispone del widget timeline.  Se trata de una librería javascript que permite justamente eso, visualizar cronológicamente información.  El software se ofrece bajo una licencia BSD.  Se proporciona documentación de cómo se puede incluir una línea temporal en una página HTML.  Aquí lo que vamos a ver es cómo hacerlo en una página ADF Faces.  Nuestra página ADF dispone de un campo lista desplegable. El usuario seleccionará un valor determinado de dicha lista y pulsará un botón de consulta. En ese momento, deberá mostrarse la linea temporal con el calendario correspondiente a la opción elegida.

La estructura

Para usar la linea temporal es necesario incluir los scripts de Simile en nuestro proyecto, en un subdirectorio dentro de public_html. Una vez hecho esto, crearemos tres servlets, a saber:

  • Un primer servlet que extraerá la información que va a aparecer en la línea temporal y generará un XML con la estructura que espera Simile. El parámetro que necesita para extraer la información lo tomará de la sesión.  No obstante, se le pasará un parámetro con los milisegundos de la hora actual para evitar que algunos navegadores (I.E., de hecho) no invoquen al servlet por segunda vez en una sesión al asumir erróneamente que, siendo la misma URL, los datos devueltos deben ser los mismos (incorrecto, ya que los parámetros se están pasando a través de la sesión).
  • Otro servlet que creará la parte jscript que va en el head de la página HTML final.
out.println("<script src=\"simile-timeline-api/timeline-api.js\" type=\"text/javascript\"></script>");
 out.println ("<script>");
 out.println ("var tl1, tl2;");
 out.println ("function onLoad() {");
 out.println ("var ejercicio=new Date().getFullYear();");
 out.println ("var eventSource = new Timeline.DefaultEventSource();");
 out.println ("");
 out.println ("            var theme = Timeline.ClassicTheme.create();");
 out.println ("");
 out.println ("            var date = \"" + getFechaActual() + "\"");
 out.println ("            var bandInfos = [");
 out.println ("                Timeline.createBandInfo({");
 out.println ("                    eventSource:    eventSource,");
 out.println ("                    date:           date,");
 out.println ("                    width:          \"70%\",");
 out.println ("                    intervalUnit:   Timeline.DateTime.MONTH,");
 out.println ("                    intervalPixels: 200");
 out.println ("                }),");
 out.println ("                Timeline.createBandInfo({");
 out.println ("                    eventSource:    eventSource,");
 out.println ("                    date:           date,");
 out.println ("                    width:          \"30%\",");
 out.println ("                    intervalUnit:   Timeline.DateTime.YEAR,");
 out.println ("                    intervalPixels: 200,");
 out.println ("                    overview: true,");
 out.println ("                    trackHeight:    10,");
 out.println ("                    trackGap:       5");
 out.println ("                })");
 out.println ("            ];");
 out.println ("            bandInfos[1].syncWith = 0;");
 out.println ("            bandInfos[1].highlight = true;");
 out.println ("");
 out.println ("            for (var i = 0; i < bandInfos.length; i++) {");
 out.println ("                bandInfos[i].decorators = [");
 out.println ("                    new Timeline.SpanHighlightDecorator({");
 out.println ("                        startDate:  \"" + getFechaInicioMesActual() + "\",");
 out.println ("                        endDate:    \"" + getFechaInicioMesSiguiente() + "\",");
 out.println ("                        color:      \"#AAAACD\", // set color explicitly");
 out.println ("                        opacity:    50,");
 out.println ("                        theme:      theme");
 out.println ("                    })");
 out.println ("                ];");
 out.println ("            }");
 out.println ("tl1 = Timeline.create(document.getElementById(\"tl1\"), bandInfos, Timeline.HORIZONTAL);");
 out.println ("Timeline.loadXML(\"servlet1?time=" + new Date().getTime() + "\", function(xml, url) { eventSource.loadXML(xml, url); });");
 out.println ("}");
 out.println ("</script>");
  • Un tercer servlet que creará la parte HTML que va en el body de la página y que pinta la línea de tiempo.
out.print("<div id=\"body\">");
 out.print("<div style=\"float: rigth; margin-left: 1em; margin-bottom: 1em;\">");
 out.print("<table>");
 out.print("<tr>");
 out.print("<td>");
 out.print("<div id=\"tl1\" class=\"timeline-default\" style=\"width: 600px; height: 200px;\"></div>");
 out.print("</td>");
 out.print("</tr>");
 out.print("</table>");
 out.print("</div>");
 out.print("</div>");
 out.close();

Tendremos que escribir también código en el botón para que al pulsarse, se grabe en la sesión el valor seleccionado en la lista de parámetros, para que pueda ser recogido por el primer servlet.

En la página jspx se incluirá en la cabecera una llamada al servlet2:

 <f:view>
   <afh:html>
     <afh:head title="Mi pagina">
       <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
       <f:subview id="timelinehead">
         <jsp:include page="/servlet2"/>
       </f:subview>
     </afh:head>
     <afh:body onload="onLoad();">

En el cuerpo de la página se incluirá una llamada al servlet3:

 <f:verbatim>
   <f:subview id="timelinebody">
     <jsp:include page="/servlet3"/>
   </f:subview>
 </f:verbatim>

La cáscara de plátano

Lo último que hay que hacer es incluir en el mismo directorio que nuestra página JSPX un fichero con el nombre __history__.html que contenga lo siguiente:

<html><body></body></html>

Al parecer, la librería javascript busca en un momento dado este fichero y si no lo encuentra, provoca una exepción como la siguiente:

com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:346)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:152)
oracle.adfinternal.view.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:157)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:65)
oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl._invokeDoFilter(AdfFacesFilterImpl.java:228)
oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl._doFilterImpl(AdfFacesFilterImpl.java:197)
oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl.doFilter(AdfFacesFilterImpl.java:123)
...
Anuncios

septiembre 22, 2009 at 12:37 pm Deja un comentario

La Oreja de Van Gogh y Carl Sagan

Imagen de Carl Sagan

Imagen de Carl Sagan

Recientemente tuve ocasión de escuchar atentamente la letra de la canción “Europa VII” de La Oreja de Van Gogh y no pude evitar acordarme de algunas de las ideas que Carl Sagan expuso a lo largo de su vida. La referencia a “un diminuto punto azul se pierde en un millón de chispas” me hizo acordarme de “un punto azul pálido”, donde se relativiza todo el drama humano y se le da una visión desde una perspectiva cósmica que lo convierte en algo trivial. Esa idea flota en toda la canción (“es mi planeta a un día luz y una lección de perspectiva“…). También, el alegato pacifista de Sagan en plena guerra fría contra la división del mundo en bloques enfrentados podrían verse de algún modo recordados por esta estrofa: “me quito la bandera de mi traje espacial y escribo en el reverso que soy de la humanidad“.

La canción continúa: “la frágil existencia milagrosa y casual, la vida más pequeña vale mil veces más que la nación

Imagen del video "Europa VII" de la Oreja de Van Gogh

Imagen del video "Europa VII" de la Oreja de Van Gogh

más grande que se invente jamás“. Me recuerda a “La vida es sólo un vistazo momentáneo de las maravillas de este asombroso universo…” y a cómo se nos recordaba en el segundo capítulo de Cosmos (“Una voz en la fuga cósmica”, donde el propio título ya es de por sí revelador), que la vida se debe a una sucesión de casualidades, ensayos y errores de la Naturaleza, que de manera milagrosa, nos han llevado a ser lo que somos, a estar donde estamos y a ser parte de un Universo al que, de forma parcial, podemos comprender.  La fragilidad de la vida de la que habla la canción se plasmó en Cosmos mediante el símbolo de un diente de león, sobre el cual metafóricamente el científico realizó su “viaje personal”.

Ahora voy a ponerme una canción de Julio Iglesias a ver si encuentro alguna relación con los discursos de Obama. Como los dos son negros… 😉

junio 29, 2009 at 3:07 pm 1 comentario


Autores