javascript - samsung - ¿Cómo puedo evitar la superposición en un generador de árbol genealógico?
superposición de pantalla samsung s6 (3)
Como ya está utilizando Family Echo , le sugiero que observe cómo desarrollan su diagrama de árbol familiar en línea, ya que parecen haber resuelto su problema.
Cuando ingreso su diagrama de muestra en Family Echo, puedo construir un árbol de aspecto agradable que parece ser lo que está buscando sin cruzarlo.
Aunque están creando sus diagramas con html y css, puede agregar a las personas a sus diagramas uno por uno y luego inspeccionar dónde se ubican las cajas en términos de las ubicaciones de los píxeles superior e izquierdo de cada elemento.
Si tuviera más experiencia en JavaScript, habría intentado construir un código para replicar algo de lo que Family Echo está haciendo, pero me temo que ese no es mi mojo.
Estoy creando un creador de árbol genealógico interactivo, a diferencia de las versiones más simples que son cuadros / árboles de pedigrí simples.
Los requisitos para la mía (basados en familyecho.com) son:
- compañeros múltiples vs solo un simple padre de 2 a 1 hijo que normalmente ves.
- hermanos múltiples
- Las parejas no necesariamente tienen que tener hijos.
- no siempre tiene que haber un "par" de padres, solo puede haber un solo padre / madre
El problema que estoy encontrando es: estoy generando las compensaciones basadas en el nodo / miembro "actual" de la familia y cuando paso la primera generación con, digamos, 2 padres, se superpone.
Ejemplo de la superposición, así como del compañero que no se dibuja en el mismo eje X:
Aquí está la aplicación real y el archivo principal js donde tengo el problema. Y aquí hay un jsfiddle simplificado que creé que demuestra el problema principal / de compensación, aunque realmente tengo que resolver la superposición de esto en general , además de asegurarnos de que los socios estén dibujados en el mismo eje x que otros socios.
¿Cómo puedo solucionar este problema y posibles conflictos futuros que se superpongan? ¿Necesito algún tipo de función de redibujo que detecte collisions y ajuste las compensaciones de cada bloque al detectar? Estoy tratando de hacerlo sin problemas por lo que hay una cantidad limitada de redibujado hecho.
Un ejemplo de cálculo de la compensación relativa al "contexto" o nodo actual:
var offset = getCurrentNodeOffset();
if ( relationship == RELATIONSHIPS.PARTNER ) {
var t = offset.top; // same level
var l = offset.left + ( blockWidth + 25 );
} else {
var t = offset.top - (blockHeight + 123 ); // higher
var l = offset.left - ( blockWidth - 25 );
}
Tendrá que ajustar todas las ramas del nodo al que afecta, cada rama tendrá que volver a calcular la posición de sus nodos, y cada nodo tendrá que recalcularse localmente para alcanzar las hojas. Usted calculó una vez que las hojas van a tener para recalcular todo el camino a la copia de seguridad, todo eso recursivamente. Es como un árbol real, cuando se agrega físicamente rama a tronco ... las otras ramas se mueven solas para dejar algo de espacio, todas las hojas se restablecen automáticamente, por lo que hay que imaginar. Y simula este proceso en tu diagrama. Los procesos de cada rama llegan a cada hoja y recalculan hasta volver a calcular los vecinos del nodo modificado. (un nivel por encima de usted comenzó) Eso no es tarea fácil o sencilla de hacer.
Voy a dar una respuesta complicada, y eso es porque esta situación es más complicada de lo que parece. Los algoritmos de diseño de gráficos son un campo de investigación activo. Es fácil intentar un algoritmo más simple que el general y luego hacer que falle de manera espectacular cuando se hacen suposiciones injustificadas y generalmente ocultas.
En general, los gráficos de herencia genética no son planos (consulte Gráficos planares en Wikipedia). Aunque es poco común, ciertamente sucede que todas las relaciones ancestrales no están llenas de personas únicas. Esto sucede, por ejemplo, cuando los primos segundos tienen hijos.
Otra situación no planar puede ocurrir en la situación de los niños de padres no monógamos. El ejemplo más simple es dos hombres y dos mujeres, cada pareja con niños (por lo tanto, al menos cuatro). No puede colocar incluso los cuatro pares de padres en una fila sin líneas curvas.
Estos son solo ejemplos. Estoy seguro de que descubrirás más mientras trabajas en tu algoritmo. La verdadera lección aquí es modelar explícitamente la clase de relación que su algoritmo puede diseñar y tener un código de verificación en el algoritmo para detectar cuándo los datos no cumplen con estos requisitos.
Sin embargo, la pregunta que realmente estás haciendo es mucho más básica. Está teniendo dificultades básicas porque necesita usar un recorrido de profundidad de la gráfica. Esta es la versión completa (más fácil) de lo que significa disponer "de arriba abajo" (en uno de los comentarios). Este es solo uno de los muchos algoritmos para atravesar árboles .
Está diseñando un gráfico dirigido con (al menos) noción implícita de rango. El sujeto es rango 0; los padres son rango 1; abuelos en el rango 2. (A propósito de las advertencias anteriores, la clasificación no siempre es única.) La mayor parte del área de estos gráficos se encuentra en la ascendencia. Si no coloca los nodos de la hoja primero, no tiene ninguna esperanza de tener éxito. La idea es que coloque los nodos con el rango más alto primero, incorporando progresivamente los nodos de rango más bajo. El recorrido en profundidad primero es la forma más común de hacer esto.
Yo trataría esto como un algoritmo de reescritura de gráficos. La estructura de datos básica es un híbrido de subgrafos renderizados y el grafo de ascendencia subyacente. Un subgrafo representado es un (1) subárbol de todo el gráfico con (1a) un conjunto de progenie, cuyos antepasados se representan y (2) una colección de datos de representación: posiciones de nodos y líneas, etc. El estado inicial El híbrido es el gráfico completo y no tiene subgrafos renderizados. El estado final es un gráfico completo renderizado. Cada paso del algoritmo convierte un conjunto de elementos en el límite de la hoja del gráfico híbrido en un subgrafo renderizado (más grande), reduciendo la cantidad de elementos en el híbrido. Al final solo hay un elemento, el gráfico de render en su totalidad.