// Follows the idea from Gansner etc 93, creating a special graph // for x-coordinates calculation import {BasicGraphOnEdges} from '../../structs/basicGraphOnEdges' import {LayerArrays} from './LayerArrays' import {PolyIntEdge} from './polyIntEdge' import {ProperLayeredGraph} from './ProperLayeredGraph' export class XLayoutGraph extends BasicGraphOnEdges { layeredGraph: ProperLayeredGraph // the result of layering layerArrays: LayerArrays // the result of layering virtualVerticesStart: number virtualVerticesEnd: number // we have 0,,,virtualVerticesStart-1 - usual vertices // virtualVerticesStart,...,virtualVerticesEnd -virtual vertices // and virtualVirticesEnd+1, ...NumberOfVertices - nvertices weightMultiplierOfOriginalOriginal = 1 // weight multiplier for edges with Defaults or n end and start weightMultOfOneVirtual = 3 // weight multiplier for edges with only one virtual node weightMultiplierOfTwoVirtual = 8 // weight multiplier for edges with two virtual nodes /* internal */ constructor( graph: BasicGraphOnEdges, layeredGraph: ProperLayeredGraph, layerArrays: LayerArrays, edges: PolyIntEdge[], nov: number, ) { super() this.SetEdges(edges, nov) this.virtualVerticesStart = graph.nodeCount this.virtualVerticesEnd = layeredGraph.NodeCount - 1 this.layeredGraph = layeredGraph this.layerArrays = layerArrays } // following Gansner etc 93 returning weight multplier bigger if there are virtual nodes EdgeWeightMultiplier(edge: PolyIntEdge): number { const s: number = edge.source const t: number = edge.target if ( s < this.layeredGraph.NodeCount && this.layerArrays.y[s] === this.layerArrays.y[t] && this.layerArrays.x[s] === this.layerArrays.x[t] + 1 ) { return 0 } // this edge needed only for separation vertices in the same layer let k = 0 /*Assert.assert(s >= this.layeredGraph.NodeCount)*/ // check the graph on correctness` // throw new Error();//"XLayout graph is incorrect"); // here (s0,t0) is the edge of underlying graph let t0 = -1 let s0 = -1 // t0 is set to -1 to only avoid the warning // there are only two edges in graph.OutEdges(s) for (const intEdge of this.outEdges[s]) { if (s0 === -1) { s0 = intEdge.target } else { t0 = intEdge.target } } if (s0 >= this.virtualVerticesStart && s0 <= this.virtualVerticesEnd) { k++ } if (t0 >= this.virtualVerticesStart && t0 <= this.virtualVerticesEnd) { k++ } const ret = k === 0 ? this.weightMultiplierOfOriginalOriginal : k === 1 ? this.weightMultOfOneVirtual : this.weightMultiplierOfTwoVirtual return ret } // caching edges weights SetEdgeWeights() { for (const intEdge of this.edges) { intEdge.weight = intEdge.weight * this.EdgeWeightMultiplier(intEdge) } } }