Aetheria/Assets/Scripts/NIH/MSAGL/Layout/Layered/LayerArrays.cs
hyperion51 01a956eef6 MSAGL Support
Added new tech tree layout implementation using Microsoft Automatic Graph Layouts
Added some functionality to the database editor tools
2020-04-14 00:42:04 +01:00

174 lines
4.3 KiB
C#

using System;
namespace Microsoft.Msagl.Layout.Layered {
/// <summary>
/// Keeps all information about the hierarchy of layers
/// </summary>
internal class LayerArrays {
internal int[] Y;
int[] verticesToX;
int[][] layers;
internal LayerArrays(int[] verticesToLayers) {
Initialize(verticesToLayers);
}
internal void Initialize(int[] verticesToLayers) {
this.Y = verticesToLayers;
this.verticesToX = null;
this.layers = null;
}
/// <summary>
/// Returns the same arrays but with no empty layers.
/// </summary>
/// <returns></returns>
internal LayerArrays DropEmptyLayers() {
int[] drop = new int[this.Layers.Length];
int dropVal = 0;
for (int i = 0; i < this.Layers.Length; i++) {
drop[i] = dropVal;
if (this.Layers[i].Length == 0)
dropVal++;
}
if (dropVal == 0)
return this;
//we do have empty layers
int[] ny = new int[Y.Length];
for (int i = 0; i < ny.Length; i++)
ny[i] = Y[i] - drop[Y[i]];
//copy the layers itself
int[][] nls = new int[this.layers.Length - dropVal][];
for (int i = 0; i < layers.Length; i++) {
if (layers[i].Length > 0)
nls[i - drop[i]] = (int[])layers[i].Clone();
}
LayerArrays la = new LayerArrays(ny);
la.layers = nls;
return la;
}
internal void UpdateLayers(int[][] ulayers) {
if (layers == null)
InitLayers();
for (int i = 0; i < layers.Length; i++)
ulayers[i].CopyTo(layers[i], 0);
UpdateXFromLayers();
}
internal void UpdateXFromLayers() {
if (layers == null)
InitLayers();
if (verticesToX == null)
verticesToX = new int[Y.Length];
foreach (int[] layer in layers) {
int i = 0;
foreach (int v in layer)
verticesToX[v] = i++;
}
}
/// <summary>
/// gives the order of the vertices in the y-layer
/// </summary>
/// <value></value>
internal int[] X {
get {
if (verticesToX != null)
return verticesToX;
verticesToX = new int[Y.Length];
UpdateXFromLayers();
return verticesToX;
}
}
/// <summary>
/// returns the layer hierarchy where the order of the layers is reversed
/// </summary>
/// <returns></returns>
internal LayerArrays ReversedClone() {
int[] rv = new int[Y.Length];
int lastLayer = Layers.Length - 1; //call Layers to ensure that the layers are calculated
for (int i = 0; i < Y.Length; i++)
rv[i] = lastLayer - Y[i];
return new LayerArrays(rv);
}
/// <summary>
/// Layers[i] is the array of vertices of i-th layer
/// </summary>
internal int[][] Layers {
get {
if (layers != null)
return layers;
InitLayers();
return this.layers;
}
set {
layers = value;
}
}
private void InitLayers() {
//find the number of layers
int nOfLayers = 0;
foreach (int l in this.Y)
if (l + 1 > nOfLayers)
nOfLayers = l + 1;
int[] counts = new int[nOfLayers];
//find the number of vertices in the layer
foreach (int l in Y)
counts[l]++;
layers = new int[nOfLayers][];
for (int i = 0; i < nOfLayers; i++) {
layers[i] = new int[counts[i]];
counts[i] = 0;//we reuse these counts later in the depth search
}
for (int i = 0; i < Y.Length; i++) {
int l = Y[i];
layers[l][counts[l]++] = i;
}
}
}
}