public virtual void TmiSetSize(UInt32 _size) { if (m_parent != null) { m_parent.TmiSetSize(m_parent.TmiGetSize() - m_size); } m_size = _size; if (m_parent != null) { m_parent.TmiSetSize(m_parent.TmiGetSize() + m_size); } }
//----------------------------------------------------------------------------------------- public void draw(Graphics _graphics, Rectangle R, SpaceGraphItem root) { if (R.IsEmpty) { return; } if (m_options.Grid) { _graphics.FillRectangle(new SolidBrush(CurrentOptions.GridColor), R); } else { _graphics.DrawLine(Pens.DarkGray, new Point(R.Right - 1, R.Top), new Point(R.Right - 1, R.Bottom)); _graphics.DrawLine(Pens.DarkGray, new Point(R.Left, R.Bottom - 1), new Point(R.Right, R.Bottom - 1)); } R.Width--; R.Height--; if (R.IsEmpty) { return; } if (root.TmiGetSize() > 0) { RecurseDrawGraph(_graphics, root, R, true, 0); } else { _graphics.FillRectangle(Brushes.Black, R); } }
//----------------------------------------------------------------------------------------- // return: whether the rows are horizontal. // bool KDirStat_ArrangeChildren(SpaceGraphItem parent, List <double> childWidth, List <double> rows, List <int> childrenPerRow) { if (parent.TmiGetSize() == 0) { rows.Add(1.0); childrenPerRow.Add(parent.TmiGetChildrenCount()); for (int i = 0; i < parent.TmiGetChildrenCount(); i++) { childWidth[i] = 1.0 / parent.TmiGetChildrenCount(); } return(true); } bool horizontalRows = (parent.TmiGetRectangle().Width >= parent.TmiGetRectangle().Height); double width = 1.0; if (horizontalRows) { if (parent.TmiGetRectangle().Height > 0) { width = (double)parent.TmiGetRectangle().Width / parent.TmiGetRectangle().Height; } } else { if (parent.TmiGetRectangle().Width > 0) { width = (double)parent.TmiGetRectangle().Height / parent.TmiGetRectangle().Width; } } int nextChild = 0; while (nextChild < parent.TmiGetChildrenCount()) { int childrenUsed = 0; rows.Add(KDirStat_CalcutateNextRow(parent, nextChild, width, ref childrenUsed, childWidth)); childrenPerRow.Add(childrenUsed); nextChild += childrenUsed; } return(horizontalRows); }
//----------------------------------------------------------------------------------------- double KDirStat_CalcutateNextRow(SpaceGraphItem parent, int nextChild, double width, ref int childrenUsed, List <double> childWidth) { double _minProportion = 0.4; double mySize = (double)parent.TmiGetSize(); UInt32 sizeUsed = 0; double rowHeight = 0; int i; for (i = nextChild; i < parent.TmiGetChildrenCount(); i++) { UInt32 childSize = parent.TmiGetChild(i).TmiGetSize(); if (childSize == 0) { break; } sizeUsed += childSize; double virtualRowHeight = sizeUsed / mySize; // Rectangle(mySize) = width * 1.0 // Rectangle(childSize) = childWidth * virtualRowHeight // Rectangle(childSize) = childSize / mySize * width double childwidth = childSize / mySize * width / virtualRowHeight; if (childwidth / virtualRowHeight < _minProportion) { // For the first child we have: // childWidth / rowHeight // = childSize / mySize * width / rowHeight / rowHeight // = childSize * width / sizeUsed / sizeUsed * mySize // > childSize * mySize / sizeUsed / sizeUsed // > childSize * childSize / childSize / childSize // = 1 > _minProportion. break; } rowHeight = virtualRowHeight; } // Now i-1 is the last child used // and rowHeight is the height of the row. // We add the rest of the children, if their size is 0. while (i < parent.TmiGetChildrenCount() && parent.TmiGetChild(i).TmiGetSize() == 0) { i++; } childrenUsed = i - nextChild; // Now as we know the rowHeight, we compute the widths of our children. if (rowHeight == 0) { for (i = 0; i < childrenUsed; i++) { childWidth[nextChild + i] = 0; } } else { for (i = 0; i < childrenUsed; i++) { // Rectangle(1.0 * 1.0) = mySize double rowSize = mySize * rowHeight; double childSize = (double)parent.TmiGetChild(nextChild + i).TmiGetSize(); double cw = childSize / rowSize; childWidth[nextChild + i] = cw; } } return(rowHeight); }
//========================================================================================= // // Space graph map: // simple arrangment method: No squarification. Children are arranged // alternately horizontally and vertically. // //========================================================================================= //----------------------------------------------------------------------------------------- void Simple_DrawChildren(Graphics _graphics, SpaceGraphItem parent, UInt32 flags) { //throw (new NotImplementedException()); Rectangle rc = parent.TmiGetRectangle(); bool horizontal = (flags == 0); int width = horizontal ? rc.Width : rc.Height; if (width < 0) { return; } double fBegin = horizontal ? rc.Left : rc.Top; int veryEnd = horizontal ? rc.Right : rc.Bottom; int i = 0; for ( ; i < parent.TmiGetChildrenCount(); i++) { double fraction = (double)(parent.TmiGetChild(i).TmiGetSize()) / parent.TmiGetSize(); double fEnd = fBegin + fraction * width; bool lastChild = (i == parent.TmiGetChildrenCount() - 1 || parent.TmiGetChild(i + 1).TmiGetSize() == 0); if (lastChild) { fEnd = veryEnd; } int begin = (int)fBegin; int end = (int)fEnd; Rectangle rcChild = new Rectangle(); if (horizontal) { rcChild.X = begin; rcChild.Width = end - begin; rcChild.Y = rc.Top; rcChild.Height = rc.Height; } else { rcChild.Y = begin; rcChild.Height = end - begin; rcChild.X = rc.Left; rcChild.Width = rc.Width; } RecurseDrawGraph(_graphics, parent.TmiGetChild(i), rcChild, false, (uint)(flags == 0 ? 1 : 0)); if (lastChild) { i++; break; } fBegin = fEnd; } if (i < parent.TmiGetChildrenCount()) { parent.TmiGetChild(i).TmiSetRectangle(Rectangle.FromLTRB(-1, -1, -1, -1)); } }
//----------------------------------------------------------------------------------------- void SequoiaView_DrawChildren(Graphics _graphics, SpaceGraphItem parent, UInt32 flags) { // Rest rectangle to fill Rectangle remaining = parent.TmiGetRectangle(); // Size of rest rectangle UInt32 remainingSize = parent.TmiGetSize(); // Scale factor double sizePerSquarePixel = (double)parent.TmiGetSize() / remaining.Width / remaining.Height; // First child for next row int head = 0; // At least one child left while (head < parent.TmiGetChildrenCount()) { // How we divide the remaining rectangle bool horizontal = (remaining.Width >= remaining.Height); // Height of the new row int height = horizontal ? remaining.Height : remaining.Width; // Square of height in size scale for ratio formula double hh = (height * height) * sizePerSquarePixel; // Row will be made up of child(rowBegin)...child(rowEnd - 1) int rowBegin = head; int rowEnd = head; // Worst ratio so far double worst = double.MaxValue; // Maximum size of children in row UInt32 rmax = parent.TmiGetChild(rowBegin).TmiGetSize(); // Sum of sizes of children in row UInt32 sum = 0; // This condition will hold at least once. while (rowEnd < parent.TmiGetChildrenCount()) { // We check a virtual row made up of child(rowBegin)...child(rowEnd) here. // Minimum size of child in virtual row UInt32 rmin = parent.TmiGetChild(rowEnd).TmiGetSize(); // If sizes of the rest of the children is zero, we add all of them if (rmin == 0) { rowEnd = parent.TmiGetChildrenCount(); break; } // Calculate the worst ratio in virtual row. // Formula taken from the "Squarified Tree maps" paper. // (http://http://www.win.tue.nl/~vanwijk/) double ss = ((double)sum + rmin) * ((double)sum + rmin); double ratio1 = hh * rmax / ss; double ratio2 = ss / hh / rmin; double nextWorst = Math.Max(ratio1, ratio2); // Will the ratio get worse? if (nextWorst > worst) { // Yes. Don't take the virtual row, but the // real row (child(rowBegin)..child(rowEnd - 1)) // made so far. break; } // Here we have decided to add child(rowEnd) to the row. sum += rmin; rowEnd++; worst = nextWorst; } // Row will be made up of child(rowBegin)...child(rowEnd - 1). // sum is the size of the row. // Width of row int width = (horizontal ? remaining.Width : remaining.Height); if (sum < remainingSize) { width = (int)((double)sum / remainingSize * width); } // else: use up the whole width // width may be 0 here. // Build the rectangles of children. Rectangle rc = remaining; double fBegin; if (horizontal) { rc.Width = width; fBegin = remaining.Top; } else { rc.Height = width; fBegin = remaining.Left; } // Now put the children into their places for (int i = rowBegin; i < rowEnd; i++) { int begin = (int)fBegin; double fraction = (double)(parent.TmiGetChild(i).TmiGetSize()) / sum; double fEnd = fBegin + fraction * height; int end = (int)fEnd; bool lastChild = (i == rowEnd - 1 || parent.TmiGetChild(i + 1).TmiGetSize() == 0); if (lastChild) { // Use up the whole height end = (horizontal ? remaining.Top + height : remaining.Left + height); } if (horizontal) { rc.Y = begin; rc.Height = end - begin; } else { rc.X = begin; rc.Width = end - begin; } RecurseDrawGraph(_graphics, parent.TmiGetChild(i), rc, false, 0); if (lastChild) { break; } fBegin = fEnd; } // Put the next row into the rest of the rectangle if (horizontal) { remaining.X += width; remaining.Width -= width; } else { remaining.Y += width; remaining.Height -= width; } remainingSize -= sum; head += (rowEnd - rowBegin); if (remaining.Width <= 0 || remaining.Height <= 0) { if (head < parent.TmiGetChildrenCount()) { parent.TmiGetChild(head).TmiSetRectangle(Rectangle.FromLTRB(-1, -1, -1, -1)); } break; } } }