universidad central del ecuador facultad de

Anuncio
UNIVERSIDAD CENTRAL DEL ECUADOR
FACULTAD DE INGENIERÍA CIENCIAS FÍSICAS Y MATEMÁTICA
CARRERA DE INGENIERÍA EN COMPUTACIÓN GRÁFICA
REPRESENTACIÓN WEB DE BASE DE DATOS EN GRAFOS
TRABAJO DE GRADUACIÓN PREVIO A LA OBTENCIÓN DEL
TÍTULO DE INGENIERA EN COMPUTACIÓN GRÁFICA
AUTOR:
ALARCÓN RUIZ VIVIANA MICAELA
TUTOR:
ING. PEDRO ALMAGRO BLANCO
QUITO – ECUADOR
2015
DEDICATORIA
Dedico el presente trabajo a las personas que hicieron posible de una u otra manera que
suba un escalón más en la vida. A mi familia, a mis profesores, al GMSC y amigos/as
ii
AGRADECIMIENTO
Deseo agradecer a aquellas personas que han estado a mi lado durante toda esta etapa
universitaria. A mi familia por el apoyo y la paciencia que me han brindado día a día para
alcanzar una de las metas propuestas.
A los profesores por compartir con nosotros todos sus conocimientos para que podamos
crecer tanto en el ámbito personal como en el profesional.
Al Grupo de Modelado de Sistemas Complejos que nos han guiado y entregado todo el
apoyo en la culminación de nuestras carreras además de acogernos como una familia, a
Pedro quien no solo ha sido mi tutor y guía académico sino también un amigo que me ha
trasmitido fuerza y aliento para seguir adelante.
A compañeros y compañeras con quienes hemos ido caminando juntos y mutuamente nos
hemos apoyado.
iii
iv
CERTIFICACIÓN DE TUTOR
v
OFICIO DE CALIFICACIÓN DEL TRABAJO DE GRADUACIÓN
vi
CALIFICACIÓN DEL TRABAJO DE GRADUACIÓN
vii
Contenido
DEDICATORIA………………………………………………………………………………………………………… II
AGRADECIMIENTO…………………………………………………………………………………………………. III
AUTORIZACIÓN DE AUTORÍA INTELECTUAL……………………………………………………………. IV
CERTIFICACIÓN DE TUTOR………………………………………………………………………………………. V
OFICIO DE CALIFICACIÓN DE TRABAJO DE GRADUACIÓN ………………………………………. VI
CALIFICACIÓN DEL TRABAJO DE GRADUACIÓN ……………………………………………………… VII
CONTENIDO …………………………………………………………………………………………………………. VIII
LISTA DE FIGURAS…………………………………………………………………………………………………… X
RESUMEN……………………………………………………………………………………………………………… XII
ABSTRACT……………………………………………………………………………………………………………… XIII
CERTIFICADO DE TRADUCCIÓN DE RESUMEN AL IDIOMA INGLÉS………………………… XIV
TÍTULO DE IDIOMA INGLES…………………………………………………………………………………… XV
INTRODUCCIÓN……………………………………………………………………..….……………………………….. 1
1
CAPÍTULO I ......................................................................................................................... 3
1.1
PLANTEAMIENTO DEL PROBLEMA ...................................................................... 3
1.2
OBJETIVOS .................................................................................................................. 4
Objetivo general ..................................................................................................... 4
Objetivos específicos ............................................................................................. 4
1.3
2
JUSTIFICACIÓN .......................................................................................................... 5
CAPÍTULO II ........................................................................................................................ 7
2.1
ANTECEDENTES ........................................................................................................ 7
2.2
MARCO TEÓRICO ..................................................................................................... 11
Bases de Datos ..................................................................................................... 11
Grafos e Hipergrafos ............................................................................................ 13
Bases de Datos en Grafo ...................................................................................... 16
Neo4j .................................................................................................................... 18
Cypher .................................................................................................................. 20
HTML .................................................................................................................. 21
JavaScript ............................................................................................................. 22
CSS ...................................................................................................................... 23
JQuery .................................................................................................................. 25
D3.JS .................................................................................................................... 26
3
CAPÍTULO III ..................................................................................................................... 28
3.1
METODOLOGÍA ........................................................................................................ 28
3.2
DISEÑO DE LA APLICACIÓN WEB ....................................................................... 28
viii
Librerías para grafos ............................................................................................ 28
Uso de Cypher...................................................................................................... 31
Apertura De Nodos .............................................................................................. 35
Cierre De Nodos................................................................................................... 36
Facetado Global ................................................................................................... 39
Facetado Local ..................................................................................................... 41
3.3
DISEÑO VISUAL DE LA APLICACIÓN WEB ........................................................ 45
3.4
MANUAL DE USUARIO ........................................................................................... 51
Requerimientos Del Sistema ................................................................................ 51
Uso del Navegador ............................................................................................... 51
Apertura de nodos ................................................................................................ 54
Cierre de nodos .................................................................................................... 56
Información completa del nodo ........................................................................... 56
Configuración del navegador ............................................................................... 57
4
CAPÍTULO IV..................................................................................................................... 58
4.1
CONCLUSIONES ....................................................................................................... 58
4.2
RECOMENDACIONES .............................................................................................. 60
4.3
BIBLIOGRAFÍA ......................................................................................................... 61
4.4
ANEXOS ..................................................................................................................... 63
Anexo A.
Index.html ............................................................................................................ 63
Anexo B.
Datos.js................................................................................................................. 68
Anexo C.
Config.js ............................................................................................................... 69
Anexo D.
Nodos.js ............................................................................................................... 72
Anexo E.
TiposNodos.js ...................................................................................................... 77
Anexo F.
TiposRelaciones.js ............................................................................................... 79
Anexo G.
Funciones.js ......................................................................................................... 80
Anexo H.
Información.js ...................................................................................................... 86
Anexo I.
primerNodo.js ...................................................................................................... 88
Anexo J.
Numvecinos.js ...................................................................................................... 91
Anexo K.
PedirVecinos.js .................................................................................................... 93
Anexo L.
abrirVecinos.js ..................................................................................................... 94
Anexo M.
Cierre.js ............................................................................................................ 96
Anexo N.
Cerrar.js ................................................................................................................ 97
ix
Anexo O.
funcionesBotones.js ............................................................................................. 99
Anexo P.
facetadoLocal.js ................................................................................................. 103
Anexo Q.
VecinosMenore.js .............................................................................................. 106
Anexo R.
tipoRelaLocales.js .............................................................................................. 108
Anexo S.
relacionesLocales.js ........................................................................................... 110
Anexo T.
VecinoLocales.js ................................................................................................ 115
LISTA DE FIGURAS
Figura 1 Linkurious ............................................................................................................ 7
Figura 2 Navegador Gephi ................................................................................................. 8
Figura 3 Navegador Mohiomap ......................................................................................... 8
Figura 4 KeyLines .............................................................................................................. 9
Figura 5 Navegador SylvaDB ............................................................................................ 9
Figura 6 Modelo Relacional ............................................................................................. 11
Figura 7 Consultas SQL ................................................................................................... 12
Figura 8 Grafo no dirigido Figura 9 Grafo dirigido ...................................................... 14
Figura 10 Camino de un Grafo......................................................................................... 14
Figura 11 Hiperaristas ...................................................................................................... 15
Figura 12 Hiper-Aristas.................................................................................................... 16
Figura 13 Base de datos en Grafos ................................................................................... 16
Figura 15 Interfaz Neo4j en LocalHost ............................................................................ 19
Figura 16 Estructura CSS ................................................................................................. 24
Figura 17 Ejemplo de D3.js con Nodos en Movimiento .................................................. 29
Figura 18 Ejemplo de D3.js con Zoom a los Nodos ........................................................ 29
Figura 19 Ejemplo de D3.js con Datos Geográficos Con Zoom ..................................... 30
Figura 20 Ejemplo de D3.js de Nodos Con Apertura y Cierre de Nodos ........................ 30
Figura 22 Ejemplo Nodos Estáticos ................................................................................. 31
Figura 23 Ejemplo utilizando Layout .............................................................................. 31
Figura 24 Consulta de 20 Nodos ...................................................................................... 32
Figura 25 Consulta de un Nodo, sus Vecinos y sus Relaciones ...................................... 33
Figura 26 Consulta de Nodos de acuerdo al Tipo de Nodo ............................................. 33
Figura 27 Nodo antes de dar click.................................................................................... 36
Figura 28 Apertura de Nodos con el evento click ............................................................ 36
Figura 29 Nodos con sus Vecinos .................................................................................... 38
Figura 30 Cierre de nodos con el evento doble click ....................................................... 38
Figura 31 Nodo con sus Vecinos ..................................................................................... 39
x
Figura 32 Nodo con otros vecinos sin los anteriores ....................................................... 39
Figura 33 Tipos de Nodos ................................................................................................ 40
Figura 34 Tipos de Relaciones ......................................................................................... 40
Figura 35 Facetado Local - Tipos de Nodos Vecinos ...................................................... 42
Figura 36 Tipos de Relaciones del Nodo del Tipo seleccionado .................................... 42
Figura 37 Grupo de nodos que se relacionan con el tipo de nodo seleccionado .............. 43
Figura 38 Selección de Grupo de nodos .......................................................................... 43
Figura 39 Vecinos al azar ................................................................................................. 44
Figura 40 Nodos Guías - Tipos de Nodos ........................................................................ 45
Figura 41 Tipo de Nodo en evento mouseover ................................................................ 46
Figura 42 Opciones para el Primer Nodo ......................................................................... 46
Figura 43 Primer Nodo de la Navegación ........................................................................ 47
Figura 44 Ventana Modal - Información del Nodo .......................................................... 48
Figura 45 Collapse - Tipos de Nodos ............................................................................... 49
Figura 46 Collapse - Tipos de Relaciones........................................................................ 49
Figura 47 Facetado Local - Popover ................................................................................ 50
Figura 48 Tooltip - Nodo inicio ....................................................................................... 50
Figura 49 Tooltip - Facetado Global ................................................................................ 50
Figura 50 Criterios para Nodo inicial............................................................................... 51
Figura 51 Ejemplos de nodos que se pueden buscar ........................................................ 52
Figura 52 Nodo inicial ..................................................................................................... 52
Figura 53 Selección Tipo de Nodos ................................................................................. 53
Figura 54 Selección Tipo de Relaciones .......................................................................... 53
Figura 55 Nodos Guías .................................................................................................... 53
Figura 56 Información y Tipos de Nodos ........................................................................ 54
Figura 57 Tipos de Nodos Vecinos .................................................................................. 54
Figura 58 Tipos de Relaciones de Nodo Vecino .............................................................. 55
Figura 59 Grupo de Nodos que están conectados con nodos Vecinos ............................. 55
Figura 60 Apertura de Nodos Vecinos ............................................................................. 56
Figura 61 Cierre de Nodos ............................................................................................... 56
Figura 62 Ventana Modal con Información del Nodo ..................................................... 57
xi
RESUMEN
REPRESENTACIÓN WEB DE BASE DE DATOS EN GRAFOS
Se presenta un prototipo de navegador web para Bases de Datos en Grafo que permite una
correcta navegación a través de información altamente relacionada y con contenido
multimedia, para ello se han implementado funcionalidades de navegación como son:
apertura de nodos, cierre de nodos, visualización de la información multimedia y filtrado
de nodos y relaciones.
Para la creación del prototipo se desarrollan librerías JavaScript construidas sobre
tecnologías robustas y ampliamente aceptadas en el ámbito del desarrollo web y el
modelado de datos en forma de red como son: D3.js, JQuery, Cypher, Neo4j, y por
supuesto HTML.
DESCRIPTORES:
BASE DE DATOS EN GRAFO / GESTOR DE BASES DE DATOS NEO4J /
CYPHER/ PROGRAMACIÓN JAVASCRIPT / LENGUAJE HTML / LIBRERÍA
D3.JS / NAVEGADOR MULTIMEDIA
xii
ABSTRACT
Web representation of graphs databases
It presents a prototype of web browser to Graph Databases in allowing a correct navigation
through highly related information and multimedia content, for this has been implemented
navigation features like as: opening nodes, closing nodes, visualization multimedia
information and filtering nodes and relationships.
For prototyping JavaScript libraries built on robust technologies are developed and widely
accepted in the field of development and modeling data in a network like as: D3.js,
JQuery, Cypher, Neo4j, and off course HTML.
DESCRIPTORS:
GRAPH DATABASE / NEO4J DATABASE MANAGER / CYPHER /
JAVASCRIPT PROGRAMMING / HTML LANGUAGE/ D3.JS LIBRARIES/
MULTIMEDIA NAVIGATION
xiii
xiv
xv
INTRODUCCIÓN
Las Bases de Datos en Grafo nos ofrecen nuevas formas de almacenar y tratar la
información y si bien es cierto que son relativamente nuevas nos ayudan a solucionar
problemas importantes en el ámbito del tratamiento de datos [4] [5]. Un caso concreto de
aplicación de las Bases de Datos en Grafo es aquél en el que la información se encuentra
altamente relacionada, es aquí que mediante una Base de Datos en Grafo se pueden
obtener mejoras en cuanto al almacenamiento, el acceso y la representación de los datos.
Neo4j es un gestor de Base de Datos en Grafo cada vez más utilizado alrededor del mundo
debido a los beneficios que brinda, su rapidez y facilidades para su uso, y a su eficiencia
al momento de realizar consultas, además de su fácil conexión con otras tecnologías.
En la web es muy importante una correcta visualización multimedia así como una interfaz
sencilla e intuitiva que facilite al usuario la navegación a través de los datos. Se pueden
encontrar diversos navegadores para Bases de Datos en Grafo que utilizan diferentes
tecnologías y sirven para diferentes campos profesionales o personales, se están
empezando a desarrollar cada vez más plataformas de este tipo pero aún no se satisfacen
todas las necesidades que el usuario requiere para un correcto análisis de las redes que
investiga. Debido a que no se dispone actualmente de ningún navegador web para grafos
multimedia se plantea el desarrollo de un prototipo de software para una navegación web
de datos almacenados en grafo (altamente relacionados) y enriquecidos mediante
contenido multimedia.
Para cumplir con el objetivo principal se realiza un análisis de las tecnologías presentes
de uso libre y de esta manera se determina cuáles son las más óptimas para el propósito
establecido: El desarrollo de librerías JS que nos permitan crear un prototipo de navegador
multimedia que pueda ser conectado con cualquier base de datos en grafo (Neo4j), y cuyos
parámetros sean configurables. Los mínimos parámetros que se requiere que sean
configurables son: Conexión con la base de datos, máximo de nodos vecinos a mostrar y
el conjunto de atributos que se desean ver del nodo. El navegador web debe implementar
diferentes funcionalidades como son apertura de nodos, cierre de nodos y opciones de
filtrado (global y local). Además, la navegación debe ser interactiva de tal manera que el
1
usuario se sienta cómodo en la búsqueda de la información, para ello se integran detalles
visuales que facilitan el uso de la aplicación.
La aplicación ha sido diseñada para que sea capaz de conectarse con cualquier Base de
Datos en Grafo (Neo4j). Debido a que el Instituto Nacional de Patrimonio Cultural (INPC)
está incorporando nuevas herramientas computacionales al análisis de sus bases de datos
en los últimos años [6], se ha utilizado una de sus bases de datos de este instituto como
caso de uso que actualmente se encuentra almacenada en su sistema Abaco1.
1
www.inpc.gob.ec/sistema-de-informacion-para-la-gestion-de-bienes-culturales-abaco
2
1
1.1
CAPÍTULO I
PLANTEAMIENTO DEL PROBLEMA
En una Base de Datos en Grafo la estructura está constituida por nodos y aristas, en donde
los nodos representan los registros o elementos únicos almacenados con al menos una
propiedad y las aristas representan las relaciones que existen entre los elementos. En este
tipo de base de datos no existe un esquema fijo con el cual modelar, de esta manera es
una base de datos más flexible, la cual puede seguir creciendo o disminuyendo sin
problemas ni restricciones, dando mayor importancia a sus relaciones.
Debido a que un grafo es un concepto abstracto que únicamente establece relaciones entre
entidades de muy diversa clase, existen dificultades en la representación visual de la
información que se puede almacenar en una estructura de Base de Datos en Grafos (GDB)
(Sancho Caparrini, 2014).
Cuando el número de nodos y/o relaciones es muy alto, no es fácil dar una representación
geométrica del grafo completo que permita comprender los distintos patrones que
aparecen entre las conexiones a corta y larga distancia entre los elementos de la Base de
Datos. Si, además, añadimos la característica de que el contenido que se almacena en los
nodos/relaciones del grafo es enriquecido (contenido multimedia que mezcla diferentes
tipos de información, desde simples textos hasta videos y audio, pasando por mapas e
imágenes), nos encontramos con estructuras informativas muy complejas que requieren
de nuevas formas de visualización.
Las Bases de Datos en Grafo están solucionando importantes problemas con el manejo de
grandes cantidades de datos altamente relacionados y con contenido dinámico, que con
las bases de datos relacionales resultan complejos, es por ello que en la web existen varios
navegadores para Base de Datos en Grafo, pero por ser una tecnología emergente tenemos
una ausencia de navegadores completos y óptimos para que el usuario encuentre toda la
información requerida de manera rápida y para que además pueda observar la información
multimedia.
3
Por todo lo mencionado se hace necesario el desarrollo de una aplicación web que permita
la navegación sencilla y eficaz a través de una Base de Datos en Grafo con contenido
multimedia.
1.2
OBJETIVOS
Objetivo general
1. Generar un conjunto de soluciones de software que puedan ser aplicadas sobre
casos concretos de representación de información altamente relacionadas y con
un contenido altamente enriquecido (multimedia).
Objetivos específicos
Estos objetivos generales se subdividen en los siguientes objetivos específicos:
1. Conocer las diversas tecnologías que pueden ser de utilidad para una correcta
representación de la información en la web.
2. Estudiar con profundidad las soluciones basadas en la tecnología JavaScript y en
las librerías que ya hay diseñadas en este lenguaje de programación, tanto a nivel
de representación gráfica como de conexión de datos.
3. Conocer las posibles soluciones, a nivel de cliente, que puedan aplicarse al
contexto del problema planteado.
4. Conectar con la información presente en el sistema Abaco del Instituto Nacional
de Patrimonio Cultural (INPC) para poder ser visualizada de las formas que se
estimen más adecuadas según los objetivos marcados (para usuario final, para
investigadores, para gestores, etc.)
4
1.3
JUSTIFICACIÓN
En los últimos años ha aparecido una buena colección de bases de datos basadas en grafo
para dar soluciones a diversos problemas que venían apareciendo en el mundo de las bases
de datos.
En las Bases de Datos en Grafo se aprovechan las relaciones complejas y dinámicas que
existen en los datos por lo que las consultas en función de las relaciones son más rápidas
que las consultas en función de las propiedades de los objetos. Otra ventaja representativa
de las bases de datos en grafos es que la forma de almacenamiento es más similar a la
manera de pensar de las personas que las bases de datos relacionales, lo cual facilita su
comprensión y da más importancia a las relaciones dentro del modelo de datos
Por otro lado la navegación a través de la web por el usuario debe ser interactiva y eficiente
para que pueda encontrar la información requerida rápidamente, se requiere unir la
representación de las relaciones entre los datos con el contenido multimedia que éstos
poseen, es por ello que se propone un prototipo de navegador web para base de datos en
grafos con contenido multimedia, utilizando herramientas para el desarrollo web como el
lenguaje JavaScript y librerías existentes de uso libre.
Si bien es cierto existen varios navegadores en la web para Base de Datos en Grafos pero
éstos tienen limitaciones las cuales requieren ser corregidas para beneficio del usuario.
Una de las limitaciones más significativas es no poder mostrar los vecinos de un nodo
seleccionado debido a que el número de éstos es muy elevado, esto tiene evita que la red
sea accesible de manera completa. Para solucionar este problema en el prototipo
desarrollado, se le ofrece al usuario la posibilidad de filtrar los nodos vecinos en función
de sus características en el caso de que el número de éstos supere un límite preestablecido.
Dicho límite es configurable por el gestor del navegador y por defecto tiene un valor de
25 debido a que es un valor idóneo para que el usuario pueda navegar la red sin reducir el
rendimiento de la aplicación. Además, la forma de obtener los nodos vecinos en el
prototipo desarrollado es aleatoria, de tal manera que el usuario siempre tiene la
posibilidad de recorrer la red completa.
5
Otra de las limitaciones que se encuentran en las plataformas actuales es que no permiten
la visualización de contenido multimedia asociado a los datos, es por éste motivo que en
la aplicación que se presenta se ha añadido un componente que permite desplegar
contenido audiovisual (imágenes, videos, audios, etc.).
En el Instituto Nacional de Patrimonio Cultural (INPC), el cual se tomará como un caso
de uso, disponen de un aplicativo web llamado Ábaco, que permite la visualización de las
fichas de registro que contienen la información sobre el patrimonio cultural ecuatoriano,
estas fichas están almacenadas en una base de datos relacional que divide al patrimonio
cultural en secciones: inmaterial, inmuebles, documentos, etc. Esta base de datos es muy
rica en información tanto descriptiva como audiovisual, ya que contiene anexos con
archivos como imágenes (jpg), videos (mp4), documentos (doc), etc., por cada ficha.
Lastimosamente es un visualizador plano, que no posee interacción con el usuario, con la
implementación del prototipo de navegador web utilizando Bases de Datos en Grafo se
fomenta la navegación relacional junto con un facetado que ayuda al usuario a conocer
sobre el patrimonio cultural de una forma interactiva, además la integración de la parte
multimedia permite una excelente experiencia de navegación.
6
2
2.1
CAPÍTULO II
ANTECEDENTES
En la web existen diferentes páginas que ofrecen una representación de base de datos
relacional y también de Base de Datos en Grafo, desarrolladas haciendo uso de diferentes
tecnologías, entre las que se encuentran:
Linkurious2: Herramienta accesible con licencia comercial o gratuita en comunidad libre,
utiliza el gestor de base de datos Neo4j y fue desarrollada con Sigma.js3, posee
características como animaciones e interacción con el usuario, tiene restricciones con el
número máximo de nodos por pantalla y es utilizada principalmente para búsqueda de
datos.
Figura 1 Linkurious
Gephi4: es una herramienta para el análisis de datos, se puede manipular estructuras,
formas y colores para interpretar características de la red que no son visibles con facilidad,
es utilizado como complemento a la estadística y es un software de licencia libre
desarrollado en lenguaje Java.
2
linkurio.us
sigmajs.org
4
gephi.github.io
3
7
Figura 2 Navegador Gephi
Mohiomap:5 es una herramienta desarrollada para visualizar y navegar a través de los
datos de forma gráfica que se tiene almacenados en la nube, permite realizar mapas
mentales con los archivos más importantes que se tiene almacenados y categorizar, se
puede tener una agenda ordenada e interactiva.
Figura 3 Navegador Mohiomap
KeyLines6: es una herramienta desarrollada en JavaScript para crear aplicaciones de
visualización personalizada de acuerdo al área de uso, tiene licencia empresarial, la de
prueba y la académica. Este software es utilizado para análisis de datos y patrones
dirigidos a la inteligencia de negocios y redes sociales.
5
6
www.moh.io/mohiomap/welcome.php
keylines.com
8
Figura 4 KeyLines
SylvaDB7: es un sistema de gestión de bases de datos en grafo con esquema relajado. Una
herramienta idónea para la organización de datos altamente relacionados y dinámicos, es
flexible ya que el usuario puede crear su propio esquema, es de uso libre, contempla el
desarrollo colaborativo y además tiene una interfaz amigable que permite modelar a
cualquier usuario (aunque no tenga conocimientos previos de Bases de Datos).
Figura 5 Navegador SylvaDB
En los últimos años ha ido aumentando el desarrollo de diferentes librerías de
programación y sistemas gratuitos para el diseño web utilizando HTML y JavaScript, ya
que el acceso a la información y navegación a través de la misma es más común para la
obtención de conocimiento, en el Ecuador el desarrollo de las mismas están en auge, y su
7
sylvadb.com
9
objetivo a corto plazo es conseguir una mejor navegación del usuario y ofrecer respuestas
inmediatas a la información requerida.
10
2.2
MARCO TEÓRICO
Bases de Datos
Las bases de datos actualmente se encuentra en forma digital pero en coneptos generales
una base de datos es un conjunto de datos almacenados sistemáticamente de acuerdo a un
mismo contexto, una base de datos muy común que se observa son las bibliotecas, donde
se encuentran libros o documentos que se encuentran agrupados según su área de estudio
y ser encontrados con facilidad.
Una base de datos relacional (RDB) es una base de datos que cumple con el modelo
relacional, que es el modelo más utilizado en la actualidad para implementar bases de
datos ya planificadas. En este modelo aquellos datos que sigan una estructura semejante
se almacenan en una misma tabla, y se permite establecer relaciones entre tablas distintas,
de forma que se establezcan interconexiones entre datos. Sus fundamentos fueron
postulados en 1970 por Edgar Frank Codd, de los laboratorios IBM en San José
(California), y frente a otros modelos alternativos que surgieron en esos mismos años, no
tardó en consolidarse como el nuevo paradigma en los modelos de base de datos.
Figura 6 Modelo Relacional
Las características principales son:

Una base de datos relacional se compone de varias tablas o relaciones.

No pueden existir dos tablas con el mismo nombre.

Cada tabla está formada por un conjunto de registros (filas y columnas).
11

La relación entre tablas relacionadas se consigue por medio del uso de claves que
identifican las filas relacionadas entre ellas.
Debido a que hay una estructura común que recorre toda la base de datos, suele hablarse
de su esquema como la definición de la estructura de la base de datos. Para definir un
esquema de una Base de Datos relacional se necesita dar: el nombre de cada tabla, el
nombre de cada columna, el tipo de dato de cada columna y la tabla a la que pertenece
cada columna.
Para manipular la información que hay en una RDB se utiliza lo que se denominan
lenguajes relacionales. Entre ellos, el más común es el lenguaje de consultas SQL
(Structured Query Language), un estándar implementado por los principales motores o
sistemas de gestión de bases de datos relacionales.
Figura 7 Consultas SQL
Sin embargo, cuando la información que se maneja soporta su importancia tanto en las
relaciones como en las propias entidades que se está estructurando, las soluciones basadas
en este tipo de Bases de Datos Relacionales no resultan convincentes, por una parte, el
12
esquema se aleja cada vez más del mundo real que el individuo tiene en mente y, por otra
parte, hace muy costoso desde el punto de vista técnico su mantenimiento debido a la
falta de flexibilidad que el modelo proporciona. Es por ello que, al menos desde un punto
de vista conceptual, y cada vez más desde un punto de vista práctico, para muchos
modelados de información se están haciendo uso de nuevos sistemas de gestión de bases
de datos que no siguen las normas de las tablas relacionales, y que han venido a llamarse
de forma genérica como Bases de Datos NoSQL (que debe interpretarse como “No
solamente SQL” y no como “No al SQL”, ya que en la mayoría de los casos intenta
mantener un equilibrio entre las buenas características de las RDB y las nuevas opciones
que proporcionan otro tipo de sistemas de almacenamiento y gestión) (Caparrini, 2015).
Grafos e Hipergrafos
La teoría de grafos se remonta al año 1736 en el que el matemático Leonard Euler resolvió
un problema relacionado con los puentes de la ciudad Königsberg [1].
Un grafo es un conjunto de objetos llamados vértices o nodos unidos por enlaces llamados
aristas o arcos, que permiten representar relaciones binarias entre elementos de un
conjunto. Habitualmente, un grafo se puede representar gráficamente como un conjunto
de puntos (o figuras geométricas) unidos por líneas en el plano (o, a veces, en el espacio
tridimensional).
Desde un punto de vista práctico, los grafos permiten estudiar las interrelaciones
existentes entre unidades que interactúan unas con otras. Por ejemplo, una red de
conceptos de un dominio puede representarse y estudiarse mediante un grafo en el cual
los vértices representan los diversos conceptos que se estudian y las aristas representan
conexiones (las que se consideren oportunas en el dominio, por ejemplo, sinonimia,
antonimia, procede de, etc.). Prácticamente cualquier problema puede representarse
mediante un grafo, y su estudio trasciende a las diversas áreas de las ciencias exactas y
las ciencias sociales.
13
Figura 8 Grafo no dirigido
Figura 9 Grafo dirigido
Dependiendo de cómo se considera la arista que une a los vértices, los grafos se pueden
clasificar como dirigidos (cuando la arista parte de uno de los vértices y llega al otro, es
decir, el papel que juegan ambos nodos en la relación no es el mismo), o no dirigidos
(cuando la arista simplemente conecta los vértices entre sí). Normalmente, las aristas
dirigidas se representan como una flecha (tal y como vemos en la figura anterior) y las no
dirigidas como un segmento.
Figura 10 Camino de un Grafo
Un camino en un grafo es una sucesión de vértices tal que para cada uno de sus vértices
existe una arista hacia el vértice sucesor [2].
14
Además, se pueden considerar pesos en las aristas que pueden indicar algún tipo de
característica de la misma (longitud, flujo de información, fuerza de la conexión, etc.).
En dicho caso, diremos que el grafo es ponderado.
A veces el tipo de información que se quiere conectar no simplemente relaciona los
vértices de forma binaria, es decir, de dos en dos, sino que las relaciones se producen
entre conjuntos mayores de vértices. Por ejemplo, si se tiene una red de turismo en la que
se considera a los turistas que viajan anualmente y las zonas que visitan, en ese caso,
relacionar solo que el turista v1 visitó la zona v2 puede ser insuficiente porque depende
del año en que lo hizo, en este caso se introduce un tercer tipo de vértice, temporal, y la
relación se da entre los tres nodos simultáneamente: el turista v1 visitó la zona v2 en el
año v3.
Figura 11 Hiper-Aristas
En este caso, existen posibilidades más ricas de expresión, por ejemplo: los turistas v 1 y
v5 viajaron en el año v3. Estas nuevas relaciones son más complejas e informativas. Por
supuesto, su representación gráfica se complica y ya no basta con representarlas por
medio de segmentos conectando los puntos, y se suele acudir a representaciones de
superficies para ello. A este tipo de grafos con aristas más potentes se les conoce como
hipergrafos, y a las aristas de este tipo hiperaristas.
Debido a que las representaciones de las hiperaristas son mucho más complejas desde un
punto de vista técnico (y confusas en su representación) y como demostración de la
versatilidad que tienen los grafos, no es necesario acudir a los hipergrafos aunque las
relaciones no sean binarias, sino que existe la posibilidad de “crear” tipos de vértices
15
intermedios, que representen esas hiperaristas (son vértices artificiales, que no pertenecen
al mundo real que se pretende modelar) de manera que si v1, v2 y v3 son vértices que
comparten esa hiperarista, se crea el vértice h1 y se enlaza con aristas binarias con los tres
anteriores. De esa forma no se pierde la información a almacenar y se trabaja con grafos
sin necesidad de desarrollar herramientas teóricas ni de representación nuevas.
Figura 12 Hiper-Aristas
Bases de Datos en Grafo
Una Base de Datos en Grafo (GDB) es un tipo de base de datos NoSQL que usa
estructuras de grafos con nodos, aristas y propiedades para representar y almacenar la
información [3].
Figura 13 Base de datos en Grafos
Los nodos pueden representar entidades tales como personas, partes de un texto,
conceptos, o cualquier tópico, real o no, que pueda ser útil para modelar un problema.
16
Las aristas representan relaciones entre entidades, y a diferencia de las relaciones en las
RDB, en las GDB mucha de la información relevante al modelo se almacena en estas
aristas. Habitualmente, cuando se decide por una implementación del modelo en un GDB
es porque se requiere estudiar los patrones que emergen en las conexiones e
interconexiones entre nodos, propiedades y aristas, y no tanto en la información relativa
a cada uno de ellos por separado.
Las propiedades son unidades de información relevante para los nodos y las aristas. Por
ejemplo, si un nodo representa una comedia, propiedades relevantes podrían ser: la fecha
de edición, género, extensión, etc… el hecho de que algunas de estas propiedades pasen
a convertirse en nodos independientes del grafo, adquieran entidad propia, depende del
objetivo a cumplir y está relacionado con el cómo estructurar la información. Además,
suele ser habitual disponer de una clasificación en los nodos, de manera que se pueda
agruparlos según el tipo al que pertenecen (por ejemplo, personas, obras, lugares, etc.).
Debido a la libertad que ofrecen los grafos
como
soporte
conceptual
de
la
información, una GDB puede llegar a
carecer por completo de esquema, es decir,
que se puede asociar con absoluta libertad
nodos entre sí, añadir propiedades de
manera arbitraria e individualizada y añadir
el número de relaciones que se desee entre
distintos nodos. Sin embargo, suele ser habitual que, haciendo uso de la clasificación por
tipos de los nodos y de las relaciones semánticas habituales que hay entre ellos (y que
sean relevantes para el problema en cuestión) se trabaje sobre un esquema inicial que
restrinja de alguna forma qué tipos de nodos y propiedades se pueden crear y cómo se
pueden relacionar entre sí. Pero debe tenerse en mente que estas restricciones no son
propias del modelo GDB, sino que tienen el fin de minimizar los posibles errores y
optimizar la manipulación de datos.
Comparadas con las RDB, las GDB a menudo ofrecen mayor velocidad en la búsqueda
de patrones y se ajustan más directamente con el mapa conceptual del problema. Además,
17
escalan de manera más natural (es decir, no son tan sensibles al tamaño total de la base
de datos) y eso facilita las consultas complejas que en las RDB pueden volverse
especialmente inmanejables. Además, como dependen de un esquema mucho menos
estricto son mucho más apropiadas para escenarios en que los datos pueden ser muy
cambiantes (quizás por desconocimiento previo de los requisitos) y hace falta realizar
evoluciones en el esquema de datos de manera frecuente. En contra, debe señalarse que
especialmente para aquellos casos en que una consulta, por ejemplo, requiere mover
mucha información similar, las RDB son mucho más rápidas y eficientes.
Una de las ventajas adicionales del uso de las GDB es que se soportan sobre una teoría
matemática muy robusta y madura, por lo que muchos de los procesos necesarios para
manejar la información que se ha almacenado en ellas pueden ser resueltos por resultados
matemáticos demostrados (como, por ejemplo, la búsqueda de caminos mínimos entre
dos nodos del grafo, las consultas, detección de comunidades, etc.).
En general, se dice que un grafo es multimedia cuando en los nodos/relaciones del grafo
almacenamos contenido multimedia que, podrían ser: imágenes, audio, video, etc.
Neo4j
Neo4j es un gestor de base datos desarrollada en Java, que almacena la información de
forma relacionada formando un grafo dirigido con sus nodos y las relaciones existentes
entre ellos, es decir es un gestor de base de datos orientada a grafos. Puede integrarse con
múltiples lenguajes entre ellos: Java, PHP, Ruby, .Net, Python. La base de datos está
embebida en un servidor Jetty.
18
Figura 14 Interfaz Neo4j en LocalHost
Es distribuida en dos versiones: la community edition (open source) y la enterprise edition.
La versión comunity se diferencia de la Enterprise por no disponer de: clusterización,
monitorización, backups en caliente y un sistema de cache de alto rendimiento, además
de soporte de sus creadores, pero puede ser usada perfectamente para desarrollo a nivel
educativo o para pequeñas aplicaciones. Una de las principales ventajas que tiene Neo4j
es que se pueden efectuar las consultas directamente mediante un API REST.
Es el gestor de base de datos para grafos más utilizado en el mundo por miembros de la
comunidad, organizaciones y empresas, que la utilizan para el desarrollo de la educación,
ciencia, tecnología y desarrollo empresarial.
Utiliza el lenguaje de consulta Cypher, el cual es considerado el más potente y productivo
para las consultas a una base de datos en grafos, ya que es intuitivo y fácil de aprender.
No solo ofrece seguridad para las bases de datos en grafos, sino que también cumple con
altos estándares de calidad que cumplen las bases de datos relacionales, como por
ejemplo velocidad, rendimiento y con las propiedades ACID 8 (Atomicity, Consistency,
Isolation, Durability), que garantiza la eficiencia en las consultas basadas en relaciones,
que es el fuerte de los gestores de bases de datos orientados a grafos. Desde su primera
versión ha ido mejorando en cada una de sus actualizaciones, con pruebas continuas y
rigurosas para que sea una herramienta confiable.
8
Atomicidad: ocurren todas las transacciones o ninguna, Consistencia: no rompe la integridad de la base
de datos, Aislamiento: ninguna operación afecta a otra en su ejecución y Durabilidad: una vez realizada la
operación no se puede deshacer.
19
En su página web oficial dispone de una gran cantidad de información, tutoriales,
ejemplos y videos que facilitan su aprendizaje9.
Cypher
Cypher es un lenguaje de consulta declarativa para gestores de base de datos en grafos
basados en SQL, permite describir los nodos o relaciones que deseamos seleccionar,
actualizar o borrar de la base de datos. Utiliza código ASCII10 (American Standard Code
for Information Interchange) para representar patrones, que estructuran las consultas.
De tal forma que, para definir un nodo se utilizan paréntesis de esta forma: (nodo)
Una vez definido el nodo se puede referir a él asignándole una etiqueta como (p) aunque
se puede usar un identificador de tal forma que ayude a identificar el nodo de una forma
más natural, por ejemplo se puede usar (persona) para un nodo que se refiera a un ser
humano.
Para encontrar las relaciones entre los nodos se utiliza un patrón que tiene esta forma:
(persona)-[v:vive_en]->(ciudad)
De esta forma se pide la relación viven_en, es decir qué personas viven en cada ciudad.
También se puede acceder a las propiedades (property) de los nodos utilizando una
sentencia de tipo: persona.nombre esta consulta devolverá la propiedad nombre del
nodo persona. O la consulta v.desde para devolver una propiedad de la relación que en
el ejemplo sería vive desde (una fecha)
Cypher también permite hacer uso de etiquetas (LABEL) permitiendo asignar tipos a los
nodos. Por ejemplo se puede crear el nodo (p:Persona) esto creará un nodo denominado
p de tipo Persona.
9
neo4j.com/docs/2.2.3
Código Estándar Estadounidense para el Intercambio de Información
10
20
Finalmente haciendo uso de la sentencia MATCH y RETURN se puede recuperar nodos
o relaciones almacenadas. Por ejemplo: MATCH (p:Persona) RETURN p que devolverá
los nodos p de tipo Persona.
Adicionalmente Cypher permite utilizar las cláusulas Distinct, Where y Order by de la
misma forma que se usan en una base de datos relacional.
MATCH (c:Ciudad) WHERE ciudad.nombre = "Quito" RETURN c, devolverá el
nodo c de tipo Ciudad cuyo atributo nombre posea el valor Quito.
HTML
Es un lenguaje de marcado que utiliza etiquetas, atributos y variables para el desarrollo de
páginas web cuyas siglas traducidas al español significan lenguaje de marcas de
hipertexto.
Una de las características más importantes de las páginas Web modernas es que son
hipertexto. Esto quiere decir que las páginas no son elementos aislados, sino que están
conectadas a otras mediante links (enlaces hipertexto). Estos enlaces permiten al
navegante pulsar sobre un texto de una página (un link) para navegar hasta otra página.
El lenguaje de marcado HTML permite desarrollar documentos Web insertando en el texto
de los mismos una serie de etiquetas que controlan los diferentes aspectos de la
presentación y comportamiento de sus elementos. A su vez las etiquetas pueden contener
atributos y variables.
Para añadir un elemento ajeno a la página, como una imagen, un video, etc. Este no se
incrusta directamente en el código de la página, sino que se hace una referencia a la
ubicación de dicho elemento mediante texto. De este modo, la página web contiene sólo
texto mientras que recae en el navegador web (interpretador del código) la tarea de unir
todos los elementos y visualizar la página final.
Las etiquetas que controlan el comportamiento del documento son fragmentos de texto
encerrados entre los signos < > (mayor que y menor que) (<etiqueta>). Existen diferentes
21
tipos de etiquetas, algunas definen la presentación del texto del documento, la forma en
que se incluirán en el documento elementos externos y los hiperenlaces con documentos
o con diferentes partes del mismo documento. Las etiquetas funcionan la mayoría de veces
en parejas, un símbolo para indicar el inicio de enlace o formato, y otro para señalar el
final. La marca de inicio es una letra o una palabra (por ejemplo <B>, <TITLE>). La
marca de final es la misma letra o palabra precedida por la barra inclinada o "slash" (</B>,
</TITLE>). Existen algunas marcas que no requieren su pareja de cierre, por ejemplo
<BR> (que fuerza un salto de línea).
Para escribir HTML lo único que se necesita es un editor de texto ASCII, como el Bloc
de notas de Windows. Los documentos HTML deben tener la extensión html o htm, para
que puedan ser visualizados en los navegadores.
JavaScript
Es un lenguaje de programación interpretado que nació como un lenguaje de scripting del
lado del cliente, es decir, para programar ciertos comportamientos sobre las páginas web
que respondían a la interacción del usuario. Con JavaScript (JS) se pueden llevar a cabo
todo tipo de acciones e interacciones como validar formularios, mostrar cajas de diálogo,
etc. Además, mediante JS se pueden enviar instrucciones al navegador con el propósito
de cambiar la página después de que se haya descargado. A JavaScript se le denomina
"del lado del cliente" porque donde se ejecuta es en el navegador (cliente web) y es éste
el que soporta la carga de procesamiento. Actualmente con JS se pueden hacer muchas
cosas más como implementar todo tipo de efectos, interfaces de usuario y comunicación
asíncrona con el servidor por medio de AJAX (Asynchronous JavaScript And XML).
El código JavaScript se debe incluir entre las etiquetas <script>...</script>.
Además, para que la página sea válida, es necesario definir el atributo type de la etiqueta
<script>. Técnicamente, el atributo type se corresponde con "el tipo MIME", que es un
estándar para identificar los diferentes tipos de contenidos. El "tipo MIME" correcto para
JavaScript es text/JavaScript.
22
Entre las características principales de JavaScript podemos citar:
-
Aunque al código JavaScript se puede escribir directamente en un documento
HTML, o XHTML como ocurre con las hojas de estilo CSS, suele ser más útil
como un archivo independiente linkeado a cada documento que necesite de los
comportamientos definidos en él. De esta forma, con un solo archivo podemos
lograr que varios documentos tengan el mismo comportamiento con tan solo
agregar esta línea al comienzo del documento html o xhtml que nos permite
vincular el archivo independiente .js (JavaScript) al documento HTML o XHTML
que deseemos.
<script type="text/javascript"src="URL_de_archivo.js"></script>
-
JavaScript es un lenguaje interpretado, no compilado, esto quiere decir que el
navegador lee, entiende y ejecuta el código, la carga está del lado del cliente.
-
Es case sensitive, es decir sensible a mayúsculas/minúsculas: una variable llamada
matriz es diferente de otra variable llamada Matriz, por ejemplo.
-
Si no se termina en punto y coma las líneas de código, el intérprete de JavaScript
considerará un salto de línea como el final de un enunciado.
-
La sintaxis de los comentarios depende del número de líneas:
// …éste es un comentario de una sola línea…
/* …éste es un bloque de comentarios que ocupa varias líneas… */
-
Los bloques de código son un conjunto de enunciados que deben interpretarse
como una secuencia completa —como por ejemplo una función—. Se indican con
llaves ({}).
CSS
Hoja de Estilo en Cascada o CSS (siglas en inglés de cascading style sheets) permite
separar los contenidos de la página de su aspecto, dentro de la propia página HTML se
23
crea una zona en la que se incluye toda la información relacionada con los estilos de la
página. Existen dos maneras de incluir CSS:
-
Incluir CSS en el mismo documento HTML.- La etiqueta <style> crea una zona
especial donde se incluyen las reglas CSS que se aplican en la página.
-
Definir CSS en un archivo externo.- Los estilos CSS se incluyen en un archivo de
tipo CSS que las páginas HTML enlazan mediante la etiqueta <link>. Un archivo
de tipo CSS no es más que un archivo simple de texto cuya extensión es .css Cada
página HTML puede enlazar tantos archivos CSS como sea necesario.
CSS define una serie de términos que permiten describir cada una de las partes que
componen los estilos CSS.
Figura 15 Estructura CSS
Regla.- Cada uno de los estilos que componen una hoja de estilos CSS. Cada regla está
compuesta de una parte de "selectores", un símbolo de "llave de apertura" ({), otra parte
denominada "declaración" y por último, un símbolo de "llave de cierre" (}).
Selector: Indica el elemento o elementos HTML a los que se aplica la regla CSS.
Declaración.- Especifica los estilos que se aplican a los elementos. Está compuesta por
una o más propiedades CSS.
Propiedad.- Es una característica que se modifica en el elemento seleccionado.
Valor.- Establece el nuevo valor de la característica modificada en el elemento.
24
JQuery
JQuery no es un lenguaje, sino una serie de métodos y funciones de JavaScript. JQuery es
una librería que podemos usar opcionalmente. Nos podemos referir a JQuery como
framework o incluso como un API de funciones modular de JS útiles en la mayoría de
proyectos web, cuando un desarrollador utiliza JavaScript, generalmente tiene que
preocuparse por hacer scripts compatibles con varios navegadores y para ello tiene que
incorporar código para detectar el browser del usuario, JQuery implementa una serie de
clases (de programación orientada a objetos) que nos permiten desarrollar sin importar
con qué navegador nos está visitando el usuario. Así pues, ofrece una infraestructura con
la que se tiene mayor facilidad para la creación de aplicaciones complejas del lado del
cliente por ejemplo, se obtiene ayuda en la creación de interfaces de usuario, efectos
dinámicos, aplicaciones que hacen uso de Ajax, etc.
El constructor de JQuery se comporta de la siguiente manera, al recibir un string lo toma
como una query (consulta) y devuelve un conjunto de elementos del DOM (Modelo de
Objetos del Documento), que pertenecen al resultado de la consulta y en caso de no
encontrar ningún elemento que cumpla con la consulta nada devuelve un conjunto vacío.
Entre las características que posee JQuery se tiene la manipulación de eventos y hojas de
estilos CSS, selección de elementos de la página web, crear efectos y animaciones
personalizadas, hacer uso de AJAX, entre otras.
Otra característica significativa de JQuery es su flexibilidad para hacer consultas a través
del DOM. JQuery básicamente permite hacer 3 tipos de consultas: CSS, Xpath y
Trasversales.
El archivo del JQuery ocupa unos 56 KB, el servidor lo enviará al cliente la primera vez
que visite una página. En las siguientes páginas el cliente ya tendrá el archivo del
framework, por lo que no necesitará transferirlo y lo tomará de la caché. Con lo que la
25
carga de la página sólo se verá afectada por el peso de este framework una vez por
usuario11.
D3.JS
Es una librería de JavaScript que permite manipular documentos Web que se basan en
datos, es decir permite visualizar datos utilizando HTML, SVG y CSS, combina elementos
de visualización, transformación y manipulación de DOM. Esto se puede lograr gracias a
que D3.js nos permite “conectar” datos a un DOM y generar a partir de esos datos: tablas,
grafos u otras formas de visualización/transformación de datos12.
D3.js nos permite representar un grafo, y otras formas de visualización de manera
dinámica, gracias a que es el mejor framework de JavaScript para este uso en particular,
esto lo hace valiéndose de módulos y métodos propios como13:
D3.layout.force.- Para ubicar y unir los nodos.
Force.nodes.- Definir u obtener un arreglo de nodos del layout.
Force.links – Obtener o establecer el arreglo de enlaces entre los nodos
Force.charge – Definir o recuperar la fuerza de la carga.
Force.linkDistance – Obtener o establecer la distancia de los enlaces entre nodos.
Force.size. – Establecer u observar el tamaño del layout en términos de x, y.
D3.select.- Selecciona un elemento del documento actual.
D3.selectAll.- Selecciona varios o todos los elementos .del documento actual
Selection.on.- Nos permite agregar o quitar eventos que escuchan interacciones.
11
jquery.com/download
d3js.org/
13
github.com/mbostock/d3/wiki/API-Reference
12
26
Selection.append.- Crea y concatena nuevos elementos.
Selection.attr.- Fija o devuelve propiedades de los elementos.
Selection.data.- Obtiene o establece datos de un grupo de elementos mientras computa un
join relacional entre ellos.
Entre otros, siendo estos los principales módulos y métodos en que se basa una
representación en forma de grafo en d3.js.
Grandes conjuntos de datos pueden ser unidos a objetos SVG (gráficos vectoriales
escalables) utilizando funciones simples D3 para generar texto enriquecido, gráficos y
diagramas. Los datos de entrada pueden estar en diversos formatos pero comúnmente se
usa JSON (JavaScript Object Notation), valores separados por comas (CSV) o GeoJSON.
27
3
3.1
CAPÍTULO III
METODOLOGÍA
Durante el proceso de ejecución del proyecto, se pasan por diferentes fases de aprendizaje
y desarrollo. Las más relevantes son las siguientes:
1. Estudio y análisis de la teoría de grafos para un entendimiento correcto de una
base de datos en grafos.
2. Estudio y análisis de las diferentes tecnologías que soportan GDB y en concreto
de la tecnología Neo4j y su lenguaje de consulta (Cypher).
3. Estudio y análisis de las diferentes tecnologías que permiten la representación de
datos multimedia en forma de grafo en la web (librerías JavaScript, en concreto
D3.js).
3.2
DISEÑO DE LA APLICACIÓN WEB
Librerías para grafos
Para determinar la librería más adecuada para la implementación del prototipo se requiere
de un análisis de las librerías JavaScript de uso libre que permitan la representación de
grafos, entre ellas están d3.js14, sigma.js15, vis.js16, alchemy.js17.
Para realizar una elección correcta se visualizan y se manipulan ejemplos de cada una de
las librerías para entender sus funciones: cómo se aplican, qué acciones realizan y qué
beneficios tienen, también se desarrollan pequeñas aplicaciones para establecer cuando se
las puede utilizar y su efectividad en el caso concreto de Bases de Datos en Grafo y
finalmente se prueban sus conexiones con los diferentes lenguajes de programación y se
analiza cómo interactúan.
Después de un análisis minucioso se decide utilizar la librería d3.js ya que posee las
características necesarias para diseñar e implementar las librerías JS necesarias para el
14
d3js.org
sigmajs.org
16
visjs.org
17
graphalchemist.github.io/Alchemy
15
28
funcionamiento del prototipo. Se considera que es la más óptima y la más completa
respecto a las aplicaciones e interacciones que posee, además se considera que la librería
d3.js es la más adaptable a las necesidades del proyecto, incluyendo el área multimedia.
Figura 16 Ejemplo de D3.js con Nodos en Movimiento
Figura 17 Ejemplo de D3.js con Zoom a los Nodos
29
Figura 18 Ejemplo de D3.js con Datos Geográficos Con Zoom
Figura 19 Ejemplo de D3.js de Nodos Con Apertura y Cierre de Nodos
Para iniciar con el uso de la librería D3.js se realizan pruebas simples para la comprensión
de la misma:
Se empieza mostrando en pantalla nodos planos sin ningún tipo de movimiento con sus
respectivas relaciones, almacenados en un arreglo tipo JSON, en donde por una parte están
los nodos, en este caso únicamente con las propiedades de posicionamiento y por otro
están los links en donde se tiene los atributos source que contiene al nodo en el que inicia
la dirección de la relación y en target se coloca el nodo en el cual termina la relación, de
esta manera podemos obtener la direccionalidad de las relaciones cuando sea necesario.
30
Figura 20 Ejemplo Nodos Estáticos
Luego se continúa el aprendizaje de la librería utilizando más características para hacer la
aplicación interactiva, para lo cual utilizamos el método d3.layout.force el cual nos
permite construir una simulación física para los nodos y sus relaciones, esto quiere decir
que se puede utilizar características como gravedad, fuerza o distancia entre nodos, de
igual manera con datos introducidos previamente en un JSON (JavaScript Object
Notation) incrementando atributos para cada nodo: nombre, tipo e incluso rutas que
contienen imágenes o videos. Por supuesto a las relaciones o links además del source y el
target se les puede agregar más atributos como son tipos o nombres.
Figura 21 Ejemplo utilizando Layout
Uso de Cypher
Para poder mostrar nodos que se encuentran en una Base de Datos en Grafo necesitamos
conectar nuestro prototipo de representación de grafos en la web con un lenguaje de
31
consulta, para lo que se inicia el estudio del lenguaje Cypher y el funcionamiento de Neo4j
con consultas sencillas.
A continuación se muestra una de las consultas más simples que se pueden realizar con
Cypher, en la cual empezamos en un nodo cualquiera de la base de datos (utilizando el
símbolo *) o en un nodo específico (utilizando el identificador del nodo que se sustituirá
por el símbolo *). RETURN n nos devolverá los nodos seleccionados, en vista que tenemos
una base de datos extensa debemos ponerle un límite de nodos que nos va a retornar.
Figura 22 Consulta de 20 Nodos
A partir de esta primera consulta básica se puede construir consultas un poco más
completas para obtener mayor información, en este caso se utiliza el MATCH para expresar
que n tiene una relación con otro nodo que identificamos mediante x sin importar la
dirección de la relación y nos retorna el nodo n, sus vecinos y sus relaciones.
32
Figura 23 Consulta de un Nodo, sus Vecinos y sus Relaciones
También se puede realizar consultas más complejas restringiendo los nodos que se desea
obtener. En el MATCH definimos 2 relaciones, la de n con x y otra de x con b, lo que se
desea obtener son los nodos x que sean de tipo Inmaterial, que estén relacionados con n y
que estén relacionados con nodos que sean de tipo Ámbito, finalmente se pide que nos
retorne los nodos n,x y b y sus respectivas relaciones con un límite de 20 resultados.
Figura 24 Consulta de Nodos de acuerdo al Tipo de Nodo
33
Dentro del desarrollo de la aplicación se realizan 11 consultas a la base de datos similares
a las que se muestran en los ejemplos anteriores, pero en este caso se debe realizar las
consultas
cypher
con
JavaScript
mediante
una
petición
AJAX(Asynchronous JavaScript And XML) asíncrona para que permita continuar con la
navegación y no bloquee la aplicación , de esta manera se obtiene la información requerida
directamente de la base de datos en tiempo real, esto es fundamental para que la aplicación
sea capaz de conectarse con cualquier Base de Datos en Grafo.
34
Apertura De Nodos
La librería D3 nos permite manejar eventos con el mouse para tener una mayor interacción
con los nodos.
Tabla 1 Eventos del Mouse
Evento
mouseover
Función
Pasar el puntero del mouse sobre el
elemento.
mouseout
Retirar el puntero del mouse del elemento.
click
Dar clic sobre el elemento.
dblclick
Dar doble clic sobre el elemento.
En el evento click sobre el nodo se llama a la función unclick la cual invoca a su vez a
varias funciones (véase Anexo G - unclick), entre las cuales se encuentra la función para
la verificación del número de nodos vecinos que posee el nodo seleccionado para proceder
con la apertura de nodos. En el caso que el número de nodos vecinos sea menor o igual al
límite establecido se realiza la consulta para que nos retorne todos sus vecinos, se guarda
todos los datos necesarios por cada elemento, para lo que se invoca a la función
abrirvecinos en la cual se verifica si el nodo que se quiere añadir no se encuentra ya
almacenado, en ese caso se almacena junto con su relación como datos JSON para
finalmente actualizar la visualización en pantalla (véase Anexo LAnexo K).
La actualización del svg en pantalla se realiza reiniciando el force (método de D3.js para
ubicación de nodos en el layout) de los nodos y redibujando con sus características los
nodos y sus relaciones (véase Anexo G- ActalizaGrafo).
35
Figura 25 Nodo antes de dar click
Figura 26 Apertura de Nodos con el evento click
Cierre De Nodos
Una vez que la apertura de nodos funciona correctamente, se debe pensar en la manera
más sencilla posible para que el usuario pueda quitar nodos que no le interesa en su
navegación.
Debido a que en el evento click se utiliza la apertura de nodos, para el usuario es más
intuitivo que para el cierre de los mismos se utilice el evento dblclick (doble click) sobre
los nodos (véase Anexo G - Dosclick).
Se debe analizar las diferentes posibilidades que se tiene para cerrar los nodos vecinos del
nodo que ha sido seleccionado por el usuario para ser eliminado, entre las cuales se tiene:
36
1.
Cerrar los nodos vecinos sin cerrar sus nodos padres ni tampoco el nodo
seleccionado.
2.
Cerrar el nodo y todos sus vecinos.
3.
Cerrar todos sus vecinos y dejar el nodo seleccionado.
Después de analizar la lógica de cada una de las formas de cerrar los nodos se decide que
el cierre se realizará de manera que se elimine el nodo seleccionado y sus vecinos (opción
2), siempre y cuando no sean nodos padres (que significa que no sea el nodo del cual se
origina el nodo seleccionado) o tengan relacionados más de un nodo, en el caso que sus
nodos vecinos tengan más de una relación pero no sean padres se eliminará únicamente la
relación con el nodo seleccionado.
Para realizar la eliminación de nodos lo primero que se hace es guardar el nodo
seleccionado dentro de un arreglo en el que se guardarán todos los nodos a eliminarse
(Véase Anexo M). A continuación se busca todos los nodos vecinos que tenga el nodo
seleccionado verificando todas las relaciones, una vez que tengamos todos sus vecinos se
verifica el número de relaciones que tiene cada nodo vecino, si el nodo tiene una sola
relación que corresponda a la que lo une con el nodo seleccionado se agrega al arreglo de
nodos a ser eliminados y en el caso que tenga más de una relación o se encuentre
almacenado en una posición anterior al nodo pulsado, no serán eliminados.
Finalmente se compara los nodos que se tiene almacenados en el arreglo de eliminados
con los nodos que se encuentran en nodes (arreglo donde se encuentran almacenados todos
los nodos que se están visualizando), y se elimina uno por uno si coincide, de la misma
manera se maneja las relaciones tomando en cuenta que primero se debe eliminar las
relaciones que tengan los nodos para luego eliminar los nodos (véase Anexo N).
37
Figura 27 Nodos con sus Vecinos
Figura 28 Cierre de nodos con el evento doble click
Una vez finalizada la implementación del cierre de nodos y al verificar el funcionamiento
general, se observa que si se vuelve a dar click sobre un nodo que ya tenga sus vecinos
visibles se muestran más vecinos permaneciendo también los anteriores, lo que puede
hacer que aumente de manera drástica el número de nodos en pantalla, por esta razón se
decide que en este caso se eliminen primero los nodos que estén visibles para de esta forma
mostrar los nuevos vecinos del nodo seleccionado (de esta forma, además se le da la
posibilidad a el usuario de que recorra la Base de Datos completa).
Para implementar la solución se coloca un condicional para verificar la acción, si se da
doble click para eliminar todos los nodos o si se da click, en el último caso antes de abrir
38
los nodos vecinos se verifica si ya tiene vecinos el nodo pulsado y de ser así primero se
elimina los nodos vecinos que no tengan más relaciones y luego se muestra otros vecinos.
(Véase Anexo N).
Figura 29 Nodo con sus Vecinos
Figura 30 Nodo con otros vecinos sin los anteriores
Facetado Global
Ya con la estructura de navegación básica funcionando correctamente, se necesita una
manera simple y rápida para que el usuario tenga la posibilidad de filtrar los nodos y las
relaciones.
Al observar las bases de datos en grafos y su estructura, se tiene a los nodos y a sus
relaciones agrupados por tipos, haciendo uso de esto, se obtendrá los diferentes tipos de
39
nodos y tipos de relaciones que tenga la base de datos para mostrarlos en pantalla y darle
al usuario la opción de elegir los tipos que le interesa observar durante su navegación,
tomando en cuenta que puede variar su elección en cualquier momento.
Para la obtención de los tipos de nodos y relaciones se realiza una consulta mediante el
lenguaje de consulta Cypher a la base de datos, una vez que se devuelven todos los tipos
se almacenan y se agregan junto a un checkbox (véase Anexo E Anexo F).
Luego en funciones separadas se verifica si cada checkbox de tipo de nodo o tipo de
relación está seleccionado para según esto construir las consultas de manera tal que sólo
se obtengan nodos y relaciones de los tipos seleccionados (véase Anexo G – tipNodos y
tipRelaciones).
Figura 31 Tipos de Nodos
Figura 32 Tipos de Relaciones
40
Facetado Local
Al momento de abrir los nodos vecinos a un nodo dado en una Base de Datos en Grafo
con datos reales nos encontramos usualmente con un número extremadamente grande, por
lo cual es imperativo que se tenga una manera de restringir este comportamiento
mostrando únicamente un número limitado de vecinos, para que el usuario pueda tener
mayor facilidad a la hora de captar la información y pueda navegar sin complicaciones.
Cuando se da click sobre un nodo, primero se realiza una consulta a la base de datos para
determinar cuántos nodos vecinos tiene el nodo pulsado, de acuerdo a esto se realiza la
siguiente llamada a otra función con una consulta diferente, en el caso que el número de
nodos vecinos sea mayor al límite establecido se deben filtrar de alguna manera para
mostrar los nodos que al usuario más le interese (véase Anexo J).
Ya que en una base de datos en grafos es más eficiente realizar consultas según las
relaciones que por sus propiedades, se va a realizar un filtrado por el tipo de nodos vecinos
y por el tipo de relaciones que posean sus vecinos, para ello primero consultamos qué
tipos de nodos tiene como vecinos y cuantos son de cada tipo, se los almacena para luego
mostrarlos en una lista para que el usuario pueda seleccionar un tipo determinado (véase
Anexo P).
Si el número de nodos vecinos del tipo seleccionado es menor o igual al límite establecido
nodos aparecen automáticamente los vecinos (véase Anexo Q), pero si el número de nodos
es mayor se realiza otro filtro en donde se muestra una lista con el tipo de relaciones que
tienen los nodos vecinos del nodo seleccionado y de igual manera se selecciona una de las
opciones que se presente (véase Anexo R).
De acuerdo a lo seleccionado se realiza una nueva consulta con los filtros
correspondientes, en esta nueva consulta lo que se obtiene son los nodos que están
conectados con este tipo de relación y el número de nodos vecinos que tienen la relación
escogida y están conectados con el nodo que se muestra, en esta parte del filtrado se
presenta la lista junto a checkbox para que el usuario pueda escoger uno o varios grupos
de nodos (véase Anexo S).
41
Para tener más claro este paso se va a ejemplificar. Si un nodo de tipo provincia tiene
nodos vecinos de tipo cantón e inmaterial y se desea ver los vecinos de tipo
inmaterial.
Figura 33 Facetado Local - Tipos de Nodos Vecinos
Al escoger se despliega la lista de tipos de relaciones que tienen los nodos de tipo
inmaterial, por ejemplo nos despliega que tiene relaciones de tipo comunidad,
lengua,
ámbito,
subámbito,
detalle
de
subámbito,
cantón,
parroquia, etc.
Figura 34 Tipos de Relaciones del Nodo del Tipo seleccionado
Si se elige en este caso por ejemplo ámbito nos desplegará las opciones de nodos
relacionados que tiene. Por ejemplo, nodos de tipo inmaterial cuyo ámbito es
tradiciones y expresiones orales o aquellos cuyo ámbito es artes del
espectáculo...
42
Figura 35 Grupo de nodos que se relacionan con el tipo de nodo seleccionado
Si en este caso se escoge únicamente artes del espectáculo que tiene 151 nodos lo que se
va a obtener son 25 (límite establecido) nodos vecinos de tipo inmaterial relacionados con
el nodo artes del espectáculo.
En el caso de elegir más de un grupo de nodos se procede de la siguiente manera: se divide
el límite que se tiene para los nodos, que en este caso es 25, para el número de checkbox
que se encuentren seleccionados para tener un límite provisional para cada consulta que
se realizará por cada selección que se hizo.
Figura 36 Selección de Grupo de nodos
Debido a que Neo4j retorna los nodos en forma ordenada desde el primer nodo encontrado,
para poder visualizar diferentes nodos en cada consulta y abarcar mayor extensión al
43
navegar en la base de datos se utiliza skip en la consulta Cypher la cual indica cuántas
posiciones saltar antes de seleccionar los nodos e ingresaremos un valor aleatorio de
acuerdo al número de nodos (esto nos permite retornar en cada caso un conjunto diferente
de vecinos).
De tal manera que la consulta (en el caso descrito) se realiza con los parámetros
anteriormente escogidos que son: el tipo de nodo vecino, el tipo de nodo que tiene
relacionado el vecino, el nombre del nodo con el tipo escogido, el punto de inicio que se
obtendrán los nodos y el límite de nodos que se obtiene por cada consulta.
Figura 37 Vecinos al azar
44
3.3
DISEÑO VISUAL DE LA APLICACIÓN WEB
El desarrollo visual se realiza una vez que las funcionalidades de la aplicación han sido
implementadas, ordenando cada elemento de la navegación: el facetado global, el facetado
local, guías, información de los nodos e inicio desde un nodo determinado. De esta manera
el usuario podrá tener una visualización amigable y de fácil entendimiento.
Se ha escogido la librería de estilo CSS Bootstrap18 ya que se considera que es la librería
que posee los componentes adecuados para la presentación de este proyecto.
Los nodos se grafican de diferentes colores de acuerdo al tipo al que pertenezca, para que
el usuario pueda identificar de qué tipo son los nodos que se encuentran en pantalla se
coloca en la parte superior nodos guías con los respectivos colores y al momento de pasar
el mouse sobre los nodos guías nos muestra el nombre del tipo al que corresponde, de la
misma manera si se pone el mouse sobre los nodos se podrá observar a qué tipo de nodo
corresponde. Para poder mostrar las etiquetas de la manera descrita se utiliza la librería
d3-tip19, que es una librería adjunta a la librería d3.js.
Figura 38 Nodos Guías - Tipos de Nodos
18
19
getbootstrap.com
github.com/Caged/d3-tip
45
Figura 39 Tipo de Nodo en evento mouseover
La aplicación inicia sin ningún nodo en pantalla para dar la opción al usuario de escoger
desde qué nodo desea iniciar su navegación, para ello se coloca un textbox o cuadro de
texto junto con un botón y un desplegable utilizando la librería de bootstrap
(específicamente input groups – buttons with dropdowns) en donde se podrá escoger el
criterio de selección del nodo inicial. Las opciones que se presentan son Provincia, Cantón
y Lengua.
Figura 40 Opciones para el Primer Nodo
Se debe seleccionar primero el criterio mediante el que se desea buscar, luego ingresar el
nombre y luego hacer click en buscar, entonces se mostrará en pantalla el primer nodo
para comenzar con la navegación.
46
Figura 41 Primer Nodo de la Navegación
Con el evento mouseover se visualiza el nombre del nodo, como se observa en la figura
anterior, el nodo es de tipo Provincia y su nombre es Pichincha, para observar la
información completa del nodo se tiene que dar click sobre el nombre y se despliega una
ventana modal con características de la librería de estilo Bootstrap.
La ventana modal consta de un título el cual corresponde al nombre del nodo seguido de
la información o atributos que posee el nodo, debajo de la información se encuentra el
contenido multimedia como pueden ser imágenes, videos, documentos o audios y
finalmente un botón para cerrar o también se puede cerrar dando click fuera de la ventana
modal.
La información se la muestra utilizando la función infoNodos (véase Anexo H), se realiza
una comparación entre los datos que se encuentran almacenados en el nodo y los datos
que se desea mostrar, los cuales fueron previamente definidos en el archivo de
configuración, se toma dato por dato el nombre del atributo y su valor para ir agregando
a la ventana modal de forma ordenada. Para la información multimedia se toma la
información almacenada en el nodo seleccionado, se verifica el tipo de archivo y se lo
muestra dentro del modal.
47
Figura 42 Ventana Modal - Información del Nodo
Se tiene un archivo de configuración en el cual se define el enlace donde se encuentra la
base de datos, el número máximo de nodos a mostrar, y un diccionario para definir los
atributos del nodo que se desea mostrar dentro de la ventana modal. El diccionario se lo
realiza utilizando hashtable, que es una variable tipo objeto en la cual se almacena el
nombre del dato y su valor, como si fuera una matriz (véase Anexo C).
Para la presentación del facetado o filtrado global se utiliza el elemento de la librería
bootstrap collapse – collapse group20 el cual nos permite mostrar únicamente los títulos
que en este caso sería Tipos de Nodos y Tipos de Relaciones, se puede observar la
información que contiene dando click sobre el nombre, al momento que se requiere abrir
la siguiente pestaña la anterior se contrae, dentro se tiene los tipos de nodos y relaciones
con los respectivos checkbox para la selección.
20
getbootstrap.com/javascript/#collapse-example-accordion
48
Figura 43 Collapse - Tipos de Nodos
Figura 44 Collapse - Tipos de Relaciones
La visualización del facetado local se realiza dentro de un popover el cual contendrá los
select con los tipos de nodos vecinos, tipos de relaciones y los nodos.
49
Figura 45 Facetado Local - Popover
El usuario necesita guías para conocer sobre la utilización de los elemento de la aplicación
web, se coloca tooltip con la librería Bootstrap en los diferentes elementos indicando cuál
es su función.
Figura 46 Tooltip - Nodo inicio
Figura 47 Tooltip - Facetado Global
50
3.4
MANUAL DE USUARIO
El presente prototipo de un navegador web de una base de datos en grafos permite navegar
a través de sus elementos online, en este caso los bienes culturales del INPC, observando
todas las relaciones que existen entre los datos, además de representar la información
multimedia.
La navegación a través de grafos proporciona una visualización de los datos en su contexto
lo que ayuda al usuario a tener un mayor entendimiento sobre el tema que se encuentra
investigando.
Requerimientos Del Sistema
Debido a que es un navegador web, para la utilización de la aplicación se necesita el
navegador web de su elección.
Uso del Navegador
La aplicación consta de varias partes esenciales:
-
Input group: el cual consta de un cuadro de texto, un botón y un dropdown. Este
elemento se utiliza para seleccionar el nodo desde el que se iniciará la navegación.
Figura 48 Criterios para Nodo inicial
Se debe seleccionar un criterio para la selección del nodo inicial: Provincia, Cantón o
Lengua (Los criterios pueden variar de acuerdo a la base de datos a la cual esté conectada
la aplicación). Si sabe el nombre del nodo con el cual desea empezar se escoge una de
estas opciones y se escribe en el cuadro de texto el nombre y se procede a dar click en
buscar.
51
En el caso de no saber el nombre del nodo por el que se desea empezar tenemos la opción
de ID Nodo con el que se puede ingresar un número que corresponde al identificador o
posición del nodo dentro de la base de datos.
Figura 49 Ejemplos de nodos que se pueden buscar
Una vez ingresado el dato se debe dar click en el botón buscar y se mostrará el primer
nodo.
Figura 50 Nodo inicial
-
Facetado global: esta parte es importante para restringir la navegación en el caso
de no desear ver todos los tipos de nodos o todos los tipos de relaciones. Para
ajustar este comportamiento se debe dar click sobre el nombre tipos de nodos o en
tipos de relaciones para que se despliegue la información y seleccionar o
deseleccionar los tipos que se deseen, por defecto viene todos los tipos marcados,
esto quiere decir que se podrá observar los nodos de todos los tipos que posee la
base de datos.
52
Figura 51 Selección Tipo de Nodos
Figura 52 Selección Tipo de Relaciones
-
Nodos guías: los nodos guías son los que se encuentran justo debajo del facetado
global, los cuales ayudarán a el usuario a entender los colores en los nodos y el
tipo al que pertenecen, solo se necesita pasar el puntero del mouse sobre dichos
nodos o a su vez se puede ver el nombre del tipo de los nodos al momento de pasar
el puntero por cualquier nodo nos dará el nombre del tipo que le corresponde de
acuerdo al color.
Figura 53 Nodos Guías
53
Figura 54 Información y Tipos de Nodos
Apertura de nodos
Para abrir los nodos vecinos de un nodo dado, se debe dar click sobre el nodo, en el caso
que el número de nodos vecinos sean menores al límite establecido se mostrarán
automáticamente (el número máximo de nodos que se mostrarán en pantalla se lo puede
configurar desde el archivo config.js que por defecto se encuentra en 25), en caso contrario
se abrirá un popover el cual contendrá un select en donde tendremos la lista de tipos de
nodos a los que pertenecen los nodos vecinos junto con el número de vecinos que tiene de
cada tipo.
Figura 55 Tipos de Nodos Vecinos
Al escoger una de las opciones se tiene 2 posibilidades la primera es que si el número de
nodos es menor al límite establecido se abra automáticamente y la segunda que si es mayor
al límite establecido se abrirá un segundo select en el cual se desplegarán los tipos de
relaciones que van a tener los nodos vecinos del tipo escogido.
54
Figura 56 Tipos de Relaciones de Nodo Vecino
Se debe elegir un tipo de relación y se mostrarán los nodos que están relacionados con los
nodos vecinos con el tipo de relación escogida junto con el número de nodos vecinos que
tienen dicha relación, se puede escoger uno o varios nodos seleccionando los checkbox.
Figura 57 Grupo de Nodos que están conectados con nodos Vecinos
Una vez escogidos los nodos se debe dar click al botón denominado Vecinos para que se
muestren los nodos vecinos.
55
Figura 58 Apertura de Nodos Vecinos
Cierre de nodos
Si no desea observar algunos de los nodos que se muestran en pantalla, éstos se puede
ocultar haciendo doble click sobre ellos. De ésta forma, también se eliminarán los vecinos
que no tengan más de una relación o que se hayan almacenado antes del nodo pulsado.
Figura 59 Cierre de Nodos
Información completa del nodo
Si se desea conocer más información sobre un nodo en específico lo que se debe hacer es
dar click sobre el nombre que aparece al pasar el puntero sobre el mismo y se abrirá una
ventana modal en la que se podrá mirar toda la información sobre el nodo.
Los datos que se pueden encontrar son: nombre completo del nodo, descripción del nodo,
descripción de algunas relaciones con otros nodos, información multimedia que pueden
56
ser imágenes, videos, audios, o archivos de texto, descripción de la información
multimedia, entre otras.
Figura 60 Ventana Modal con Información del Nodo
Configuración del navegador
En el caso que se desee administrar el navegador para utilizarlo con una Base de Datos en
Grafo (Neo4j) diferente, se deben configurar algunos parámetros en el archivo config.js.
Para conectar la base de datos con la aplicación se debe cambiar la ruta de enlace que se
encuentra almacenada en la variable enlace.
El máximo de nodos vecinos que se obtienen de un nodo seleccionado se puede cambiar
en la variable totalimite.
Para establecer qué propiedad se utiliza como etiqueta de los nodos se debe configurar la
variable camp_tooltip, esto se realiza de acuerdo a los tipos de nodos que tenga la base de
datos, para cada tipo se debe ingresar el nombre del atributo a mostrar.
En la variable camp_modal se configura los atributos que se desea visualizar de la
información general asociada a un nodo, en cada tipo de nodo se crea una lista de atributos
que se desee mostrar.
57
4
4.1
CAPÍTULO IV
CONCLUSIONES
En la web se puede encontrar información y tecnologías de libre uso suficientes para
desarrollar nuevas formas de representación de una Base de Datos en Grafo como la
aplicación implementada en el presente proyecto, adaptándolos a las necesidades
profesionales o personales que se tengan e innovando en su creación.
La navegación a través de una Base de Datos en Grafo puede proporcionar mayor
información que en una base de datos SQL y más cuando se tiene elementos altamente
relacionados y con un contenido multimedia, que puede ser utilizado para un análisis más
profundo de la red y su comportamiento.
Después del análisis de las diferentes tecnologías existentes se determinó que las más
adecuadas y eficientes para la elaboración de un nuevo prototipo son: Neo4j, D3.js,
JQuery y Bootstrap (aparte de Javascript y HTML, tecnologías estándar para el desarrollo
web). D3. Js es una librería muy robusta para la representación de información, no solo
en forma de grafos, y junto a las demás tecnologías se puede obtener resultados muy
favorables en diferentes campos de aplicación. Neo4j es uno de los gestores de Base de
Datos en Grafo más eficientes al momento de realizar consultas basadas en las relaciones
(así sean estas muy complejas), su lenguaje de consulta Cypher posee una estructura muy
sencilla pero permite obtener resultados muy completos.
La librerías desarrolladas permite tener funcionalidades generales como el cierre y la
apertura de nodos, combinadas con configuraciones personalizadas como la información
que se desea mostrar del nodo para cada tipo de área en la que pueda emplear la aplicación.
En el caso de uso del INPC se puede aprovechar al máximo sobre todo en la presentación
de la información multimedia por su riqueza y además el usuario puede tener una visión
más completa de cómo se encuentran conectados los bienes culturales en el Ecuador.
Gracias al uso correcto de las tecnologías y herramientas empleadas se pudo solucionar
un problema latente en los navegadores de base de datos en grafos (incluyendo Neo4j),
que es la visualización de los nodos vecinos a pesar que haya un número extremadamente
grande de éstos.
58
La presentación visual de la aplicación influye sobre el usuario, ya que si no tiene una
aplicación intuitiva y con directrices que le ayuden en su navegación ésta puede resultar
confusa, precisamente para evitar este problema la aplicación cuenta con guías en sus
elementos y tiene una interfaz intuitiva.
El aprendizaje obtenido diseñando e implementando las librerías complementa el estudio
teórico del diseño y programación web, permitiendo tener una visión más clara sobre qué
es lo que necesita el cliente para tener una experiencia constructiva a través de la web.
59
4.2
RECOMENDACIONES
Debido a que es un prototipo experimental se tiene trabajo por delante para mejorarlo y
que pueda ser presentado al público.
En el facetado local se puede obtener mejores resultados de filtrado si se realiza mediante
las propiedades de los nodos, de esta manera se tendría un facetado global por tipos y un
facetado local por propiedades, debido a que las consultas en las Bases de Datos en Grafo
son más eficientes por relaciones se perdería efectividad aumentando el tiempo de
respuesta y utilizando recursos innecesarios, se podría solucionar utilizando por debajo
consultas por relaciones y luego por propiedades con esto tendríamos resultados más
selectivos y mejoraría la captación del usuario.
La aplicación unida a otras librerías de representación de información como angular.js o
sigma.js se podría potencializar, obteniéndose una navegación a través de los nodos con
mayor número de características y funcionalidades para mejorar la experiencia del
usuario, incluso utilizando otras librerías implementadas que hacen uso de D3.js con
diferentes métodos se obtendría por ejemplo la navegación actual con opciones de
agrupación de nodos para un análisis selectivo de la red.
La presentación de la aplicación web se puede mejorar aplicando y desarrollando librerías
CSS adicionales con las cuales además de los componentes que se tiene se pueda agregar
animaciones al abrir nodos, al mostrar su información o que la aplicación pueda ser
utilizada en dispositivos móviles, también se puede utilizar un diseño personalizado con
el uso de atributos CSS en los diferentes elementos.
Se podría implementar un historial de acciones realizadas y mostrarlas en pantalla para
que el usuario pueda tener un control sobre en qué parte de la navegación se encuentra,
indicando paso a paso cómo ha ido navegando a través de la red: Qué nodos abrió el
usuario, qué nodos cerró o incluso de qué nodos mostró su información.
60
4.3
BIBLIOGRAFÍA
1. EULER, L. (1736). "Solutio problematis ad geometriam situs
pertinentis". Commentarii Academiae Scientiarum Imperialis
Petropolitanae 8. 128-140.
2. LIPSCHUTZ, S; LIPSON, M. "Matemáticas Discretas". McGraw-Hill, 1976.
Cap 8.
3. ROBINSON, I.; WEBBER, J y EIFREM, E (2013). Graph Databases.
4. ALMAGRO, P; ORDOÑEZ, S. “Generador de Grafos Multirrelacionales a
partir de Redes Sociales”. Ingeniería, vol. 19, no. 1, pp. 8-18, Mayo
2014. ISSN 0121-750X E-ISSN 2344-8393.
5. DE LA ROSA, J; SUÁREZ, J; SANCHO, F. “Sustaining a Global Community:
Art and Religion in the Network of Baroque Hispanic-American Paintings”.
Leonardo Transactions, 2011.
6. ALMAGRO, P.; DÁVILA, E; GUERRERO, G; MEDINA, I.; REGALADO,
E ; RUÍZ, Z; SALVADOR, J; SANCHO, F. “Nuevas líneas metodológicas
aplicadas al patrimonio cultural ecuatoriano”. Revista del Patrimonio
Cultural del Ecuador, Vol 6, I Semestre 2015, ISSN 1390-9231 (Directora:
Elena Noboa Jiménez).
7. FERNANDO SANCHO CAPARRINI. “Estructurando y consultando
información en grafos”, [Online] http://www.cs.us.es/~fsancho/?e=84
8. FERNANDO SANCHO CAPARRINI. “Base de Datos en Grafo”, [Online]
http://www.cs.us.es/~fsancho/?e=79
9. Mozzila. "JAVASCRIPT REFERENCE", developer.mozilla.org. [Online]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
10. D3.JS. "D3.JS DOCUMENTATION", Github [Online]
https://github.com/mbostock/d3/wiki
11. SIGMA.JS. "SIGMA.JS DOCUMENTATION", Github [Online]
https://github.com/jacomyal/sigma.js/wiki
12. JQUERY. “JQUERY API”, [Online] http://api.jquery.com/
13. NEO4J. "NEO4J DOCUMENTATION", [Online] http://docs.neo4j.org/
61
14. NEO4J. "CYPHER QUERY LANGUAGE", [Online]
http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html
15. NEO4J. "REST API", [Online] http://docs.neo4j.org/chunked/milestone/restapi.html
16. BOOTSTRAP. “BOOTSTRAP FRAMEWORK”, [Online] http://getbootstrap.com
17. D3-TIP. “D3.TIP API DOCUMETATION”, [Online]
https://github.com/Caged/d3-tip/blob/master/docs/index.md
18. SYLVA. “GRAPH DATABASES SYLVA MADE EASY FOR EVERYONE”,
[Online] http://sylvadb.com/
19. LINKURIOUS. “LINKURIOUS FEATURES”, [Online]
http://linkurio.us/product/
20. INSTITUTO NACIONAL DE PATRIMONIO CULTURAL DEL ECUADOR
[Online] http://inpc.gob.ec/
62
4.4 ANEXOS
Anexo A. Index.html
<html>
<meta charset="utf-8">
<body>
<!-- librerias -->
<script src="../static/js/resourse/d3.js"></script>
<script type='text/javascript'
src="../static/js/resourse/d3.tip.v0.6.3.js"> </script>
<script src="../static/js/datos.js"></script>
<!-- configuración de datos
-->
<script src="../static/js/config.js"></script>
<!-- información del nodo para visualizar en el modal
-->
<script src="../static/js/informacion.js"></script>
<script src="../static/js/estilos.js"></script>
<!-- librerias de estilos -->
<script src="../static/js/resourse/jquery-2.1.3.js"></script>
<LINK rel="stylesheet" href="../static/css/resourse/bootstrap.css">
<script src="../static/js/resourse/bootstrap.js"></script>
<LINK rel="stylesheet" href="../static/css/resourse/bootstrap-popoverx.css">
<script src="../static/js/resourse/bootstrap-popover-x.js"></script>
<script src="../static/js/resourse/bootstrap-modalpopover.js"></script>
63
<link rel="stylesheet" href="../static/css/EstiloGrafi.css">
<script src="../static/js/cierre3.js"></script>
<!-- collapse del facetado global -->
<h4>FACETADO GLOBAL</h4>
<div class="panel-group" id="accordion2" style="width:65%; float:left;
padding-left:30px;">
<div
class="panel panel-default">
<div id="titnodos" class="panel-heading"role="tab" >
<a
class="accordion-toggle" data-toggle="collapse" data-
parent="#accordion2" href="#collapseOne">
TIPOS DE NODOS
</a>
</div>
<div id="collapseOne" class="accordion-body collapse">
<div class="panel-body"
id="mi_div">
</div>
</div>
</div>
<div class="panel panel-default">
<div id="titRelaciones" class="panel-heading"role="tab">
<a class="accordion-toggle" data-toggle="collapse" dataparent="#accordion2" href="#collapseTwo">
64
TIPOS DE RELACIONES
</a>
</div>
<div id="collapseTwo" class="accordion-body collapse">
<div class="panel-body" id="mi_div2">
</div>
</div>
</div>
</div>
<!-- textbox, botón y dropdown para la busqueda inicial de nodo -->
<div class="col-xs-3" >
<div class="input-group" id="empezar">
<input id="Buscador" type="text" class="form-control" aria-label="...">
<div class="input-group-btn ">
<!-- Button and dropdown menu -->
<button class="btn btn-default"
type="button"
id="PrimerNodo">Buscar</button>
<button class="btn btn-default dropdown-toggle" type="button"
data-toggle="dropdown" aria-expanded="false" >
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
65
<li><a href="#" id="provincia"
name="Provincia">Provincia</a></li>
<li><a href="#" id="canton" name="Canton">Cantón</a></li>
<li><a href="#" id="lengua" name="Lengua">Lengua</a></li>
<li class="divider"></li>
<li><a href="#" id="idnodo">ID Nodo</a></li>
</ul>
</div>
</div>
</div>
<script src="../static/js/tiposRelaciones.js"></script>
<script src="../static/js/TiposNodos.js"></script>
<script src="../static/js/Nodos.js"></script>
<script src="../static/js/funciones.js"></script>
<script src="../static/js/numVecinos.js"></script>
<script src="../static/js/PedirVecinos.js"></script>
<script src="../static/js/funcionesBotones.js"></script>
<script src="../static/js/PrimerNodo.js"></script>
<!-- modal que muestra la informacion extendida de los nodos -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" arialabelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
66
<button type="button" class="close" data-dismiss="modal" arialabel="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel"></h4>
</div>
<div id="mi_div6" class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" datadismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="../static/js/vecinosLocal.js"></script>
<script src="../static/js/abrirVecinos.js"></script>
<script src="../static/js/facetadoLocal2.js"></script>
<script src="../static/js/vecinosMenores.js"></script>
<script src="../static/js/tipoRelaLocales.js"></script>
<script src="../static/js/relacionesLocales.js"></script>
<script src="../static/js/cerrarVecinos.js"></script>
</body>
</html>
67
Anexo B. Datos.js
// arreglos en donde se guardaran los nodos y sus relaciones
var nodes = [];
var links = [
];
Estilo.js
var w = 1500,
h = 650;
//Radio de nodos
var circleWidth = 10;
var fontFamily = 'Bree Serif',
fontSizeHighlight = '1.5em',
fontSizeNormal = '1em';
// Gama de colores
var palette = {
"lightgray": "#819090",
"gray": "#708284",
"mediumgray": "#536870",
"darkgray": "#475B62",
"darkblue": "#0A2933",
"darkerblue": "#042029",
"paleryellow": "#FCF4DC",
"paleyellow": "#EAE3CB",
"yellow": "#A57706",
68
"orange": "#BD3613",
"red": "#D11C24",
"pink": "#C61C6F",
"purple": "#595AB7",
"blue": "#2176C7",
"green": "#259286",
"yellowgreen": "#738A05"
}
Anexo C. Config.js
var enlace ="http://localhost:7474/db/data/cypher"
//Máximo de nodos para mostrar
var totalimite=25;
//Nombres de los Nodos de acuerdo al tipo
var etiqueta={};
etiqueta["Alcance"] = "det_alcance_desc";
etiqueta["Ambito"] = "amb_descripcion";
etiqueta["Canton"] = "can_descripcion";
etiqueta["Comunidad"] = "com_descripcion";
etiqueta["Detalle"] = "inmaterial_id";
etiqueta["DetalleSubambito"] = "dsa_descripcion";
etiqueta["Elemento"] = "nombre";
etiqueta["ElementosSig"] = "nombre";
etiqueta["Herramientas"] = "nombre";
etiqueta["Inmaterial"] = "inmaterial_denominacion";
69
etiqueta["Lengua"] = "len_descripcion";
etiqueta["Parroquia"] = "par_descripcion";
etiqueta["Periodicidad"] = "det_periodicidad_desc";
etiqueta["Preparativo"] = "nombre";
etiqueta["Producto"] = "nombre";
etiqueta["Provincia"] = "pro_descripcion";
etiqueta["Sensibilidad"] = "sensibilidad_desc";
etiqueta["Subambito"] = "sua_descripcion";
etiqueta["Tecnica"] = "nombre";
etiqueta["UsoSimbolico"] = "det_uso_simbolico_desc";
//Campos que se muestran en el tooltip de los nodos
var camp_tooltip ={
"Alcance":["det_alcance_desc"],
"Ambito":["amb_descripcion"],
"Canton":["can_descripcion"],
"Comunidad":["com_descripcion"],
"Detalle":["inmaterial_id"],
"DetalleSubambito":["dsa_descripcion"],
"Elemento":["nombre"],
"ElementosSig":["nombre"],
"Herramientas":["nombre"],
"Inmaterial":["inmaterial_denominacion"],
"Lengua":["len_descripcion"],
"Parroquia":["par_descripcion"],
70
"Periodicidad":["det_periodicidad_desc"],
"Preparativo":["nombre"],
"Producto":["nombre"],
"Provincia":["pro_descripcion"],
"Sensibilidad":["sensibilidad_desc"],
"Subambito":["sua_descripcion"],
"Tecnica":["nombre"],
"UsoSimbolico":["det_uso_simbolico_desc"],
}
//Campos que se muestran al abrir toda la informacion
var camp_modal ={
"Alcance":["det_alcance_desc","det_alcance"],
"Ambito":["amb_descripcion","amb_codigo"],
"Canton":["can_descripcion","pro_codigo"],
"Comunidad":["com_descripcion","com_codigo"],
"Detalle":["inmaterial_id","uso_alcance_desc"],
"DetalleSubambito":["dsa_descripcion","dsa_codigo"],
"Elemento":["nombre","inmaterial_id"],
"ElementosSig":["nombre","inmaterial_id"],
"Herramientas":["nombre","inmaterial_id"],
"Inmaterial":["inmaterial_denominacion","inmaterial_id","inmaterial_sen
si_desc","comunidad_nombre","lengua_nombre"],
"Lengua":["len_descripcion","len_codigo"],
"Parroquia":["par_descripcion","pro_codigo","can_codigo","par_codigo"],
"Periodicidad":["det_periodicidad_desc","det_periodicidad"],
71
"Preparativo":["nombre","inmaterial_id"],
"Producto":["nombre","inmaterial_id"],
"Provincia":["pro_descripcion","pro_codigo"],
"Sensibilidad":["sensibilidad_desc","sensibilidad_id"],
"Subambito":["sua_descripcion","sua_codigo"],
"Tecnica":["nombre","inmaterial_id"],
"UsoSimbolico":["det_uso_simbolico_desc","det_uso_simbolico"],
}
Anexo D. Nodos.js
// Se crea y configura la parte visual mediante la libreria D3js los
nodos y relaciones
var guia;
var color = d3.scale.category20();
var vis = d3.select("body")
.append("svg:svg")
.attr("class", "svg-tam");
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.charge(-150)
.linkDistance(50)
.size([w, h]);
72
// Flechas para la direccion de las relaciones
vis.append("svg:defs")
.selectAll("marker")
.data(["end"])
.enter().append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 40)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5 L10,0 L0, -5")
.style("stroke", "#4679BD")
.style("opacity", "0.9");
// .attr("d", "M0,-5L10,0L0,5");
//tooltip en los nodos
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([0, 7])
.html(
function(d){
var titulo=datosNodo.join();
73
//limita la cantidad de caracteres que se muestran de la variable
titulo= titulo.substring(0,10);
//muestra el nombre del nodo en un boton junto con icono de informacion
return "<button type='text'
class='btn btn-primary btn
pull-right' data-toggle='modal' data-target='#myModal' id='leermas'>
<img src='../static/img/Icono_información.png' class='icono'
>"+titulo+"... </button>";
}
)
vis.call(tip);
//tooltip para los nodos guias
var tip2 = d3.tip()
.attr('class', 'd3-tip2')
.offset([-7, 0])
.html(function (d) {
return
d.label;
})
vis.call(tip2);
// se crea el nodo con la informacion que esta en nodes y los agrega al
grupo g
var node = vis.selectAll("circle.node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.style("cursor","pointer")
74
.call(force.drag);
//CIRCLE y sus atributos
node.append("svg:circle")
.attr("r", circleWidth)
.style("cursor","pointer")
.attr("fill", function(d, i) {
return
color(d.label);
// se crea las relaciones con su estilo
var link = vis.append("g").selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("marker-end", "url(#end)");
// se crea nodos guias con sus atributos
function guias(){
guia = vis.selectAll("circle.guia")
.data(tiposNodes)
.enter()
.append("svg:circle")
.attr("r",circleWidth)
.attr("id", function(d,i){return "guia"+d.label})
.attr("fill",function(d,i) {return color(d.label)})
.attr("cx", function(d,i) { return (i*30)+20})
.attr("cy", 30)
.on("mouseover", guiatool)
75
} )
.on("mouseout", tip2.hide)
}
function guiatool(d){
tip2.show(d);
}
force.on("tick", function(e) {
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("transform", function(d, i) {
return "translate(" + d.x + "," + d.y + ")";
});
link.attr("x1", function(d)
{ return d.source.x; })
.attr("y1", function(d)
{ return d.source.y; })
.attr("x2", function(d)
{ return d.target.x; })
.attr("y2", function(d)
{ return d.target.y; })
node.each(collide(0.5));
});
force.start();
var padding = 1, // separation between circles
radius=6;
function collide(alpha) {
var quadtree = d3.geom.quadtree(nodes);
return function(d) {
var rb = 2*radius + padding,
76
nx1 = d.x - rb,
nx2 = d.x + rb,
ny1 = d.y - rb,
ny2 = d.y + rb;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y);
if (l < rb) {
l = (l - rb) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
}); }; }
Anexo E. TiposNodos.js
//Con esta consulta se obtiene todos los tipos de nodos que contiene la
base de datos y se los muestra junto a un checkbox para el facetado
global
var consulta2 =
{
"query" : "START n=node(*) RETURN distinct labels(n)",
77
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta2),
dataType: "json",
contentType: "application/json",
success: function( data ) {
tiposNodes = [];
//Se agrega cada tipo encontrado a un arreglo
for(i=0; i<data.data.length; i++){
t={label:data.data[i][0][0]};
tiposNodes.push(t);
}
for (j = 0; j < tiposNodes.length; j++) {
$( "#mi_div" ).append( "<div
class='seleccionable'> <input
+tiposNodes[j].label+"</div>"
type='checkbox' id="+j+" checked >"
);
}
guias();
},
error: function( xhr ) {
print('error retrieving schema');
78
window.console && console.log( xhr );
},
complete: function(data) {
}
})
Anexo F. TiposRelaciones.js
//Se obtiene todos los tipos de relaciones que contiene la base de
datos y los muestra junto a un checkbox para el facetado global
var consulta3 =
{
"query" : "START r=rel(*) return distinct(type(r))",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta3),
dataType: "json",
contentType: "application/json",
success: function( data ) {
tiposRelaciones = [];
for(i=0; i<data.data.length; i++){
tiposRelaciones.push(data.data[i][0]);
79
}
for (i = 0; i < tiposRelaciones.length; i++) {
$("#mi_div2").append("<div
class='seleccionableR'><input type='checkbox' id="+i+"r
checked>"+tiposRelaciones[i] +"</div>"
}
);
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})
Anexo G. Funciones.js
var tp =0;
var popopen =0;
//Verifica los checkbox de los tipos de nodos en el facetado global que
esten en check
//para agregarlos a la variable tiposN como string y realizar las
consultas
function tipNodos(){
tiposN="";
checkeado =[];
for(m=0; m<tiposNodes.length; m++){
var label = $('#'+m+'').is(":checked");
80
if(label){
checkeado.push(tiposNodes[m].label);
}
}
for(k=0; k<checkeado.length; k++){
if(k==checkeado.length-1){
tiposN = tiposN+" x: "+checkeado[k];
}
else{
tiposN = tiposN+" x: "+checkeado[k]+" or";
}
}
}
//Verifica los checkbox de los tipos de relaciones en el facetado
global que esten en check
//para agregarlos a la variable tiposR como string y realizar las
consultas
function tipRelaciones(){
tiposR="";
checkeadoRel =[];
for(p=0; p<tiposRelaciones.length; p++){
var rela = $('#'+p+'r').is(":checked");
if(rela){
checkeadoRel.push(tiposRelaciones[p]);
}
81
}
for(o=0; o<checkeadoRel.length; o++){
if(o==0){
tiposR = " and type(re)='"+checkeadoRel[o]+"'
or ";
}
if(o != 0 && o != checkeadoRel.length - 1){
tiposR = tiposR+"
type(re)='"+checkeadoRel[o]+"' or";
}
if(o==checkeadoRel.length-1){
tipos= tiposR+"
type(re)='"+checkeadoRel[o]+"'";
}
}
}
// Detecta un click sobre el nodo para la apertura de nodos
var doblclic=false;
function unclick(d){
var temp = this;
setTimeout(function(){
if(doblclic==false){
d3.select(temp).selectAll("circle")
.transition()
.duration(250)
.style("cursor", "pointer")
.attr("r", circleWidth*2);
82
tp++;
//esconde el tooltip
tip.hide(d);
//llama las funciones que verifican el facetado global
tipNodos();
tipRelaciones();
showPopover ();
//llama a la funcion numVecinos para verificar el numero de vecinos que
tiene el nodo
numVecinos(d.sid);
$("#mi_div3").empty();
}
},200);
}
//función doble click cierra los nodos
function dosclick(d){
doblclic=true;
d3.select(this).selectAll("circle")
.transition()
.duration(250)
.style("cursor", "pointer")
cerrar(d.sid);
$("g").popover('hide');
tp = 0;
setTimeout(function(){
83
doblclic=false
},200);
}
// Actualiza la presentacion en pantalla de nodos y relaciones
function actualizaGrafo(){
force.start();
node = node.data(force.nodes(), function(d) { return d.sid; });
node.enter()
.append("g")
.attr("class", "node")
.append("circle")
.attr("r", circleWidth)
.style("cursor", "pointer")
.attr("fill", function(d, i) {
)
.on("mouseover", infoNodos)
.on("mouseout", ocultarInfo)
.on("click", unclick)
.on("dblclick", dosclick)
.call(force.drag);
node.exit().remove();
$("g").popover(
{
'html':'true',
84
return
color(d.label); }
'title':'FACETADO LOCAL',
'content':"<div id='loader1'><img
src='../static/img/loading.gif'></div><select style='display:none'
id='mi_div3' ></select>"+
"<div style='display:none'
id='loader2'><img
src='../static/img/loader.gif'></div></br><select
style='display:none' id='miselec'></select>"+
"<div style='display:none'
id='loader3'><img
src='../static/img/loader.gif'></div><div
style='display:none' id='mi_div5'></div>"+
"</br></br><input style='display:none'
type='button' id='btnSubmitL' value='Vecinos' /></br></br></br>",
'container': 'body',
'placement': 'bottom',
})
link = link.data(force.links(), function(d) { return
d.source.x +"-"+d.target.x; });
link.enter()
.append("line")
.attr("class", "link")
.style("stroke", "#ccc")
.style("stroke-width", function (d) {
return Math.sqrt(d.value);})
.attr("marker-end", "url(#end)");
link.exit().remove();
}
85
var showPopover = function () {
console.log("primer"+tp);
if(tp>1){
$("g").popover('hide');
tp=0;
}
};
$("body").click(function(e){
if(e.target.localName == "svg" ){
$("g").popover('hide');
$("[role='tooltip']").popover('hide');
tp=0;
}});
Anexo H. Información.js
//función infoNodos muestra la información del tooltip
function infoNodos(d){
console.log(d);
$("#mi_div6").empty();
$("#myModalLabel").empty();
//Cuando se tiene mas de un campo que mostrar en el tooltip
for(x=0; x < nodes.length; x++){
if(nodes[x].sid == d.sid){
datosNodo=[];
86
for(t=0; t<camp_tooltip[d.label].length; t++){
$.map(nodes[x], function(value, key) {
if(key==camp_tooltip[d.label][t]){
datosNodo.push(value);
}
});
}}}
//muestra el tooltip
tip.show(d);
tip2.show(d, document.getElementById("guia"+d.label));
//Agrega el nombre del nodo al titulo de la ventana modal
$( "#myModalLabel" ).append( ""+d[etiqueta[d.label]]+""
);
//Verifica los campos que tiene el nodo con los campos definidos
para mostrar en el modal
for(x=0; x < nodes.length; x++){
if(nodes[x].sid == d.sid){
for(w=0; w<camp_modal[d.label].length; w++){
$.map(nodes[x], function(value, key) {
if(key==camp_modal[d.label][w]){
87
$( "#mi_div6" ).append( key+
": ", " "+value+ "</br>"
);
}});
}}}
//Imagen fija para mostrar en modal
$( "#mi_div6" ).append( "<img src='../static/img/GENERAL.jpg' >"
);
}
//se oculta la información del tooltip despues de 2000 milisegundos de
retirar el mouse del nodo
//para que puedan dar click sobre el nombre para abrir toda la
información
function ocultarInfo(d){
setTimeout(function(d){
tip.hide(d);
},2000);
tip2.hide(d);
}
Anexo I. primerNodo.js
// las funciones PrimerNodo y Nodo1 llaman al primer nodo que pide el
usuario mediante la busqueda
function PrimerNodo(nodoini){
var consulta4 =
{
88
"query" : "START n=node("+nodoini+") MATCH n-[re]-x RETURN n,
ID(n),count (x) ",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta4),
dataType: "json",
contentType: "application/json",
success: function( data ) {
primer = data.data[0][0].data;
Id = data.data[0][1];
label=data.data[0][0].metadata.labels[0];
primer["sid"]=Id;
primer["label"]=label;
cuenta = data.data[0][2];
nodes.push(primer);
actualizaGrafo();
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
89
complete: function(data) {
}
})
}
function Nodo1(dato,nodoini){
var consulta11 =
{
"query" : "START n=node(*) where n."+dato+"='"+nodoini+"'
RETURN n, ID(n) ",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta11),
dataType: "json",
contentType: "application/json",
success: function( data ) {
primer = data.data[0][0].data;
Id = data.data[0][1];
label=data.data[0][0].metadata.labels[0];
primer["sid"]=Id;
primer["label"]=label;
cuenta = data.data[0][2];
nodes.push(primer);
90
actualizaGrafo();
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})
}
Anexo J. Numvecinos.js
//Se llama al dar click sobre un nodo para determinar el numero de
vecinos que tiene de acuerdo al facetado local
function numVecinos(sid){
var consulta5 =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x where "+tiposN
+"
RETURN count(x) ",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
91
data: JSON.stringify(consulta5),
dataType: "json",
contentType: "application/json",
success: function( data ) {
numVeci=data.data[0][0];
//Si el numero de nodos vecinos es menor al limite definido se cierra
el modal de facetado local y se abren los nodos vecinos
if(numVeci <= totalimite){
$('#popmodal').modal('hide');
//PedirVecinos
pedirVecinos(sid);
}
//Si el numero de vecinos es mayor se llama al
facetado local
else{
FacetadoLocal(sid);
}
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})
}
92
Anexo K. PedirVecinos.js
//Esta función es llamada para abrir los nodos vecinos cuando el numero
de vecinos es menor al maximo definido
pedirVecinos = function(sid){
var consulta =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x where "+tiposN
+" "+tiposR+" RETURN x, ID(x), startnode(re),ID(startnode(re))",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta),
dataType: "json",
contentType: "application/json",
success: function( data ) {
for(i=0; i<data.data.length; i++){
origenind = -100;
posfin = -100;
insertada=false;
linkinser=false;
b = data.data[i][0].data;
93
id=data.data[i][1];
label=data.data[i][0].metadata.labels[0];
b["sid"]=id;
b["label"]=label;
nodoinicio = data.data[i][2].data;
idre=data.data[i][3];
nodoinicio["sid"]=idre;
abrirVecinos(sid);
}
actualizaGrafo();
$("g").popover('hide');
tp=0;
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}})}
Anexo L. abrirVecinos.js
function abrirVecinos(sid){
//recorre todo el arreglo de nodos que se encuentra almacenado, se
compara el identificador de cada elemento almacenado
94
//con el identificador del elemento que se va almacenar si ya esta en
el arreglo insertada se pone en true y no se agrega
for(j=0; j<nodes.length;j++){
if(nodes[j].sid==b.sid){
insertada=true;
posb=j;
}
}
// si insertada esta en false no esta en el arreglo el nodo y se agrega
if(insertada==false){
posb=nodes.push(b) - 1;
}
// Se verifica el nodo inicio de la relacion para determinar la
dirección de la misma
for(j=0; j<nodes.length;j++)
{
if(nodes[j].sid==sid &&
nodoinicio.sid==nodes[j].sid){
origenind=j;
posfin = posb;
}
if(nodes[j].sid==sid && nodoinicio.sid
!= nodes[j].sid){
origenind=posb;
posfin=j;
}
95
}
//Se verifica que las relaciones no esten en el arreglo para
agregarlas
for(k=0; k<links.length; k++){
if(links[k].source.sid==
nodes[origenind].sid && links[k].target.sid==nodes[posfin].sid)
linkinser=true;
}
if(linkinser==false){
links.push({source:
nodes[origenind], target: nodes[posfin]});
}
Anexo M.
}
Cierre.js
//Agrega al array de eliminado el nodo pulsado
cerrar = function(sid){
borrar = [];
borrarVecinos=[];
borrarLinks=[];
//busco posicion del nodo pulsado
for(l=0; l<nodes.length; l++){
if(nodes[l].sid==sid){
pulsado=l;
}
}
borrarVecinos.push(nodes[pulsado]);
96
cerrarVecinos(sid,true);
actualizaGrafo();
}
Anexo N. Cerrar.js
function cerrarVecinos(sid,actualiza){
//buscamos y agregamos todos los nodos vecinos del nodo pulsado
for( i=0; i<links.length;i++){
if(links[i].target.sid==sid){
borrar.push(links[i].source);
}
if(links[i].source.sid==sid){
borrar.push(links[i].target);
}}
for(j=0; j < borrar.length; j++){
linksVecinos = [];
//buscamos cuantos links tiene cada vecino
for(k=0; k < links.length; k++){
if(links[k].source.sid == borrar[j].sid)
linksVecinos.push(links[k]);
if(links[k].target.sid == borrar[j].sid)
linksVecinos.push(links[k]);
}
97
//si el nodo vecino tiene una sola relación correspondiente al que une
al nodo pulsado se agrega a los arreglos correspondientes el nodo
//y la relación para luego ser eliminados
if(linksVecinos.length == 1){
borrarLinks.push(linksVecinos[0]);
borrarVecinos.push(borrar[j]);
}
// en el caso de tener mas de una relación se busca la que une el
vecino con el nodo pulsado y agrega al arreglo de relaciones para
eliminarse
if(linksVecinos.length > 1 && actualiza){
for( a=0; a<links.length;a++){
if(links[a].target.sid==sid &&
links[a].source.sid == borrar[j].sid){
borrarLinks.push(links[a]);
}
if(links[a].source.sid==sid &&
links[a].target.sid == borrar[j].sid){
borrarLinks.push(links[a]);
}}}}
// Se busca las relaciones que coincidan entre el arreglo que
contiene todas las relaciones y el arreglo que contienen las relaciones
a eliminarse
// y se las elimina
for(f=0; f <links.length; f++){
98
for(p=0; p <borrarLinks.length; p++){
if(borrarLinks[p].source.sid == links[f].source.sid
&& borrarLinks[p].target.sid==links[f].target.sid){
links.splice(f,1);
}
}}
// Se busca en el arreglo de todos los nodos los que coincidan con los
que se encuentran en el arreglo de nodos para eliminar y se los elimina
for(n=0; n < nodes.length; n++){
for(g=0; g < borrarVecinos.length; g++){
if(nodes[n].sid == borrarVecinos[g].sid ){
nodes.splice(n,1);
}}}}
Anexo O. funcionesBotones.js
//Asigno a la variable buscar el input text del buscador inicial de
nodos
buscar= $("#Buscador");
busq=0;
//Cuando se selecciona en el buscador una de las opciones de tipo
de nodo por el cual buscar
$('#idnodo').click(function() {
busq=1;
});
$('#provincia').click(function() {
busq=2;
name=$('#provincia').attr('name');
});
99
$('#canton').click(function() {
busq=3;
name=$('#canton').attr('name');
});
$('#lengua').click(function() {
busq=4;
name=$('#lengua').attr('name');
});
// click en el boton buscar
$('#PrimerNodo').click(function() {
if(busq==0){
alert("Primero elija con el tipo de dato que
desea buscar")
}
// Borramos lo que tenemos en pantalla al realizar nueva busqueda
if(links.length != 0){
links.length=0;
}
if(nodes.length != 0){
nodes.length=0;
}
//Si se elige IDNodo se llama a la función PrimerNodo ingresando el
identificador del nodo
if(busq==1){
nodoini=parseInt(buscar.val());
100
PrimerNodo(nodoini);
}
//Si se elige un tipo de nodo para buscar por su nombre se llama a la
función Nodo1
if(busq != 1 && busq != 0){
//nombre ingresado
nodoini=buscar.val().toUpperCase();
//tipo de nodo
dato=etiqueta[name];
Nodo1(dato,nodoini);
}
});
//tooltip guía para la busqueda inicial
$('#empezar').tooltip({
'html':'true',
'placement': 'bottom',
'title':"<div >Para empezar elija el tipo de dato que va a
ingresar</div>"
});
//tooltip guía para el desplegable de tipo de nodos
$('#titnodos').tooltip({
'html':'true',
'placement': 'bottom',
//cambiar texto
101
'title':"<div >Puede elegir el tipo de nodos que desea ver
durante la navegación</div>"
});
//tooltip guía para los checkbox en el tipo de nodos
$('#collapseOne').tooltip({
'html':'true',
'placement': 'bottom',
//cambiar texto
'title':"<div >Si no desea ver un tipo de nodo lo puede
deseleccionar </div>"
});
//tooltip guía para el desplegable de tipo de relaciones
$('#titRelaciones').tooltip({
'html':'true',
'placement': 'bottom',
//cambiar texto
'title':"<div >Puede elegir el tipo de relaciones que desea
ver durante la navegación</div>"
});
//tooltip guía para los checkbox en el tipo de relaciones
$('#collapseTwo').tooltip({
'html':'true',
'placement': 'bottom',
//cambiar texto
102
'title':"<div >Si no desea ver un tipo de relación lo puede
deseleccionar </div>"
});
Anexo P. facetadoLocal.js
//Esta funcion es llamada para abrir el facetado local cuando el numero
de nodos es mayor a lo establecido
//Obtiene todos los tipos de nodos vecinos y el numero de vecinos que
tiene cada tipo
function FacetadoLocal(sid){
var consulta6 =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x where "+tiposN
+" RETURN
distinct labels(x), count (x)",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta6),
dataType: "json",
contentType: "application/json",
success: function( data ) {
tiposLocal=[];
for(i=0; i<data.data.length;i++){
103
typ={};
typ["tipo"]=data.data[i][0][0];
typ["nume"]=data.data[i][1];
tiposLocal.push(typ);
}
$("#mi_div3").empty();
$("#miselec").empty();
$("#mi_div5").empty();
$("#mi_div3").append("<option
value='vaciop'>...</option>");
//Rellena el select con todos los tipos de vecinos y el numero de nodos
que tiene cada uno
for (j = 0; j < tiposLocal.length; j++) {
$("#mi_div3").append("<option
name='"+tiposLocal[j].nume+"' value='"+tiposLocal[j].tipo+"' >"
+tiposLocal[j].tipo+" ("+tiposLocal[j].nume+" nodos) </option>");
}
$("#mi_div3").show();
$("#loader1").hide();
sidClick=sid;
//Detecta si se elige una opción del select y obtenemos los atributos
$("#mi_div3").change(function() {
$("#loader2").show();
104
if($("#mi_div3 option:selected").val()!= 'vaciop'){
$("#mi_div5").empty();
nombre = $("#mi_div3 option:selected").val();
$("#miselec").empty();
numveci=parseInt($("#mi_div3
option:selected").attr('name'));
//Si el tipo de nodo elegido tiene un numero menor de nodos al máximo
entonces se abren los nodos vecinos del tipo escogido
if(numveci<=totalimite){
VecinosMenor(sidClick);
$("#mi_div3").empty();
}
//Si el número de nodos es mayor entonces
llamamos a tiporelaLocales para obtener el siguiente nivel de filtrado
else{
tiporelaLocales(sidClick);
}}
});
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})
}
105
Anexo Q. VecinosMenore.js
//esta función es llamada despues de la primera seleccion en el
facetado local
//al elegir un tipo de nodo vecino que tenga igual o menos vecinos que
el limite definido.
function VecinosMenor(sid){
var consulta7 =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x
x:"+nombre+"
where
RETURN x, ID(x), startnode(re),ID(startnode(re))",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta7),
dataType: "json",
contentType: "application/json",
success: function( data ) {
for(i=0; i<data.data.length; i++){
origenind = -100;
posfin = -100;
insertada=false;
linkinser=false;
106
b = data.data[i][0].data;
id=data.data[i][1];
label=data.data[i][0].metadata.labels[0];
b["sid"]=id;
b["label"]=label;
nodoinicio = data.data[i][2].data;
idre=data.data[i][3];
nodoinicio["sid"]=idre;
abrirVecinos(sid);
}
actualizaGrafo();
$("g").popover('hide');
tp=0;
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})
}
107
Anexo R. tipoRelaLocales.js
//Esta función es llamada una vez elegido un tipo de nodo vecino que
tenga mas vecinos de los definido como máximo
// La consulta realizada nos devuelve el tipo de relaciones que tienen
los vecinos de acuerdo al tipo escogido
function tiporelaLocales(sid){
var consulta8 =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x-[r]-(b) WHERE
x:"+nombre+" RETURN DISTINCT labels(x), type(r) , labels(b) ",
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta8),
dataType: "json",
contentType: "application/json",
success: function( data ) {
tipox=[];
relacionxb=[];
tipob=[];
for(i=0; i<data.data.length; i++){
108
tx=data.data[i][0][0];
xb=data.data[i][1];
tb=data.data[i][2][0];
tipox.push(tx);
relacionxb.push(xb);
tipob.push(tb);
}
$("#miselec").empty();
//Rellena el select con los tipos de relaciones que tiene el tipo de
nodo
$("#miselec").append("<option value='vacio'>...</option>");
for(c=0; c<relacionxb.length; c++){
$("#miselec").append("<option
value='"+tipob[c]+"'>"+relacionxb[c]+"</option>"
);
}
$("#loader2").hide();
$("#miselec").show();
aplastado=sid;
//Al seleccionar un tipo de relacion me obtiene los atributos y llama a
la función relacionesLocales
//para desplegar los nodos vecinos que tiene el vecino con la relacion
elegida
$("#miselec").change(function() {
$("#loader3").show();
109
if($("#miselec option:selected").val()!= 'vacio'){
$("#mi_div5").empty();
nombreb = $("#miselec option:selected").val();
relacionesLocales(aplastado);
}});
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})}
Anexo S. relacionesLocales.js
//Esta consulta obtiene los distintos nodos vecinos del vecinos que
tengan la relacion elegida y el número de relaciones que tiene
function relacionesLocales(sid){
var consulta9 =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x-[r]-(b) WHERE
x:"+nombre+" and b: "+nombreb+" RETURN DISTINCT count (r),b ",
"params" : {
}
};
$.ajax({
async: true,
110
type: "POST",
url: enlace,
data: JSON.stringify(consulta9),
dataType: "json",
contentType: "application/json",
success: function( data ) {
numrelaciones=[];
nodob=[];
for(i=0; i<data.data.length; i++){
nrel=data.data[i][0];
nb=data.data[i][1].data;
numrelaciones.push(nrel);
nodob.push(nb);
}
numConsultas=0;
totalnumRela=0;
$("#mi_div5").empty();
//Muestra en pantalla todos los distintos nodos con su respectivo
número de relaciones junto con checkbox
for(c=0; c<nodob.length; c++){
$("#mi_div5").append("<div><input type='checkbox'
id="+c+"nrl name='"+nodob[c][etiqueta[nombreb]]+"'
value='"+numrelaciones[c]+"' >"+nodob[c][etiqueta[nombreb]]+" tiene:
"+numrelaciones[c]+" nodos relacionados </div>"
111
);
//Verifica si cada checkbox esta en check o no y los cuenta, de acuerdo
a eso es el numero de consultas que se van a realizar con sus
respectivos datos
$('#'+c+'nrl').click(function(){
contar=$(this);
if(contar.is(":checked")){
numConsultas++;
}
else{
numConsultas--;
}
pulsa=sid;
});
}
$("#loader3").hide();
$("#mi_div5").show();
$('#btnSubmitL').show();
//Al dar click sobre el botón vecinos
$('#btnSubmitL').click(function() {
//Si el nodo pulsado tiene nodos vecinos abiertos los cierra para abrir
los nuevos
borrar = [];
borrarVecinos=[];
borrarLinks=[];
cerrarVecinos(pulsa,false);
112
//divide el limite de nodos que se pueden visualizar para el numero de
consultas que se van a realizar
//para que cada seleccion tenga el mismo numero de nodos vecinos
consulReal=0;
limite=Math.ceil(totalimite/numConsultas);
nombresNodosb=[];
atributoNombre=etiqueta[nombreb];
for(j=0; j < nodob.length; j++){
nombresNodos={};
var localb = $('#'+j+'nrl').is(":checked");
localbthis=$('#'+j+'nrl');
//Si el checkbox esta en check se obtiene el numero de nodos
relacionados
if(localb){numnodos=parseInt(localbthis.attr('value'));
//Si el numero de nodos relacionados es mayor al limite se mostraran
los nodos desde una posicion aleatoria
if(numnodos > totalimite){
rando = Math.floor(Math.random() *
(numnodos));
if(rando > numnodos - totalimite){
skipe=rando-totalimite;
113
}
else{
skipe=rando;
}
if(skipe<0){
skipe=0;
}
}
else{
skipe=0;
}
nombresNodos["nodob"]=localbthis.attr('name');
nombresNodos["numero"]=skipe;
nombresNodosb.push(nombresNodos);
}
}
//de acuerdo al numero de checkbox que se encuentren
en check se realizara el llamado de la funcion VecinosLocales con sus
respectivos datos
for(k=0; k<nombresNodosb.length; k++){
nodoveci=nombresNodosb[k].nodob;
skip=nombresNodosb[k].numero;
VecinosLocales(pulsa)
$("#mi_div3").empty();
114
$("#miselec").empty();
$("#mi_div5").empty();
}
$("g").popover('hide');
tp = 0;
});
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})}
Anexo T. VecinoLocales.js
//Esta funcion se llama por cada checkbox en check y la consulta
devuelve los nodos que cumplan con los datos que se dan en la consulta
function VecinosLocales(sid){
var consulta7 =
{
"query" : "START n=node("+sid+") MATCH n-[re]-x-[r]-(b) where
x:"+nombre+" and b:"+nombreb+" and b."+atributoNombre+"='"+nodoveci+"'
RETURN x, ID(x), startnode(re),ID(startnode(re)) skip "+skip+"
"+limite+"",
115
Limit
"params" : {
}
};
$.ajax({
async: true,
type: "POST",
url: enlace,
data: JSON.stringify(consulta7),
dataType: "json",
contentType: "application/json",
success: function( data ) {
for(i=0; i<data.data.length; i++){
origenind = -100;
posfin = -100;
insertada=false;
linkinser=false;
b = data.data[i][0].data;
id=data.data[i][1];
label=data.data[i][0].metadata.labels[0];
b["sid"]=id;
b["label"]=label;
nodoinicio = data.data[i][2].data;
idre=data.data[i][3];
nodoinicio["sid"]=idre;
abrirVecinos(sid);
116
}
consulReal++;
if(consulReal==numConsultas){
actualizaGrafo();
}
},
error: function( xhr ) {
print('error retrieving schema');
window.console && console.log( xhr );
},
complete: function(data) {
}
})
}
117
Descargar