none
Can you use images as nodes and have text label below an image RRS feed

  • Question

  • i am trying to graph out a network diagram and instead of just text and shapes, i wanted to determine if there was the ability to have images as nodes?
    Tuesday, January 19, 2010 4:59 AM

Answers

  • Hi Lev,

    Cant seem to find the NodesWithImagesSample?

    I got four sample project with my install:
    DrawingfromGeometry
    LayoutEditingSample
    phyloTreeSampleOverGDI
    windowsApplicationSample

    could you post the relevant code for adding custom images as node background/ brush again somewhere

    thanks

    Ralph
    Monday, February 1, 2010 11:19 AM

All replies

  • The sample NodesWithImages.csproj shows how to do it. The sample is included in the distribution.
    Thanks,
    Lev
    Lev Nachmanson
    Tuesday, January 19, 2010 8:59 PM
  • Hi Lev,

    Cant seem to find the NodesWithImagesSample?

    I got four sample project with my install:
    DrawingfromGeometry
    LayoutEditingSample
    phyloTreeSampleOverGDI
    windowsApplicationSample

    could you post the relevant code for adding custom images as node background/ brush again somewhere

    thanks

    Ralph
    Monday, February 1, 2010 11:19 AM
  • using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.Msagl.GraphViewerGdi;
    using Microsoft.Msagl.Drawing;
    using Microsoft.Msagl;
    using CurveFactory = Microsoft.Msagl.Splines.CurveFactory;
    using P2 = Microsoft.Msagl.Point;
    using GeomNode = Microsoft.Msagl.Node;
    using GeomEdge = Microsoft.Msagl.Edge;
    using DrawingEdge = Microsoft.Msagl.Drawing.Edge;
    using DrawingNode = Microsoft.Msagl.Drawing.Node;

    namespace NodesWithImages {
        public partial class Form1 : Form {
            Image creek;
            Image leaves;
            Image tree;
            Image waterfall;
            GViewer viewer = new GViewer();

            public Form1() {
                InitializeComponent();
                creek = Image.FromFile("../../Creek.jpg");
                leaves = Image.FromFile("../../Autumn Leaves.jpg");
                tree = Image.FromFile("../../tree.jpg");
                waterfall = Image.FromFile("../../waterfall.jpg");
                SuspendLayout();
                this.Controls.Add(viewer);
                viewer.Dock = DockStyle.Fill;
                ResumeLayout();
                viewer.LayoutAlgorithmSettingsButtonVisible = false;
                InitGraph();
            }

            bool DrawNode(DrawingNode node, object graphics) {
                Graphics g = (Graphics)graphics;
                Image image;
                if (node.Id == leavesId)
                    image = leaves;
                else if (node.Id == creekId)
                    image = creek;
                else if (node.Id == wId)
                    image = waterfall;
                else
                    image = tree;

                //flip the image around its center
                using (System.Drawing.Drawing2D.Matrix m = g.Transform) {
                    using (System.Drawing.Drawing2D.Matrix saveM = m.Clone()) {
                        float c = (float)node.Attr.GeometryNode.Center.Y;

                        using (System.Drawing.Drawing2D.Matrix m2 = new System.Drawing.Drawing2D.Matrix(1, 0, 0, -1, 0, 2 * c))
                            m.Multiply(m2);

                        g.Transform = m;

                        g.SetClip(FillTheGraphicsPath(node.Attr.GeometryNode.BoundaryCurve));
                       
                        g.DrawImage(image, new PointF((float)(node.Attr.GeometryNode.Center.X - node.Attr.GeometryNode.Width / 2), (float)(node.Attr.GeometryNode.Center.Y - node.Attr.GeometryNode.Height / 2)));
                        g.Transform = saveM;
                    }
                }

                return true;//returning false would enable the default rendering
            }

            static System.Drawing.Drawing2D.GraphicsPath FillTheGraphicsPath(Microsoft.Msagl.Splines.ICurve iCurve) {
                Microsoft.Msagl.Splines.Curve curve = iCurve as Microsoft.Msagl.Splines.Curve;
                System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
                foreach (Microsoft.Msagl.Splines.ICurve seg in curve.Segments)
                    AddSegmentToPath(seg, ref path);
                return path;
            }

            private static void AddSegmentToPath(Microsoft.Msagl.Splines.ICurve seg, ref System.Drawing.Drawing2D.GraphicsPath p) {
                const float radiansToDegrees = (float)(180.0 / Math.PI);                   
                Microsoft.Msagl.Splines.LineSegment line = seg as Microsoft.Msagl.Splines.LineSegment;
                if (line != null)
                    p.AddLine(PointF(line.Start), PointF(line.End));
                else {
                    Microsoft.Msagl.Splines.CubicBezierSegment cb = seg as Microsoft.Msagl.Splines.CubicBezierSegment;
                    if (cb != null)
                        p.AddBezier(PointF(cb.B(0)), PointF(cb.B(1)), PointF(cb.B(2)), PointF(cb.B(3)));
                    else {
                        Microsoft.Msagl.Splines.Ellipse ellipse = seg as Microsoft.Msagl.Splines.Ellipse;
                        if (ellipse != null)
                            p.AddArc((float)(ellipse.Center.X - ellipse.AxisA.Length), (float)(ellipse.Center.Y - ellipse.AxisB.Length),
                                (float)(2 * ellipse.AxisA.Length), (float)(2 * ellipse.AxisB.Length), (float)(ellipse.ParStart * radiansToDegrees),
                                (float)((ellipse.ParEnd - ellipse.ParStart) * radiansToDegrees));

                    }
                }
            }

            static internal PointF PointF(P2 p) { return new PointF((float)p.X, (float)p.Y); }

            float radiusRatio = 0.3f;
           
            string leavesId = "leaves";
            string creekId = "creek";
            string treeId = "tree";
            string wId = "waterfall";

            private void InitGraph() {
                Graph drawingGraph = new Graph();
              
                DrawingEdge lc=drawingGraph.AddEdge(leavesId, creekId);
                DrawingEdge lt=drawingGraph.AddEdge(leavesId, treeId);
                DrawingEdge lw = drawingGraph.AddEdge(leavesId, wId);

                drawingGraph.FindNode(leavesId).Attr.Shape = Shape.DrawFromGeometry;
                drawingGraph.FindNode(creekId).Attr.Shape = Shape.DrawFromGeometry;
                drawingGraph.FindNode(treeId).Attr.Shape = Shape.DrawFromGeometry;
                drawingGraph.FindNode(wId).Attr.Shape = Shape.DrawFromGeometry;

                drawingGraph.FindNode(leavesId).DrawNodeDelegate = new DelegateToOverrideNodeRendering(this.DrawNode);
                drawingGraph.FindNode(creekId).DrawNodeDelegate = new DelegateToOverrideNodeRendering(this.DrawNode);
                drawingGraph.FindNode(treeId).DrawNodeDelegate = new DelegateToOverrideNodeRendering(this.DrawNode);
                drawingGraph.FindNode(wId).DrawNodeDelegate = new DelegateToOverrideNodeRendering(this.DrawNode);

                //create the geom graph
                GeometryGraph geomGraph = new GeometryGraph();
             
                double width = creek.Width;
                double height = creek.Height;

                GeomNode geomCreek = new Microsoft.Msagl.Node(creekId, CurveFactory.CreateBox(width, height, width*radiusRatio, height*radiusRatio, new P2()));
                geomGraph.AddNode(geomCreek);

                width = leaves.Width;
                height = leaves.Height;
                double arrowHeadLenght = width / 10;
                geomGraph.LayerSeparation = height / 2;
                geomGraph.NodeSeparation = width / 2;

                GeomNode geomLeaves = new Microsoft.Msagl.Node(leavesId, CurveFactory.CreateBox(width, height, width* radiusRatio, height* radiusRatio, new P2()));
                geomGraph.AddNode(geomLeaves);

                width = tree.Width;
                height = tree.Height;
                GeomNode geomTree = new Microsoft.Msagl.Node(treeId, CurveFactory.CreateBox(width, height, width* radiusRatio, height *radiusRatio, new P2()));
                geomGraph.AddNode(geomTree);


                width = waterfall.Width;
                height = waterfall.Height;
                GeomNode geomW = new Microsoft.Msagl.Node(wId, CurveFactory.CreateBox(width, height, width * radiusRatio, height * radiusRatio, new P2()));
                geomGraph.AddNode(geomW);

                GeomEdge geomLc = new Microsoft.Msagl.Edge(geomLeaves, geomCreek);
                geomLc.ArrowheadLength = arrowHeadLenght;
                geomGraph.AddEdge(geomLc);
             
                GeomEdge geomLt = new Microsoft.Msagl.Edge(geomLeaves, geomTree);
                geomLt.ArrowheadLength = arrowHeadLenght;
                geomGraph.AddEdge(geomLt);


                GeomEdge geomLw = new Microsoft.Msagl.Edge(geomLeaves, geomW);
                geomLw.ArrowheadLength = arrowHeadLenght;
                geomGraph.AddEdge(geomLw);


                geomGraph.CalculateLayout();

                //bind the geometry graph with the drawing graph
                //nodes first
                foreach (DrawingNode drawingNode in drawingGraph.NodeMap.Values)
                    drawingNode.Attr.GeometryNode = geomGraph.FindNode(drawingNode.Id);

                //bind edges
                lc.Attr.GeometryEdge = geomLc;
                lt.Attr.GeometryEdge = geomLt;
                lw.Attr.GeometryEdge = geomLw;

                //bind graphs
                drawingGraph.GeometryGraph = geomGraph;


                viewer.NeedToCalculateLayout = false;
                viewer.Graph = drawingGraph;
            }
        }
    }


    Lev Nachmanson
    Sunday, June 19, 2011 4:42 PM