domingo, 13 de diciembre de 2015

Gráficas SVG HTML5

Inició una serie de post sobre tecnologías para graficar en html, y como es de esperar me basare en las tecnologías que nos trae html5, ojala no se alarguen mucho, bueno iniciemos.

Hay veces que necesitamos graficar o realizar una animación en base a líneas, gracias a la nueva versión de html (HTML5) tenemos tecnologías que nos facilitan este trabajo, antes teníamos que usar librerías o tecnologías que en muchos casos funcionan del lado del servidor y se requería un nivel alto de programación para usar, lo más fácil era usar solo CSS para realizar dichas gráficas.

HTML5 contiene especificaciones y tecnologías que nos pueden facilitar la vida, en cuanto a realizar gráficos en una página html, algunas de estas tecnologías son SVG y Canvas y son en las que me basare para realizar esta serie de post, iniciare con SVG.

Gráficos Vectoriales Escalables (SVG): La W3C lo define como lenguaje de gráficos web, osea es un lenguaje de marcado basado en XML para la descripción de gráficos de dos dimensiones y lo más elegante de todo, es que se puede usar en nuestras páginas html, eso sí hay que tener en cuenta que funciona para los navegadores que cuenten con el motor para interpretar y renderizar dicho estándar, afortunadamente los navegadores actuales cuentan con ello, como Internet Explorer desde su versión 9, Edge, Chrome, Opera, Android Browser, etc.

Todos hablan de que es un estándar de la W3C, hasta yo cometo el error, como te puedes dar cuenta en el párrafo anterior, pero si leemos detenidamente el documento de la W3C sobre SVC, nos damos cuenta que es un proyecto de trabajo que inicialmente fue desarrollado por SVG Interest Group, y ademas tambien dice que el documento ha sido revisado por muchos y que ha sido avalada por el Director como una recomendación de la W3C, mas no dice que es un estándar, o ¿sera que me fui al documento incorrecto?, estoy  hablando del documento de recomendación de la W3C del 16 de agosto del 2011 segunda edición de SVG.

Actualmente en la W3C está publicado otro documento sobre SVG pero esta como borrador y que trata sobre SVG versión 2 el cual lo puedes leer aquí.

SVG define tres objetos gráficos que son, textos, imágenes y las formas vectoriales, lo bueno es que los objetos se pueden accede por medio de SVG DOM que en mis palabras es como DOM (Documen Object Model) pero haciendo énfasis en los objetos definidos por la especificación SVG; que veo de bueno sobre esta definición de acceso, pues que a los objetos de SVG le podemos agregar los eventos que conocemos en HTML como onclick, activate, mouseover, etc. y algunos propios como SVGLoad, SVGAbort, etc.

El MIME Type para SVG es “image/svg+xml”, es importante tenerlo en cuenta para registrar ese tipo en los servidores si es requerido además de indicarlo en nuestro código cuando cargamos gráficos de este tipo, como anécdota personal, desde el año 2014 al 2015 ando desarrollando una pagina con HTML5, CCS3 y javascript, la definición de los gráficos, como logo e iconos los défini para cargar archivos svg, y porque tomé esa decisión pues porque las imágenes quedan, digamos de cierto modo escalables, que hace que no se pierda casi resolucion si se ven en pantallas pequeñas o en pantallas amplias; yo se que ustedes no cometen este tipo de errores porque se rigen a las recomendaciones, pero yo si falle en ello y fue en lo siguiente, básicamente para la página en cuestión los navegadores de pruebas que use fueron Chrome, Opera, mozilla, en el momento que inicie el desarrollo cargue las imágenes SVG con una simple pero poderosa etiqueta IMG de HTML, en ese entonces todo funcionó a la maravilla, hasta más o menos casi mediados del 2015, las imagens cargaban bien, se veian bien y cumplian con su objetivo de renderizado en diferentes pantalla, pero despues de unas actualizaciones en los navegadores, al cargar la pagina ya no cargaba ninguna de las imágenes tocaba que hacer cierto truco para que se visualizarán pero aun asi al abrir de nuevo no aparecian.

Después de analizar cierto tiempo y probar en otros navegadores, pues decidí ir a la especificación y encontré que la forma más recomendada de cargar objetos svc es mediante la etiqueta object de html la cual nos permite cargar diferentes formatos y trae un atributo en donde especificar el MIME Type, al realizar el cambio, pues se soluciono el inconveniente, pero aun asi, todavia tengo la duda, ya que en la recomendación de la W3C también describen que con la etiqueta img se pueden cargar objetos svg.

Los gráficos svg se pueden incluir en una página html de varias formas, las principales son por referencia y en línea (o lo que es lo mismo junto al código html), según el documento de la W3C se puede hacer referencia a los documentos svg con la etiqueta object, applet y img, con el uso de img ya comente lo que me pasó en los párrafos anteriores, pero esas son las recomendaciones de la W3C, y no esque esté diciendo que este mal tal vez lo que me fallo fue los navegadores y esto tampoco quiere decir que estén mal los navegadores, lo que pasa es que como se menciona, el documento de SVG de la W3C no es un estándar es una recomendación.

Un gráfico SVG lo podemos definir como un documento, similar a un documento html, osea que es un documento basado en XML, el cual contiene los elementos svg que van a conformar el gráfico, es algo como el siguiente código.

xml version="1.0" standalone="no"?>
svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
    version="1.1" width="5cm" height="5cm">
 <desc>Two groups, each of two rectangles</desc>
 <g id="group1" fill="red">
   <rect x="1cm" y="1cm" width="1cm" height="1cm"/>
   <rect x="3cm" y="1cm" width="1cm" height="1cm"/>
 </g>
 <g id="group2" fill="blue">
   <rect x="1cm" y="3cm" width="1cm" height="1cm"/>
   <rect x="3cm" y="3cm" width="1cm" height="1cm"/>
 </g>
 
 <rect x=".01cm" y=".01cm" width="4.98cm" height="4.98cm"
       fill="none" stroke="blue" stroke-width=".02cm"/>
</svg>


Como podemos ver, es un documento con una definición DOCTYPE, este documento si se abre desde un navegador compatible con la recomendación svg, renderiza un gráfico que lo puedes ver aquí. dicho documento lo podemos guardar como un archivo con extensión svg. Se que ya me estoy extendiendo mucho en el post, pero cuando escribo empiezan a rondar muchas ideas en mi cabeza.

Ahora digamos que al anterior código lo guardamos en un archivo nombrado grouping01.svg, para hacer referencia a este desde la página html podemos hacer lo siguiente.

<img src="grouping01.svg" alt="imagen svg">
<object type="image/svg+xml" data="grouping01.svg"></object>

Lo bueno de usar object es que podemos incluir una etiqueta img interna para que cargue una imagen ya sea jpeg, png, por si por algún motivo no se carga el archivo svg.

<object type="image/svg+xml" data="grouping01.svg">
   <img src="grouping01.png" alt="imagen png">
</object>

La otra forma de incluir los SVG es incrustando el código en el archivo html.

<html lang="es">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
</head>
<body>
 <svg width="5cm" height="5cm">
   <desc>Two groups, each of two rectangles</desc>
 <g id="group1" fill="red">
   <rect x="1cm" y="1cm" width="1cm" height="1cm"/>
   <rect x="3cm" y="1cm" width="1cm" height="1cm"/>
 </g>
 <g id="group2" fill="blue">
   <rect x="1cm" y="3cm" width="1cm" height="1cm"/>
   <rect x="3cm" y="3cm" width="1cm" height="1cm"/>
 </g>
 
 <rect x=".01cm" y=".01cm" width="4.98cm" height="4.98cm"
       fill="none" stroke="blue" stroke-width=".02cm"/>
</body>
</html>

Teniendo esto, podemos entrar a ver algunos de las etiquetas para graficar este tipo de imágenes, en la recomendación de la W3C existe mucha información desde el tipo de datos hasta los tipos de formas vectoriales y muchas otras cosas más, aquí sólo veremos unos pocos y en forma resumida.

Formas vectoriales: svg define rectángulo (rect), círculo (circle), elipse (ellipse), línea (line), polilínea (polyline), polígono (polygon).

Atributos comunes, id identificador único de objeto, class (definir la clase css para el objeto), style (para definir directamente los estilos css del objeto), externalResourcesRequired (para indicar que el objeto necesita contenido externo), transform (es para indicar transformaciones como rotación, traslado, escalado, es uno de los atributos interesantes). Para algunos fill es para indicar el color de relleno, stroke es para definir el color de la línea del borde, stroke-width para definir el grosor de la línea del borde.

rect: Define un rectángulo, el atributo x define el punto inicial en el eje horizontal de donde inicia el rectángulo, el atributo y define el punto inicial en el eje vertical de donde inicia el rectángulo, height define el ancho del rectángulo, width define el largo del rectángulo, tener en cuenta que las medidas y posiciones tienen en cuenta el área definida por la etiqueta svg, rx y ry es para definir el redondeado de las esquinas del rectángulo en cada eje respectivo, si se define uno solo, el otro tomará por defecto el mismo valor.

<svg width="10cm" height="10cm" style="border: solid 1px;">
   <rect x=".5cm" y=".5cm" width="5cm" height="5cm" fill="yellow" stroke="red" stroke-width=".1cm" rx="10" ry="5"/>
 </svg>

circle: Define un círculo, el atributo cx define el punto central del círculo en el eje horizontal, cy define el punto central del círculo en el eje vertical, r define el radio del círculo.

<svg width="10cm" height="10cm" style="border: solid 1px;">
   <circle cx="6cm" cy="2cm" r="1.5cm" fill="lightblue" stroke="red" stroke-width:"2" />
</svg>

ellipse: Define una elipse, el atributo cx define el punto central del círculo en el eje x, cy define el punto central del círculo en el eje y, rx define el radio del eje x, ry define el radio del eje y.

<svg width="10cm" height="10cm" style="border: solid 1px;">
   <ellipse cx="2cm" cy="5cm" rx="1.5cm" ry="1cm" fill="lightgreen" stroke="red" stroke-width:"6"/>
</svg>

line: Define una línea, x1 define el punto inicial de la línea en el eje x, x2 define el punto final de la línea en el eje x, y1 define el punto inicial de la línea en el eje y, y2 define el punto final de la línea en el eje y.

<svg width="10cm" height="10cm" style="border: solid 1px;">
   <line x1="180" y1="160" x2="350" y2="220" stroke="red" stroke-width="2" />
</svg>

polyline: Define un conjunto de segmentos conectados, el atributo points define una lista de puntos los cuales serán interconectados. es una línea abierta.

<svg width="10cm" height="10cm" style="border: solid 1px;">
   <polyline fill="none" stroke="blue" stroke-width="3"
           points="30,240 40,250 60,250 70,240 90,240 100,250
                   130,250 200,240 300,250" />
</svg>

polygon: Define un polígono, el atributo points define una lista de puntos los cuales serán interconectados. esta etique busca el cierre de el punto inicial y el punto final.

<svg width="10cm" height="10cm" style="border: solid 1px;">
   <polygon fill="lime" stroke="blue" stroke-width="5"
           points="30,300 50,320 50,350
                   70,325 80,350 90,300" />
</svg>





Estas etiquetas de formas vectoriales son compatibles con los eventos definidos en el DOM como el onclick.


<svg width="10cm" height="10cm" style="border: solid 1px;">
   <circle cx="3cm" cy="2cm" r="1.5cm" fill="lightblue" stroke="red" stroke-width:"2"
onclick="alert('círculo');"/>

</svg>





También podemos recorrer todos los elementos definidos usando javascript, lo que hace más interesante trabajar con estos tipos de gráficos. Lo podemos hacer por medio del atributo id o por el tipo de etiqueta.


<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <script type="text/javascript">
   function inicial(){
     var circulo = document.querySelector('#svgP circle');
     alert(circulo);
     alert(circulo.cx.baseVal.value);
     alert(circulo.id);
   }
 </script>
</head>
<body>
 <svg id="svgP" width="6cm" height="4cm" style="border: solid 1px;">
   <circle id="svgCirculo" cx="3cm" cy="2cm" r="1.5cm" fill="lightblue" stroke="red" stroke-width:"2" onclick="inicial();"/>
 </svg>
</body>
</html>


Textos


text: Representa texto, el atributo x representa una lista de coordenadas en el eje horizontal según el orden de los caracteres escritos, el atributo y representa una lista de coordenadas en el eje vertical según el orden de los caracteres escritos, font-family para el tipo de letra, rotate para rotación.


<svg width="10cm" height="10cm" style="border: solid 1px;">
   <text x="2" y="1cm" fill="blue" font-size="2em" rotate="10 5 10">texto en svg</text>
</svg>


Por el momento dejo hasta aquí, con lo que hemos visto ya podemos practicar y ordenar, teniendo la facilidad de que los objetos los podemos acceder con DOM, podemos hacer gráficos programables, además de darle la capacidad de que el gráfico sea escalable sin que pierda mucho su resolución.

Quería hacer algo mas practico, pero ese será el objetivo de un próximo post no sin antes tocar primero la tecnología CANVAS que también está disponible para que grafiquemos en nuestra página.

Dejo el link hacia la recomendación de SVG descrito por la W3C, ahí se encuentra todo, aunque en mi opinión le hace falta más ejemplos.




Bueno nos hemos ganado la chela, hasta la próxima
y feliz graficación :)