Saturday, November 03, 2012

SAP HANA y R (El camino del Widget)

Un verdadero programador nunca termina de aprender eso es algo que me encanta repetir...porque se aplica a mi vida...puedes saber muchas cosas pero siempre hay nuevo por aprender o volver a aprender. Es por eso que hace un par de dias, comenze a leer wxPython in Action, un libro muy bueno que nos guia en como utilizar wxWidgets en Python. Mientras estaba leyendo el libro...un pensamiento me vino a la mente...muchos lenguajes de programacion tienen implementaciones de wxWidgets como Ruby, Python, Euphoria y Perl, por mencionar algunos...pero que podemos decir de R? Tiene R algo como eso? Por supuesto...y se llama gWidgets.

Luego de eso, comenze a leer la documentacion, buscar ejemplos en Internet y de pronto supe que queria hacer una applicacion que se integrara con SAP HANA.

Para aquellos que aun no lo saben, mi buen amigo y colega de equipo Juergen Schmerder posteo en Twitter una de las noticias mas grandes (al menos para mi)...


Esto significa que puedo utilizar ODBC en mis blogs o en mis proyectos personales sin preocuparme de que SAP no le de soporte...excelentes noticias realmente...pueden leer mas aqui

Asi que, esta es la aplicacion que hice...Tengan en cuenta de que necesitan la ultima version de  R (2.15.2) disponible en CRAN.
Necesitaran tambien las siguientes librerias RODBC, gWidgets, cairoDevice y gWidgetsRGTk2.




gWidgets_SAP_HANA.R
library("RODBC")
require ( gWidgets )
options ( guiToolkit="RGtk2" )
require( cairoDevice )

ch<-odbcConnect("HANA",uid="SYSTEM",pwd="manager")
airline_values<-c()
result<-sqlQuery(ch,"SELECT DISTINCT CARRID FROM SFLIGHT.SPFLI")
for(i in 1:nrow(result)){
 airline_values<-append(airline_values, as.character(result$CARRID[i]))
}

selected_airline<-""
distances<-data.frame(CONNID="", DISTANCE="", stringsAsFactors=FALSE)
g_distance<-c()
g_connid<-c()

window<-gwindow("gWidgets and SAP HANA", visible=FALSE)
group<-ggroup(cont=window, expand=TRUE, horiz=FALSE)
lyt<-glayout(cont=group, spacing=2)
lyt[1, 1:15, anchor=c(-1,0)]<-(search<-glabel("Carrier", cont=lyt))
lyt[1, 18:34, anchor=c(-1,0)]<-(airlines<-gcombobox(c("", airline_values), cont=lyt))
lyt[1, 38:42, anchor=c(-1,0)]<-(button<-gbutton("Submit", cont=lyt))
lyt[3:200, 1:200, anchor=c(-1,0)]<-(notebook<-gnotebook(cont=lyt))

group1<-ggroup(cont=notebook, label="Table")
group2<-ggroup(cont=notebook, label="Graphic")
plot_device<-ggraphics(cont=group2)
table<-gtable(distances,cont=group1,expand=TRUE)

addHandlerClicked(button, handler=function(h, ...){
  value<-""
  query<-"SELECT CONNID, SUM(DISTANCE) AS DISTANCE FROM SFLIGHT.SPFLI WHERE CARRID ="
  value<-paste(value,"'",svalue(airlines),"'", sep="")
  query<-paste(query, value , sep=" ")
  query<-paste(query, "GROUP BY CONNID", sep=" ")
  distances<-sqlQuery(ch, query)
  table[]<-distances
  barplot(distances$DISTANCE, names.arg=distances$CONNID)
})

visible(window)<-TRUE


Basicamente, lo que estamos haciendo es crear una ventana como contenedor, la cual va a almacenar a un  groupo, el cual va a almacenar un layout, el cual va a almacenar un label, un combobox, un boton y un notebook (panel con tabs). El notebook va a almacenar dos groups los cuales a su vez van a almacenar una tabla y una salida de graficos.
Cuando comenzamos la aplicacion, vamos a cargar los valores de CARRID de la tabla SPFLI dentro del  combobox, luego despues de escoger un valor y presionar el boton, vamos a construir una consulta que va devolvernos todos los CONNIDs junto con la suma de del campo DISTANCE. Esta informacion sera mostrada tanto en la tabla como en la salida de graficos (utilizando un Barplot).

Veamos como se ve cuando ejecutamos la aplicacion.


Por alguna razon, el ultimo tab siempre se muestra primero y no he encontrado forma de cambiar ese comportamiento.


Como recien estamos ejecutando la aplicacion, mostramos la tabla con una estructura vacia.


El combobox se llena con los valores de CARRID.


Escogemos "AA" y mostramos los valores en la tabla. Ahora podemos cambiar los tabs y ver el grafico generado.


Ahora, solo para demostrar que esto funciona realmente, vamos a escoger otro CARRIER, digamos "LH".


Veamos el grafico ahora.


Funciona perfectamente.

Asi que, que piensan? Desde la perspectiva del usuario, tener que tratar con una aplicacion gWidgets Application es mucho mejor que tratar con una aplicacion en linea de comandos, no?

Saludos,

Blag.

No comments: