private static int CalcLayout(List <MapItem> items, int start, int end, MapRect bounds) { if (start > end) { return(-1); } if (start == end) { items[start].Bounds = bounds; } int mid = start; while (mid < end) { if (GetHighestAspect(items, start, mid, bounds) > GetHighestAspect(items, start, mid + 1, bounds)) { mid++; } else { MapRect newBounds = LayoutRow(items, start, mid, bounds); int res = CalcLayout(items, mid + 1, end, newBounds); if (res != -1) { mid = res; } } } return(mid); }
public MapItem(double size, int order) { fItems = new List <MapItem>(); fSize = size; fOrder = order; fBounds = new MapRect(0, 0, 0, 0); }
public MapItem(MapItem parent, string name, double size) { fItems = new List <MapItem>(); fName = name; fParent = parent; fSize = size; fBounds = new MapRect(0, 0, 0, 0); fCalcSize = 0; }
private static void CalcRecursiveLayout(List <MapItem> items, MapRect bounds, int headerHeight, int padding = 4) { if (items == null) { return; } int itemsNum = items.Count; if (itemsNum <= 0) { return; } // calculate sum for current level double sum = 0; for (int i = 0; i < itemsNum; i++) { MapItem item = items[i]; sum += item.GetCalcSize(); } // calculate relative sizes for current level double totalArea = bounds.W * bounds.H; for (int i = 0; i < itemsNum; i++) { MapItem item = items[i]; item.Ratio = (totalArea / sum * item.GetCalcSize()); } items.Sort(ItemsCompare); CalcLayout(items, 0, itemsNum - 1, bounds); for (int i = 0; i < itemsNum; i++) { MapItem item = items[i]; int subCount = item.Items.Count; if (subCount > 0) { var clientBounds = item.Bounds; if (subCount > 1) { clientBounds.Inflate(headerHeight, padding); } CalcRecursiveLayout(item.Items, clientBounds, headerHeight, padding); } } }
/// <summary> /// Arrange the items in the given MapModel to fill the given rectangle. /// </summary> /// <param name="bounds">The bounding rectangle for the layout.</param> public void CalcLayout(List <MapItem> items, MapRect bounds, int headerHeight, int padding = 4) { // calculate all true sizes for treemap int num = items.Count; for (int i = 0; i < num; i++) { MapItem item = items[i]; item.CalculateSize(); } // calculate bounds of item for all levels CalcRecursiveLayout(items, bounds, headerHeight, padding); }
private static MapRect LayoutRow(IList <MapItem> items, int start, int end, MapRect bounds) { bool isHorizontal = bounds.W > bounds.H; float total = bounds.W * bounds.H; double rowTotalRatio = 0; for (int i = start; i <= end; i++) { rowTotalRatio += items[i].Ratio; } float rowRatio = (float)(rowTotalRatio / total); float offset = 0; for (int i = start; i <= end; i++) { MapItem item = items[i]; float ratio = (float)(item.Ratio / rowTotalRatio); float rX, rY, rW, rH; if (isHorizontal) { rX = bounds.X; rW = bounds.W * rowRatio; rY = bounds.Y + bounds.H * offset; rH = bounds.H * ratio; } else { rX = bounds.X + bounds.W * offset; rW = bounds.W * ratio; rY = bounds.Y; rH = bounds.H * rowRatio; } item.SetBounds(rX, rY, rW, rH); offset += ratio; } if (isHorizontal) { return(new MapRect(bounds.X + bounds.W * rowRatio, bounds.Y, bounds.W - bounds.W * rowRatio, bounds.H)); } else { return(new MapRect(bounds.X, bounds.Y + bounds.H * rowRatio, bounds.W, bounds.H - bounds.H * rowRatio)); } }
private static float GetHighestAspect(List <MapItem> items, int start, int end, MapRect bounds) { LayoutRow(items, start, end, bounds); float max = float.MinValue; for (int i = start; i <= end; i++) { float aspectRatio = items[i].Bounds.GetAspectRatio(); if (max < aspectRatio) { max = aspectRatio; } } return(max); }
private RectangleF ToRectangle(MapRect rect) { return(new RectangleF(rect.X, rect.Y, rect.W, rect.H)); }