demo.coffee 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. ###
  2. demo.coffee a demo of dotgraph.js/coffee
  3. Copyright (C) 2013 Jason Siefken
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. ###
  15. ###
  16. # Code to render a parsed xdot file as an SVG
  17. ###
  18. renderCurrent = ->
  19. window.ast = DotParser.parse(document.querySelector('textarea').value)
  20. console.log ast
  21. window.graph = new DotGraph(ast)
  22. console.log graph
  23. graph.walk()
  24. renderToSvg = (graph) ->
  25. floatList = (l) -> (parseFloat(v) for v in l.split(','))
  26. createElm = (name, attrs={}, parent) ->
  27. elm = document.createElement(name)
  28. for k,v of attrs
  29. elm.setAttribute(k,v)
  30. if parent?
  31. parent.appendChild(elm)
  32. return elm
  33. createElmNS = (name, attrs={}, parent) ->
  34. elm = document.createElementNS("http://www.w3.org/2000/svg", name)
  35. for k,v of attrs
  36. elm.setAttribute(k,v)
  37. if parent?
  38. parent.appendChild(elm)
  39. return elm
  40. window.div = createElm('div', {}, document.body)
  41. window.svg = createElmNS('svg', {width:700, height:500}, div)
  42. window.bb = createElmNS('g', {transform:"translate(0,0)"}, svg)
  43. parser = new DOMParser()
  44. for k,n of graph.nodes
  45. if n.attrs.pos
  46. pos = floatList(n.attrs.pos)
  47. label = n.attrs.label
  48. try
  49. label = label.replace("\\N", k)
  50. catch e
  51. ''
  52. if label.value
  53. try
  54. xml = parser.parseFromString("<root>#{label.value}</root>", "text/xml")
  55. label = (x.textContent for x in xml.querySelectorAll('font')).join('\n')
  56. catch e
  57. console.log label.value
  58. label = ''+label.value
  59. rx = parseFloat(n.attrs.width)*36
  60. ry = parseFloat(n.attrs.height)*36
  61. rect = createElmNS('rect', {id: k, x:pos[0]-rx, y:pos[1]-ry, width:rx*2, height:ry*2, stroke:'black', fill:'none', rx:10}, bb)
  62. g = createElmNS('g',{transform:"translate(#{pos[0]},#{pos[1]})"},bb)
  63. text = createElmNS('text', {x:0, y:0, 'text-anchor':'middle', 'font-family':'sans', 'font-size':12, fill:'red'}, g)
  64. tspan = createElmNS('tspan',{x:0,y:-5}, text)
  65. tspan.textContent = label.split('\n')[0]
  66. tspan = createElmNS('tspan',{x:0,y:12,fill:'blue'},text)
  67. tspan.textContent = ''+(''+label).split('\n')[1]
  68. for k,e of graph.edges
  69. e = e[0]
  70. if e.attrs.pos
  71. points = e.attrs.pos.slice(2).split(' ').map(floatList)
  72. path = "M #{points[1][0]} #{points[1][1]}"
  73. i = 2
  74. while i < points.length
  75. path += " C " + [points[i][0],points[i][1],points[i+1][0],points[i+1][1],points[i+2][0],points[i+2][1]].join(' ')
  76. i+=3
  77. createElmNS('path', {d:path, stroke:'blue', fill:'none'}, bb)
  78. dragging = false
  79. oldx = oldy = 0
  80. offsetx=offsety=0
  81. getCoords = (evt) ->
  82. rect = svg.getBoundingClientRect()
  83. return [evt.pageX-div.offsetLeft, evt.pageY-div.offsetTop]
  84. return [evt.clientX-rect.left, evt.clientY-rect.top]
  85. svg.onmousedown = (evt) ->
  86. [x,y] = getCoords(evt)
  87. oldx=x
  88. oldy=y
  89. dragging = true
  90. svg.onmouseup = (evt) ->
  91. dragging = false
  92. #console.log evt, arguments
  93. svg.onmousemove= (evt) ->
  94. if dragging
  95. [x,y] = getCoords(evt)
  96. diffx = x-oldx
  97. diffy = y-oldy
  98. offsetx += diffx
  99. offsety += diffy
  100. bb.setAttribute('transform', "translate(#{offsetx},#{offsety})")
  101. oldx = x
  102. oldy = y
  103. renderDotGraph = (canvasElm, graph) ->
  104. floatList = (l) -> (parseFloat(v) for v in l.split(','))
  105. ctx = canvasElm.getContext("2d")
  106. ctx.fillStyle = 'white'
  107. ctx.rect(0,0,10000,10000)
  108. ctx.fill()
  109. ctx.fillStyle = 'black'
  110. ctx.strokeStyle = 'red'
  111. for k,g of graph.graphs
  112. if g.attrs.bb
  113. bb = floatList(g.attrs.bb)
  114. ctx.beginPath()
  115. ctx.rect(bb[0],bb[1],bb[2]-bb[0],bb[3]-bb[1])
  116. ctx.stroke()
  117. ctx.textAlign = 'center'
  118. ctx.textBaseline = 'middle'
  119. for k,n of graph.nodes
  120. if n.attrs.pos
  121. pos = floatList(n.attrs.pos)
  122. label = n.attrs.label
  123. try
  124. label = label.replace("\\N", k)
  125. catch e
  126. console.log label
  127. ctx.fillText(label, pos[0], pos[1])
  128. rx = parseFloat(n.attrs.width)*36
  129. ry = parseFloat(n.attrs.height)*36
  130. ctx.beginPath()
  131. ctx.ellipse(pos[0]-rx,pos[1]-ry,rx*2, ry*2)
  132. ctx.stroke()
  133. ctx.strokeStyle = 'blue'
  134. for k,e of graph.edges
  135. e = e[0]
  136. if e.attrs.pos
  137. points = e.attrs.pos.slice(2).split(' ').map(floatList)
  138. ctx.beginPath()
  139. ctx.moveTo(points[1][0], points[1][1])
  140. i = 2
  141. while i < points.length
  142. ctx.bezierCurveTo(points[i][0],points[i][1],points[i+1][0],points[i+1][1],points[i+2][0],points[i+2][1])
  143. i+=3
  144. ctx.stroke()
  145. ctx.beginPath()
  146. canvas_arrow(ctx, points[points.length-1][0],points[points.length-1][1],points[0][0],points[0][1])
  147. ctx.stroke()
  148. window.onload = ->
  149. renderCurrent()
  150. renderToSvg(graph)