Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

add tree visualizer

  • Loading branch information...
commit cc5ff7a772b29ce5571172f9b32c70e4cb845221 1 parent efa7dc9
Sébastien Bourdeauducq authored August 07, 2013

Showing 1 changed file with 88 additions and 0 deletions. Show diff stats Hide diff stats

  1. 88  migen/graph/treeviz.py
88  migen/graph/treeviz.py
... ...
@@ -0,0 +1,88 @@
  1
+import cairo
  2
+import math
  3
+
  4
+def _cairo_draw_node(ctx, radius, color, outer_color, s):
  5
+	ctx.save()
  6
+
  7
+	ctx.set_line_width(0.0)
  8
+	gradient_color = cairo.RadialGradient(0, 0, 0, 0, 0, radius)
  9
+	gradient_color.add_color_stop_rgb(0, *color)
  10
+	gradient_color.add_color_stop_rgb(1, *outer_color)
  11
+	ctx.set_source(gradient_color)
  12
+	ctx.arc(0, 0, radius, 0, 2*math.pi)
  13
+	ctx.fill()
  14
+
  15
+	ctx.set_source_rgb(0, 0, 0)
  16
+	x_bearing, y_bearing, textw, texth, x_advance, y_advance = ctx.text_extents(s)
  17
+	ctx.translate(-textw/2, texth/2)
  18
+	ctx.show_text(s)
  19
+
  20
+	ctx.restore()
  21
+
  22
+def _cairo_draw_connection(ctx, x0, y0, color0, x1, y1, color1):
  23
+	ctx.move_to(x0, y0)
  24
+	ctx.curve_to(x0, y0+20, x1, y1-20, x1, y1)
  25
+	ctx.set_line_width(1.2)
  26
+	gradient_color = cairo.LinearGradient(x0, y0, x1, y1)
  27
+	gradient_color.add_color_stop_rgb(0, *color0)
  28
+	gradient_color.add_color_stop_rgb(1, *color1)
  29
+	ctx.set_source(gradient_color)
  30
+	ctx.stroke()
  31
+
  32
+class RenderNode:
  33
+	def __init__(self, label, children=None, color=(0.8, 0.8, 0.8), radius=40):
  34
+		self.label = label
  35
+		if children is None:
  36
+			children = []
  37
+		self.children = children
  38
+		self.color = color
  39
+		self.outer_color = (color[0]*3/5, color[1]*3/5, color[2]*3/5)
  40
+		self.radius = radius
  41
+		self.pitch = self.radius*3
  42
+
  43
+	def get_extents(self):
  44
+		if self.children:
  45
+			cw, ch = zip(*[c.get_extents() for c in self.children])
  46
+			w = max(cw)*len(self.children)
  47
+			h = self.pitch + max(ch)
  48
+		else:
  49
+			w = h = self.pitch
  50
+		return w, h
  51
+
  52
+	def render(self, ctx):
  53
+		_cairo_draw_node(ctx, self.radius, self.color, self.outer_color, self.label)
  54
+		if self.children:
  55
+			cpitch = max([c.get_extents()[0] for c in self.children])
  56
+			first_child_x = -(cpitch*(len(self.children) - 1))/2
  57
+
  58
+			ctx.save()
  59
+			ctx.translate(first_child_x, self.pitch)
  60
+			for c in self.children:
  61
+				c.render(ctx)
  62
+				ctx.translate(cpitch, 0)
  63
+			ctx.restore()
  64
+
  65
+			current_x = first_child_x
  66
+			for c in self.children:
  67
+				current_y = self.pitch - c.radius
  68
+				_cairo_draw_connection(ctx, 0, self.radius, self.outer_color, current_x, current_y, c.outer_color)
  69
+				current_x += cpitch
  70
+
  71
+	def to_svg(self, name):
  72
+		w, h = self.get_extents()
  73
+		surface = cairo.SVGSurface(name, w, h)
  74
+		ctx = cairo.Context(surface)
  75
+		ctx.translate(w/2, self.pitch/2)
  76
+		self.render(ctx)
  77
+		surface.finish()
  78
+
  79
+def _test():
  80
+	xns = [RenderNode("X"+str(n)) for n in range(5)]
  81
+	yns = [RenderNode("Y"+str(n), [RenderNode("foo", color=(0.1*n, 0.5+0.2*n, 1.0-0.3*n))]) for n in range(3)]
  82
+	n1 = RenderNode("n1", yns)
  83
+	n2 = RenderNode("n2", xns, color=(0.8, 0.5, 0.9))
  84
+	top = RenderNode("top", [n1, n2])
  85
+	top.to_svg("test.svg")
  86
+
  87
+if __name__ == "__main__":
  88
+	_test()

0 notes on commit cc5ff7a

Please sign in to comment.
Something went wrong with that request. Please try again.