static private bool CompareRatio(List <TreemapNode> row, TreemapNode next, double w)
        {
            double mn  = float.MaxValue;
            double sum = 0.0f;
            double mx  = 0.0f;

            for (int i = 0, c = row.Count; i != c; ++i)
            {
                TreemapNode n = row[i];
                mx   = Math.Max(mx, n.Size);
                mn   = Math.Min(mn, n.Size);
                sum += n.Size;
            }

            double sumSq = sum * sum;
            double wSq   = w * w;
            double ratio = Math.Max((wSq * mx) / sumSq, sumSq / (wSq * mn));

            double nextMx  = Math.Max(mx, next.Size);
            double nextMn  = Math.Min(mn, next.Size);
            double nextSum = sum + next.Size;

            double nextSumSq = nextSum * nextSum;
            double nextRatio = Math.Max((wSq * nextMx) / nextSumSq, nextSumSq / (wSq * nextMn));

            return(ratio <= nextRatio);
        }
        static private void Squarify(List <TreemapNode> nodes)
        {
            RectD bounds = new RectD(0, 0, 1, 1);
            int   ni     = 0;

            List <TreemapNode> row = new List <TreemapNode>();

            do
            {
                row.Clear();

                double w = Math.Min(bounds.Width, bounds.Height);

                for (int c = nodes.Count; ni != c; ++ni)
                {
                    TreemapNode n = nodes[ni];
                    if (CompareRatio(row, n, w))
                    {
                        break;
                    }
                    row.Add(n);
                }

                RectD remainder;
                LayoutRow(ref bounds, row, out remainder);
                bounds = remainder;
            }while (ni < nodes.Count);
        }
Exemple #3
0
        protected override string FormatTooltip(TreemapNode node)
        {
            RDIElementValue <ProfilerRDI> prdiEv = node.Tag as RDIElementValue <ProfilerRDI>;

            if (prdiEv != null)
            {
                float  val = prdiEv.m_value;
                string vals;
                if (val > 1.0f)
                {
                    vals = string.Format("{0:F1}MB", val);
                }
                else if (val > 1.0f / 1024.0f)
                {
                    vals = string.Format("{0:F0}KB", val * 1024.0f);
                }
                else
                {
                    vals = string.Format("{0:F0}B", val * 1024.0f * 1024.0f);
                }

                return(string.Format("{0}\n{1}", prdiEv.m_rdi.Path, vals));
            }

            return(string.Empty);
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.None)
            {
                if (e.X != m_lastPoint.X || e.Y != m_lastPoint.Y)
                {
                    TreemapNode selectedNode = HitTest(e.Location);

                    if (selectedNode != m_hoverNode)
                    {
                        string tt = string.Empty;

                        m_hoverNode = selectedNode;
                        if (selectedNode != null)
                        {
                            tt = FormatTooltip(selectedNode);
                        }

                        m_tooltip.SetToolTip(this, tt);
                    }
                }

                m_lastPoint = new Point(e.X, e.Y);
            }

            base.OnMouseMove(e);
        }
        private void EnumTree(TreemapNode n, RectD nBounds, double pxX, double pxY, int depth, EnumTreeHandler h)
        {
            if (h(n, nBounds, depth))
            {
                RectD conBounds = new RectD(
                    nBounds.Left + nBounds.Width * 0.01f,
                    nBounds.Top + nBounds.Height * 0.03f,
                    nBounds.Right - nBounds.Width * 0.01f,
                    nBounds.Bottom - nBounds.Height * 0.01f);
                for (int i = 0, c = n.Children.Count; i != c; ++i)
                {
                    TreemapNode cn = n.Children[i];

                    RectD cBounds = new RectD(
                        cn.Bounds.Left * conBounds.Width + conBounds.Left,
                        cn.Bounds.Top * conBounds.Height + conBounds.Top,
                        cn.Bounds.Right * conBounds.Width + conBounds.Left,
                        cn.Bounds.Bottom * conBounds.Height + conBounds.Top);

                    if (cBounds.Width > pxX * 5)
                    {
                        cBounds.Left  += pxX * m_pxNodeMargin;
                        cBounds.Right -= pxX * m_pxNodeMargin;
                    }

                    if (cBounds.Height > pxY * 5)
                    {
                        cBounds.Top    += pxY * m_pxNodeMargin;
                        cBounds.Bottom -= pxY * m_pxNodeMargin;
                    }

                    EnumTree(cn, cBounds, pxX, pxY, depth + 1, h);
                }
            }
        }
        public TreemapNode CreateChild(TreemapNode parent)
        {
            TreemapNode n = new TreemapNode();

            parent.Children.Add(n);
            m_dirty = true;
            return(n);
        }
        static private void LayoutTree(TreemapNode tree)
        {
            Squarify(tree.Children);

            for (int i = 0, c = tree.Children.Count; i != c; ++i)
            {
                LayoutTree(tree.Children[i]);
            }
        }
 public TreemapNode CreateTree()
 {
     m_tree        = new TreemapNode();
     m_tree.Bounds = new RectD(0, 0, 1, 1);
     m_dirty       = true;
     m_selectNode  = null;
     VirtualBounds = m_tree.Bounds;
     return(m_tree);
 }
        protected override void OnLClick(MouseEventArgs e)
        {
            base.OnLClick(e);

            TreemapNode node = HitTest(e.Location);

            m_selectNode = node;
            if (m_selectNode != null)
            {
                OnSelectedNode();
            }
        }
        private void StrokeNode(TreemapNode n, RectD nBounds, RectD vBounds, double pxX, double pxY, int depth)
        {
            if (Overlaps(nBounds, vBounds))
            {
                OpenGL.glColor3f(0, 0, 0);

                {
                    OpenGL.glVertex2f((float)nBounds.Left, (float)nBounds.Top);
                    OpenGL.glVertex2f((float)nBounds.Left, (float)nBounds.Bottom);

                    OpenGL.glVertex2f((float)nBounds.Left, (float)nBounds.Bottom);
                    OpenGL.glVertex2f((float)nBounds.Right, (float)nBounds.Bottom);

                    OpenGL.glVertex2f((float)nBounds.Right, (float)nBounds.Bottom);
                    OpenGL.glVertex2f((float)nBounds.Right, (float)nBounds.Top);

                    OpenGL.glVertex2f((float)nBounds.Right, (float)nBounds.Top);
                    OpenGL.glVertex2f((float)nBounds.Left, (float)nBounds.Top);
                }

                RectD conBounds = new RectD(
                    nBounds.Left + nBounds.Width * 0.01f,
                    nBounds.Top + nBounds.Height * 0.03f,
                    nBounds.Right - nBounds.Width * 0.01f,
                    nBounds.Bottom - nBounds.Height * 0.01f);

                for (int i = 0, c = n.Children.Count; i != c; ++i)
                {
                    TreemapNode cn = n.Children[i];

                    RectD cBounds = new RectD(
                        cn.Bounds.Left * conBounds.Width + conBounds.Left,
                        cn.Bounds.Top * conBounds.Height + conBounds.Top,
                        cn.Bounds.Right * conBounds.Width + conBounds.Left,
                        cn.Bounds.Bottom * conBounds.Height + conBounds.Top);

                    if (cBounds.Width > pxX * 5)
                    {
                        cBounds.Left  += pxX * m_pxNodeMargin;
                        cBounds.Right -= pxX * m_pxNodeMargin;
                    }

                    if (cBounds.Height > pxY * 5)
                    {
                        cBounds.Top    += pxY * m_pxNodeMargin;
                        cBounds.Bottom -= pxY * m_pxNodeMargin;
                    }

                    StrokeNode(cn, cBounds, vBounds, pxX, pxY, depth + 1);
                }
            }
        }
Exemple #11
0
        void m_treemapControl_SelectionChanged(object sender, EventArgs e)
        {
            TreemapNode node = m_treemapControl.SelectedNode;

            if (node != null)
            {
                RDIElementValue <ProfilerRDI> prdiEv = node.Tag as RDIElementValue <ProfilerRDI>;

                if (prdiEv != null)
                {
                    SelectItemInfo(prdiEv.m_rdi);
                }
            }
        }
        static private void LayoutRow(ref RectD bounds, List <TreemapNode> nodes, out RectD remainder)
        {
            double sum = 0.0;

            for (int i = 0, c = nodes.Count; i != c; ++i)
            {
                TreemapNode n = nodes[i];
                sum += n.Size;
            }

            double boundsWidth  = bounds.Width;
            double boundsHeight = bounds.Height;
            double stride       = sum / Math.Min(boundsWidth, boundsHeight);
            bool   horz         = bounds.Width < bounds.Height;

            double x = bounds.Left;
            double y = bounds.Top;

            for (int i = 0, c = nodes.Count; i != c; ++i)
            {
                TreemapNode n = nodes[i];
                double      d = n.Size / stride;

                if (horz)
                {
                    n.Bounds = new RectD(x, y, x + d, y + stride);
                    x       += d;
                }
                else
                {
                    n.Bounds = new RectD(x, y, x + stride, y + d);
                    y       += d;
                }
            }

            if (horz)
            {
                remainder = new RectD(bounds.Left, bounds.Top + stride, bounds.Right, bounds.Bottom);
            }
            else
            {
                remainder = new RectD(bounds.Left + stride, bounds.Top, bounds.Right, bounds.Bottom);
            }
        }
        private TreemapNode HitTest(TreemapNode n, double x, double y)
        {
            if (x >= n.Bounds.Left && x < n.Bounds.Right)
            {
                if (y >= n.Bounds.Top && y < n.Bounds.Bottom)
                {
                    foreach (TreemapNode c in n.Children)
                    {
                        TreemapNode hn = HitTest(c, x, y);
                        if (hn != null)
                        {
                            return(hn);
                        }
                    }

                    return(n);
                }
            }

            return(null);
        }
        public TreemapNode HitTest(Point clientPt)
        {
            double smpX = SampleXFromClientX(clientPt.X);
            double smpY = SampleYFromClientY(clientPt.Y);

            if (m_tree != null)
            {
                TreemapNode hit = null;
                EnumTree(
                    m_tree, new RectD(0, 0, 1, 1), smpX, smpY, 0,
                    (TreemapNode n, RectD nBounds, int depth) =>
                {
                    if (smpX < nBounds.Left)
                    {
                        return(false);
                    }
                    if (smpX >= nBounds.Right)
                    {
                        return(false);
                    }
                    if (smpY < nBounds.Top)
                    {
                        return(false);
                    }
                    if (smpY >= nBounds.Bottom)
                    {
                        return(false);
                    }

                    hit = n;

                    return(true);
                });
                return(hit);
            }

            return(null);
        }
Exemple #15
0
        protected override void glDraw()
        {
            while (true)
            {
                KeyValuePair <Image, GLTexture> req;

                lock (m_thumbnailComplete)
                {
                    if (m_thumbnailComplete.Count == 0)
                    {
                        break;
                    }
                    req = m_thumbnailComplete[0];
                    m_thumbnailComplete.RemoveAt(0);
                }

                if (req.Key != null)
                {
                    req.Value.Update((Bitmap)req.Key);
                    req.Key.Dispose();
                }
            }

            if (m_logViews.Count > 0)
            {
                LogView lv = m_logViews[0];
                LogData ld = lv.m_logData;

                if (m_remakeTree)
                {
                    VirtualBounds = new RectD(0, 0, 1, 1);
                    View          = new RectD(0, 0, 1, 1);

                    TreemapNode rootNode = CreateTree();

                    FrameRecord fr = m_frameRecord;

                    if (fr != null)
                    {
                        lock (ld)
                        {
                            List <RDIElementValue <ProfilerRDI> > children = new List <RDIElementValue <ProfilerRDI> >();

                            float totalSize = 0;

                            foreach (RDIElementValue <ProfilerRDI> prdiEv in m_logControl.m_prdiTree.GetValueEnumerator(fr))
                            {
                                float size = prdiEv.m_value;

                                if (size == 0.0f)
                                {
                                    continue;
                                }

                                children.Add(prdiEv);
                                totalSize += size;
                            }

                            rootNode.Name = String.Format("{0} MB", totalSize);

                            children.Sort((a, b) => - a.m_value.CompareTo(b.m_value));

                            foreach (RDIElementValue <ProfilerRDI> ev in children)
                            {
                                float  size = ev.m_value;
                                string path = ev.m_rdi.Path;
                                int    sep  = path.LastIndexOf('/');

                                GLTexture tex = null;

                                if (path.StartsWith("/TexStrm/"))
                                {
                                    string texturepath = path.Substring("/TexStrm/".Length).Replace(".dds", ".tif");
                                    tex = RequestThumbnail(texturepath, -size);
                                }

                                TreemapNode child = CreateChild(rootNode);
                                child.Size    = size / totalSize;
                                child.Name    = (sep >= 0) ? path.Substring(sep + 1) : path;
                                child.Tag     = ev;
                                child.Texture = tex;
                            }
                        }
                    }

                    VirtualBounds = new RectD(0, 0, 1, 1);
                    View          = new RectD(0, 0, 1, 1);

                    m_remakeTree = false;
                }
            }
            base.glDraw();
        }
 protected virtual string FormatTooltip(TreemapNode node)
 {
     return(node.Name);
 }
        private void FillNode(TreemapNode n, RectD nBounds, RectD vBounds, double pxX, double pxY, int depth)
        {
            if (Overlaps(nBounds, vBounds))
            {
                GLTexture tex = n.Texture;
                if (tex != null && tex.Valid)
                {
                    OpenGL.glEnd();
                    OpenGL.glEnable(OpenGL.GL_TEXTURE_2D);
                    OpenGL.glDisable(OpenGL.GL_BLEND);
                    tex.Bind();

                    OpenGL.glColor3f(1.0f, 1.0f, 1.0f);
                    OpenGL.glBegin(OpenGL.GL_QUADS);
                }
                else
                {
                    RGB col = new RGB(new HSV(depth * (1.0f / 6.0f), 0.5f - depth / 256.0f, 1));
                    OpenGL.glColor3f(col.r, col.g, col.b);
                }

                {
                    OpenGL.glTexCoord2f(0.0f, 0.0f);
                    OpenGL.glVertex2f((float)nBounds.Left, (float)nBounds.Top);

                    OpenGL.glTexCoord2f(0.0f, 1.0f);
                    OpenGL.glVertex2f((float)nBounds.Left, (float)nBounds.Bottom);

                    OpenGL.glTexCoord2f(1.0f, 1.0f);
                    OpenGL.glVertex2f((float)nBounds.Right, (float)nBounds.Bottom);

                    OpenGL.glTexCoord2f(1.0f, 0.0f);
                    OpenGL.glVertex2f((float)nBounds.Right, (float)nBounds.Top);
                }

                if (tex != null && tex.Valid)
                {
                    OpenGL.glEnd();
                    tex.Unbind();
                    OpenGL.glDisable(OpenGL.GL_TEXTURE_2D);
                    OpenGL.glEnable(OpenGL.GL_BLEND);
                    OpenGL.glBegin(OpenGL.GL_QUADS);
                }

                RectD conBounds = new RectD(
                    nBounds.Left + nBounds.Width * 0.01f,
                    nBounds.Top + nBounds.Height * 0.03f,
                    nBounds.Right - nBounds.Width * 0.01f,
                    nBounds.Bottom - nBounds.Height * 0.01f);

                for (int i = 0, c = n.Children.Count; i != c; ++i)
                {
                    TreemapNode cn = n.Children[i];

                    RectD cBounds = new RectD(
                        cn.Bounds.Left * conBounds.Width + conBounds.Left,
                        cn.Bounds.Top * conBounds.Height + conBounds.Top,
                        cn.Bounds.Right * conBounds.Width + conBounds.Left,
                        cn.Bounds.Bottom * conBounds.Height + conBounds.Top);

                    if (cBounds.Width > pxX * 5)
                    {
                        cBounds.Left  += pxX * m_pxNodeMargin;
                        cBounds.Right -= pxX * m_pxNodeMargin;
                    }

                    if (cBounds.Height > pxY * 5)
                    {
                        cBounds.Top    += pxY * m_pxNodeMargin;
                        cBounds.Bottom -= pxY * m_pxNodeMargin;
                    }

                    FillNode(cn, cBounds, vBounds, pxX, pxY, depth + 1);
                }
            }
        }