I’m using Graphviz to generate nice orgcharts from Rails.
It is easy to install for Rails, and you can find nice how-to examples here.
And the code snippet for Graphviz-like node generation is this (use it in the controller):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | # Orgchart generator def generate_diagram # set current time tnow = Time.now time_now_formatted = tnow.strftime("%Y-%m-%d %H:%M") time_now_raw = tnow.strftime("%Y%m%d%H%M%S") # set graph titles title1 = l(:accordion, :the_organizational_structure_of_the_company) title2 = Department.localized_model_name # set destination directory & file name file_dirname = "files/orgcharts/orgchart-" + title2 # create graph title @r = 'digraph G { label = < <table border="0"> <tr><td align="left" colspan="3"><font point-size="24">Apemin Tusnad S.A</font></td></tr> <tr><td align="left" colspan="3"><font point-size="24">' + title1 + ' - ' + title2 + '</font></td></tr> <tr><td align="left"><font color="#dddddd">' + time_now_formatted + ' / ' + current_user.login + '</font></td><td align="right" colspan="2"><font color="#dddddd">www.clair.ro</font></td></tr> <tr><td colspan="3" cellpadding="10"></td></tr> </table> > labelloc = top center = true margin = 0.5 //rankdir = LR node [shape=box] ' # generate graph nodes @depts = Department.find(:all, :include => [:children]) @iteration = 0 @parent = Array.new @res = @r + get_children(@depts, nil, 0) { |node| node.name} + " }" # write .dot file to disk f = File.new(file_dirname + ".dot", "w+") f.puts @res f.close # run dot command png = IO.popen("/usr/bin/dot -Tpng -o" + file_dirname + ".png","w+") png.puts @res png.close_write # send back the image file name # -- first move under "public" mo = IO.popen("mv " + file_dirname + ".png public/" + file_dirname + ".png") mo.close @result = file_dirname + ".png" end def get_children(tree, parent_id, counter) ret = '' @parent << counter.to_s tree.each do |node| counter = @iteration if counter < @iteration if node.parent_id == parent_id counter += 1 ret += "node" + counter.to_s + ' [label="' + node.name + '"] ' ret += "node" + @parent.last + " -> node" + counter.to_s + " " unless @parent.last == "0" ret += get_children(tree, node.id, counter) { |n| yield n } unless node.children.empty? end end @iteration = counter @parent.delete_at(@parent.length-1) ret += '' end |


