viernes, 12 de enero de 2007

Somatocarta

Hace un tiempo surgió en el foro de Velneo un post titulado "Somatocarta" donde GAV quería saber si era posible hacer con Velneo un informe que representara una gráfica donde se plasmaran los ejes, la rejilla de coordenadas y una figura fija, y encima poder dibujar un punto por coordenadas X,Y que correspodían a una ficha de una tabla.

La ebullición típica del foro de Velneo hizo brotar un montón de ideas ingeniosas para plasmar dicho gráfico en un informe de Velneo; casilleros de 14x13, una tabla maestra con 182 dibujos, preposicionar puntos en las intersecciones y mostrarlos por condiciones de visibilidad, etc.

Yo propuse:
"Y si generas el informe en html? Así lo podrías montar como quieras y siempre se imprimirá. Un saludo, DomK "

Como de costumbre nadie me hizo caso ;-D hasta que alguien más juicioso que yo y con mucha más solera (gracias Adolfomont) volvió sobre mi propuesta.

Lo siguiente fue montar una demo-web de un gráfico por coordenadas x-y, e integrarlo dentro de un formulario Velneo. Veamos cómo.

Mi propuesta consistía en una página web con capas (layers). Una capa para mostrar el fondo de la gráfica, es decir, la rejilla, los ejes de coordenadas y demás adornos, y otra capa por cada punto a representar. En la capa del punto sólo se representaría un gif de un píxel por un píxel para el punto, que se situaría sobre la capa del fondo con la rejilla.

Veamos el código html de la página en cuestión.

[!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"]
[html]
[head]
[title]Grafico html[/title]
[meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"]
[/head]
[body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"]
[div id="Rejilla" style="position:absolute; width:600px; height:480px; z-index:1; left: 0px; top: 0px;"]
[img src="img/Rejilla.gif" width="600" height="480"]
[/div]
[div id="Punto" style="position:absolute; width:1px; height:1px; z-index:2; left: 150px; top: 340px;"]
[img src="img/Punto.gif" width="1" height="1"]
[/div]
[/body]
[/html]

En esta página tenemos dos div's (layers o capas); uno llamado Rejilla que contiene la imagen de la rejilla y está situado en z=1 (orden de apilamiento de las capas), y otro para el punto a representar, llamado Punto que contiene la imagen del punto y está situado en z=2 para que se muestre por encima de la rejilla.

El truco para utilizar esto como una representación gráfica por coordenadas es el uso que hacemos de las coordenadas de las capas. Estamos definiendo la posición de los layers como absoluta, esto quiere decir que sus coordenadas (posición de la esquina superior izquierda de la capa) se mide respecto del origen (esquina superior izquierda) de la ventana que contiene al layer.

Hemos de tener en cuenta el sentido de los ejes; la coordenada X aumenta hacia la derecha y la coordenada Y aumenta hacia abajo. Lo normal es que en nuestro gráfico la coordenada X vaya en el mismo sentido, pero la Y va en sentido inverso. Esto implica hacer una inversión del eje Y para pasar nuestras coordenadas-gráfico a píxeles-pantalla en nuestra representación gráfica.

Supongamos que la imagen de la rejilla es como esta por ejemplo



donde tenemos un margen superior de 40 píxeles, un margen izquierdo de 50 píxeles y un paso de rejilla de 50 píxeles en X y 50 píxeles en Y. El origen de coordenadas lo tenemos en la esquina inferior izquierda de nuestra rejilla.

Veamos en principio la traslación del origen de coordenadas necesaria para llevar un punto de coordenadas-gráfico (0,0) a las coordenadas píxeles-pantalla.

El (0,0) de las coordenadas píxeles-pantalla se encuentra en la esquina superior izquierda, y para llevar este punto al (0,0) de nuestro gráfico deberíamos aumentar la coordenada X en 50 píxeles (margen izquierdo de la rejilla) y la coordenada Y en 440 píxeles (40 del margen superior de la rejilla + (50*8) píxeles de rejilla).

Supongamos que queremos representar ahora el punto (2,2) en nuestro gráfico. La coordenada x=2 se tranformará en 50 de margen izquierdo más 2 veces el paso de la rejilla, es decir, 50+(2*50)=150, y la coordenada y=2 se transformará en los 440 píxeles anteriormente calculados menos 2 veces el paso de la rejilla, es decir, 440-(2*50)=340.

Así pues nuestra transformación de coordenadas quedará así

X = 50 + ( x * 50 )
Y = 440 - ( y * 50 )


Este es el más sencillo de los casos ya que la escala para los ejes x e y (valor del paso de la rejilla) es igual para ambos ejes. Si no fuese así bastaría con aplicar el factor de escala correspondiente a cada eje y ya está.

Ya tenemos la fórmula a aplicar a las coordenadas del punto que queramos representar en nuestro gráfico-web.

Supongamos que tenemos una tabla PUNTOS con los campos CODIGO, COORD-X y COORD-Y, y que queremos representar gráficamente el punto en el formulario de edición de un punto.

Para ello generaremos tres componentes html; uno para el inicio del html y la rejilla de fondo, otro para el div del punto, y otro para finalizar el html.

El código del componente html INI-HTML perteneciente a ninguna tabla sería:

[!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"]
[html]
[head][title]Grafico html[/title]
[meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"]
[/head]
[body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"]
[div id="Rejilla" style="position:absolute; width:600px; height:480px; z-index:1; left: 0px; top: 0px;"]
[img src="img/Rejilla.gif" width="600" height="480"]
[/div]

El código del componente html PUNTO-HTML perteneciente a la tabla de PUNTOS sería:

[div id="Punto#AVP%CODIGO%" style="position:absolute; width:1px; height:1px; z-index:2; left: #AVP'X'px; top: #AVP'Y'px;"] [img src="img/Punto.gif" width="1" height="1"]
[/div]

donde utilizamos id="Punto#AVP%CODIGO%" para generar un identificador único para el layer del punto, y los parámetros #AVP'X' y #AVP'Y' para suministrar las coordenadas transformadas según la transformación de coordenadas antes calculada.

Y el código del componente html FIN-HTML perteneciente a ninguna tabla sería:

[/body]
[/html]

Ahora necesitamos un proceso GRAFICO.PRO que reciba el parámetro $PUNTO$ (variable global accesible web) que contendrá el CODIGO del punto a representar, y que monte la página web que representa ese punto. El proceso sería algo así como:

Rem-]Inicializo página
Set-]pagina,""
Set-]tramo,""
Rem-]Recibo parámetro
Set-]punto,$PUNTO$
Rem-]Compongo la página
Html, ejecutar componente-]tramo,INI-HTML
Set-]pagina,'pagina' + 'tramo'
Carga lista-]PUNTOS,CODIGO,'punto'
Seleccionar ficha por posición-]1
Leer ficha seleccionada
Set-]X,50 + ( %COORD-X% * 50 )
Set-]Y,440 - ( %COORD-Y% * 50 )
Html, ejecutar componente-]tramo,PUNTO-HTML,'X','Y'
Set-]pagina,'pagina' + 'tramo'
Html, ejecutar componente-]tramo,FIN-HTML
Set-]pagina,'pagina' + 'tramo'
Rem-]Devuelvo la página
Añadir retorno texto-]'pagina'

El proceso recibe en la variable global accesible web $PUNTO$ el CODIGO del punto a representar, ejecuta el componente INI-HTML, carga la lista de PUNTOS por el índice CODIGO resolviendolo con el código del punto a representar, hace la transformación de coordenadas y ejecuta el PUNTO-HTML pasandole en los parámetros 'X' e 'Y' con las coordenadas ya transformadas, finaliza el html y devuleve la página construida.

Ya tenemos todo lo necesario.

Ahora veamos cómo representar esto en el formulario de edición de PUNTOS.

Para ello vamos a necesitar un control html en el formulario con la siguiente fórmula para su contenido:

fGetWebAplicacion() + "GRAFICO.PRO?PUNTO=" + %CODIGO%

fGetWebAplicacion() devuelve la ruta web de nuestra aplicación, el típico http://ip_servidor/cgi-vel/alias_aplicacion/, y a esto le añadimos el proceso que genera nuestra representación gráfica pasandole a través de la variable global accesible web PUNTO el CODIGO del punto a representar.

Y ya está!!!


No lo había dicho antes pero esto sólo funciona en C/S, ya que al ser una página web compuesta por proceso desde componentes html, debe ser servida por el servidor web de Velneo.

Partiendo de esta base se pueden realizar todo tipo de representaciones gráficas-web a partir de datos en registros de tablas, sorteando así las limitaciones de los objetos específicos de Velneo para tal fin.

Veremos cómo a partir de este principio podemos generar gráficos de barras u otros más elaborados, pero eso será tema de un próximo post.

Hasta la próxima!

1 comentario:

  1. hola la verdad es que soy nuevo en la utilizacion de velneo pero lo poco que e descubierto me a imprecionado demaciado esperen a que pueda descubrir mas............
    tengo dos preguntas y me gustarian que me pudieran ayudar.
    1:como crear una opcion para llamar a algun lugar al cual yo pueda configurar, es como para incrementarlo en la aplicacion como por ejemplo cuando el usuario tenga alguna duda pueda darle click en el boton y automaticamente marque

    si algo mi correo es hacker_quiceno@hotmail.com

    2:como imprimir un recibo que cree pero solo imprimir el actual no el informe

    ResponderEliminar