Gráficas lineales creadas en SVG

Figura
Figura. Gráficas lineales con SVG

Esta Herramienta de Web Tool Online sirve para crear gráficas lineales usando exclusivamente elementos SVG. Los tipos disponibles son gráficas de barras, de líneas y circulares (tipo "tarta"). Puede interactuar con el editor SVG traspasando el código SVG generado en la gráfica a ese editor y así poder realizar modificaciones en los elementos SVG de la gráfica. Otra posibilidad es traspasar el código al Parseador XML on objeto de verificar la corrección del SVG, pues en cualquier caso un SVG es un XML.

La herramienta es similar a otra anteriormente publicada gráficas lineales con HTML donde utilizábamos exclusivamente HTML+CSS para los mismos tipos de gráficas de barras, líneas y circulares. Actualmente los navegadores soportan ampliamente SVG, resultando en un código final más compacto.

Hemos generado la gráfica de barras representada en la imagen de la Figura en ambas aplicaciones, resultados que veremos a continuación:

Gráfica
Uds
Enero
Febrero
Marzo
100.0
75.0
50.0
25.0
0.0
40.3
90.0
100.0
50.0
65.4
78.0
25.0
33.0
22.1
Meses
Serie 1
Serie 2
Serie 3
Figura. Gráfica lineal de barras con elementos HTML+CSS

Desde la anterior aplicación exportamos un código HTML+CSS minimizado de unos 8.03 KB (8230 bytes). Lo insertamos en la Figura, donde podrá comprobar con el menú Inspeccionar del navegador que está construido con elementos HTML. El estilo CSS generado lo insertamos en un elemento <style> en la cabecera de la página.

40,3 90,0 100,0 50,0 65,4 78,0 25,0 33,0 22,1 Gráfica SVGEneroFebreroMarzo100,080,561,141,622,1UdsMesesSerie 1Serie 2Serie 3
Figura. Gráfica lineal de barras con elementos SVG

En la nueva aplicación exportamos un código SVG minimizado de unos 5 KB (5021 bytes). Lo insertamos en la Figura, donde podrá comprobar con el menú Inspeccionar del navegador que está construido con elementos SVG. A un SVG puede aplicarse estilo CSS, pero en este caso no es necesario.

Ambos están construidos en medidas relativas. Si amplia con el zoom la pantalla podrá observar que no pierden resolución, como si le afecta a la imagen de la Figura 1.

Interfaz de la herramienta para editar gráficas lineales con SVG

Figura
Figura. Interfaz del editor de gráfica lineales con SVG

En la Figura puede ver una captura de pantalla de la herramienta. En la parte izquierda están los grupos de controles de configuración que nos permitirán modificar la gráfica, que se presenta en la parte derecha. Podemos insertar valores directamente en formato de líneas de texto con valores separados por tabulador y filas separadas por salto de línea. Así es posible copiar una tabla de valores en Excel o en una página web donde la primera columna contiene los nombres de categorías y la primera fila los nombres de las series y pegarla directamente en el área de texto de valores. Por ejemplo, para la gráfica de la Figura tenemos esta tabla de valores en formato de texto:

Meses	Serie 1	Serie 2	Serie 3
Enero	40.3	50	25
Febrero	90	65.4	33
Marzo	100	78	22.1

La primera celda de la tabla anterior tiene el valor "Meses" y se aplicará como título del eje X. Los valores numéricos deben expresarse con punto decimal y sin separación de miles. Para insertar un caracter tabulador ha de usarse la combinación de teclas Mayús + Tab, puesto que la tecla Tab sobre el área de texto (elemento <textarea>) se comporta por defecto como un salto al siguiente elemento de control.

El código SVG puede ser modificado traspasando su contenido al Editor SVG usando el botón . En el editor SVG podemos realizar modificaciones en la propia gráfica, como corregir ubicaciones de elementos, cambiar colores, etc. También puede traspasarse el código al Parseador XML para verificar la corrección del mismo usando el botón .

Figura
Figura. Ayuda para detectar las configuraciones en el editor gráfica lineales con SVG

Con el botón se resaltará aquella parte de la gráfica que puede modificarse con el grupo de propiedades que tengamos abierto. Esto nos servirá para descubrir donde se aplican las propiedades.

En la Figura puede observarse que tenemos el botón activado (color azul). Y también tenemos el grupo Título desplegado, con lo que el título de la gráfica es resaltado en color verde. Esto nos permitirá descubrir que parte de la gráfica resultará afectada por una configuración. El color de resalte puede modificarse en la pestaña Configuración de la herramienta.

Módulo JavaScript para crear gráficas lineales con SVG

El módulo chart.js contiene la configuración inicial y la función create({values, config}) que nos permitirá crear una gráfica partiendo de un Array de valores y una configuración a aplicar.

Antes de eso hay que iniciar el módulo cargando estos scripts en la página. El primero chart.js es el que comentaremos en este apartado. El segundo chartui.js es para construir una interfaz que veremos en el siguiente apartado:

<script src="/res/inc/chart.js" async></script>
<script src="/res/inc/chartui.js" async></script>
    

Una vez cargados los scripts anteriores en el window.onload ejecutaremos el cargador de módulos que estoy usando en este sitio. Esto podría estructurarse de otras formas, pero así es como está aquí. Necesitamos una variable global a modo de espacio de nombres. Estoy usando para ello Wextensible pero podría modificarse por otro nombre, no olvidando que ha de ser una variable ubicada en global. El primer módulo tiene esta estructura:

var Wextensible = Wextensible || {};
Wextensible.CHART_JS = function(){
    Wextensible.startChart = function(){
        const configIni = {
            svgType: {
                group: "svg",
                value: "bar",
                check: ["bar", "line", "circle"],
                ...
            },
            ...
        };
        function create({values=[[]], config={}}={}){
            ...
        }
        return {
            configIni,
            create
        };
    };
};

Envolvemos el módulo en la función CHART_JS() que ejecutaremos tras el window.onload. Esto hará que tengamos disponible el iniciador startChart() que podríamos ejecutar en un momento posterior. Aunque en este ejemplo lo hacemos todo de una vez:

Wextensible.CHART_JS();
wxL.chart = Wextensible.startChart();
    

El iniciador nos devuelve el objeto {configIni, create} que pondremos en wxL.chart, siendo wxL = Wextensible.local = {} una subvariable para guardar cosas en ejecución local a la página. A partir de aquí podemos usar create() para crear gráficas:

let values = [
    ["Meses", "Serie 1", "Serie 2", "Serie 3"],
    ["Enero", 40.3, 50, 25],
    ["Febrero", 90, 65.4, 33],
    ["Marzo", 100, 78, 22.1]
];
let config = {
    svgType: "line",
    title: "Gráfica SVG",
    labelValue: true,
    xAxisRotation: 0,
    yLabel: "Uds"
};
let temp = wxL.chart.create({values, config});
if (temp.error) throw new Error(temp.error);
let conten = document.getElementById("conten-chart-example");
conten.innerHTML = temp.svg;
    

A la función create() le pasamos un Array de valores y una configuración que modifica algunos valores de la configuración inicial, creándose la gráfica en SVG que metemos en el contenedor, quedando como se observa en el siguiente ejemplo. Esto se ejecuta desde un módulo local para ejecutar sólo en esta página.

Ejemplo: Usando el módulo chart.js

A continuación mostramos una lista con todas las configuraciones posibles para crear una gráfica.

Ejemplo: Configuración chart.js

Algunos detalles a tener en cuenta con la tabla anterior cuando pasemos la configuración en create({values, config}):

  • Columna Default value: No es necesario pasar los valores por defecto.
  • Los valores como [1 .. 10] se refiere a un número entre esos dos valores. Con [Text] expresamos que puede incluirse cualquier texto.
  • Columna Array values: Si está activado podemos pasar un Array de valores que serán aplicados a las series y/o categorías de forma consecutiva. Si ese Array es menor que el número de series o categorías se tomará el valor por defecto.
  • Columna Omit: Algunas configuraciones se ignoran para algunos tipos de gráficas.

Módulo JavaScript como interfaz para editar gráficas lineales con SVG

El otro módulo chartui.js tiene como finalidad construir una interfaz para editar la gráfica. Lo iniciamos con startChartui() debiendo pasarse la referencia al objeto chart que generamos antes con el iniciador startChart():

Wextensible.CHARTUI_JS();
wxL.chartuiConstructor = Wextensible.startChartui(wxL.chart);
    

En wxL.chartuiConstructor obtenemos el objeto {instances, createUi, getConfigInfo} con algunas cosas genéricas a nivel del constructor:

  • instances: Objeto donde se guardarán las múltiples instancias a crear con createUi().
  • createUi: Función para crear las instancias.
  • getConfigInfo: Función para obtener una lista de las configuraciones a modo de información. Esta función es la que hemos usado para construir la lista al final del apartado anterior.

Con la función createUi() creamos una nueva interfaz para lo cual hemos de pasar al menos el argumento location que es una referencia a un elemento HTML donde ubicar la interfaz. En una página pueden crearse múltiples instancias de la interfaz, pues quedan definidas por el elemento donde se ubican y que hemos de pasar en ese argumento location. Estas referencias se guardan en instances.

wxL.chartui = wxL.chartuiConstructor.createUi({
    location: document.getElementById("conten-chartui-example"),
    lang: "es",
    widthConf: 22,
    colorInput: true,
    modeErrorMessage: "html"
});
if (wxL.chartui.error) throw new Error(wxL.chartui.error);
    

Tras esto podemos usar los métodos de chartui como setValues() para insertar una tabla de valores y refreshView() para refrescar la vista:

//Introducir valores
temp = wxL.chartui.setValues({values});
if (temp.error) throw new Error(temp.error);
//Refrescar la vista
temp = wxL.chartui.refreshView();
if (temp.error) throw new Error(temp.error);
    

El resultado de todo lo anterior se observará en este ejemplo:

Ejemplo: Usando el módulo chartui.js

La interfaz contiene botones para plegar y desplegar los grupos de configuración, otro para resaltar partes de la gráfica, como explicamos más arriba, y finalmente un botón para refrescar la vista tras realizar algún cambio en la configuración.

Figura
Figura. Barra de botones del editor gráficas SVG

En la herramienta Web Tools Online usamos esta misma interfaz, mejorándola agregando algunas funcionalidades, como botones para imprimir, para traspasar el código al editor SVG y al parseador XML así como un botón de ayuda. También podemos personalizar algunas cosas más, como la configuración del papel al enviar a imprimir y alguna configuración previa antes de enviar al editor SVG o al parseador XML.

También podemos configurar el idioma de la interfaz en la herramienta, por ahora sólo español ("es") e inglés ("en"), valor por defecto. En la interfaz generada hay una configuración para idioma dentro del grupo SVG, pero es para ajustar los valores de números al idioma. Así un número como 1234.56 se presenta como 1.234,56 en español ("es") y como 1,234.56 en inglés ("en"). Aquí si podemos usar cualquier idioma puesto que realizamos esa conversión usando el método de JavaScript toLocaleString().

En la herramienta también se dota de la paleta de colores a las configuraciones de color. Por defecto sólo aparece la paleta del sistema, insertada por medio del elemento <input type="color"> si activamos el argumento colorInput al crear la interfaz.

Los argumentos de la función createui() son los siguientes:

  • location=null: Argumento obligatorio del tipo HTMLElementDiv, que referencia un <div> existente en la página donde insertar la interfaz que vamos a crear. Si no existe no se creará la interfaz.
  • lang="en": Argumento opcional String para establecer el idioma de la interfaz. Disponibles español ("es") e inglés ("en"). Si no son estos se tomarán el valor "en".
  • widthConf="auto": Argumento opcional String o Number, para fijar el ancho del panel izquierdo que contendrá las configuraciones. El número se traslada como medidas relativas, por ejemplo, si pasamos 20 se utilizará como 20em. El valor "auto" no fija ancho alguno. Cualquier otro valor distinto de "auto" o un número será tratado como "auto".
  • heightConf="auto": Argumento opcional String o Number, para fijar el alto del panel izquierdo que contendrá las configuraciones. El número se traslada como medidas relativas, por ejemplo, si pasamos 20 se utilizará como 20em. El valor "auto" no fija alto alguno. Cualquier otro valor distinto de "auto" o un número será tratado como "auto".
  • modeErrorMessage="alert": Argumento opcional limitado a los valores siguientes:
    • Con un valor de tipo String que sea exactamente "html" el mensaje de error se insertará en un elemento HTML junto a la gráfica de la interfaz.
    • Con un valor de tipo Function se espera una función externa que sea capaz de presentar el mensaje de error.
    • Si se pasa "alert" o cualquier otra cosa se usará el mensaje de alertas del propio navegador.
  • colorInput=false: Argumento opcional Boolean para insertar un botón que abrirá la paleta de colores del sistema.
  • colorHighlight="rgb(0,255,0)": Argumento opcional String para indicar el color de primer plano al resaltar partes de la gráfica con el uso del botón activado.
  • backColorHighlight="rgba(0,255,0,0.2)": Argumento opcional String como el anterior, pero para resaltar colores de fondo de partes de la gráfica.

La función createUi() nos devolverá un objeto para manejar la interfaz:

{
    ui,
    lang,
    colorHighlight,
    backColorHighlight,
    modeErrorMessage,
    getConfig(),
    setConfig({config={}}),
    getValues(),
    setValues({values=[[]]}),
    refreshView(),
    importChart({object=null, json=""}),
    exportChart(),
    applyLang({lang="en"}),
    showGroup({groups=[]})
}

En ui tenemos la referencia al HTMLElementDiv que pasamos en el argumento location al crear la interfaz. En importChart() podemos pasar la gráfica en formato object o JSON. Se trata de un objeto que podríamos obtener con exportChart() y que nos devolvería algo como esto:

{
    "values": [
        ["Meses","Serie 1","Serie 2","Serie 3"],
        ["Enero",40.3,50,25],
        ["Febrero",90,65.4,33],
        ["Marzo",100,78,22.1]
    ],
    "config": {
        "svgType": "line",
        "titleColor": "#8080ff",
        "labelValue": true,
        "markerSize": 3
    }
}
    

Contiene todo lo necesario para representar la gráfica puediendo guardarse como un archivo de texto (si se exporta en JSON) e importarlo en un momento posterior.