Can you use images as nodes and have text label below an image
-
Tuesday, January 19, 2010 4:59 AMi 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?
All Replies
-
Tuesday, January 19, 2010 8:59 PMOwnerThe sample NodesWithImages.csproj shows how to do it. The sample is included in the distribution.
Thanks,
Lev
Lev Nachmanson -
Monday, February 01, 2010 11:19 AM
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- Marked As Answer by Lev NachmansonOwner Sunday, June 19, 2011 4:42 PM
-
Sunday, June 19, 2011 4:42 PMOwner
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

