def __init__( self ): self.canvas = svgfig.canvas( style="stroke:black; fill:none; stroke-width:1px; stroke-linejoin:round; text-anchor:left" ) self.text = svgfig.SVG( "g" ) self.connectors = svgfig.SVG( "g" ) self.boxes = svgfig.SVG( "g" ) svgfig.Text.defaults[ "font-size" ] = "10px" self.in_pos = {} self.out_pos = {} self.widths = {} self.max_x = 0 self.max_y = 0 self.max_width = 0 self.data = []
def add_connection( self, step_dict, conn, output_dict): margin = MARGIN in_coords = self.in_pos[ step_dict[ 'id' ] ][ conn ] # out_pos_index will be a step number like 1, 2, 3... out_pos_index = output_dict[ 'id' ] # out_pos_name will be a string like 'o', 'o2', etc. out_pos_name = output_dict[ 'output_name' ] if out_pos_index in self.out_pos: # out_conn_index_dict will be something like: # 7: {'o': (824.5, 618)} out_conn_index_dict = self.out_pos[ out_pos_index ] if out_pos_name in out_conn_index_dict: out_conn_pos = out_conn_index_dict[ out_pos_name ] else: # Take any key / value pair available in out_conn_index_dict. # A problem will result if the dictionary is empty. if out_conn_index_dict.keys(): key = out_conn_index_dict.keys()[0] out_conn_pos = self.out_pos[ out_pos_index ][ key ] adjusted = ( out_conn_pos[ 0 ] + self.widths[ output_dict[ 'id' ] ], out_conn_pos[ 1 ] ) self.text.append( svgfig.SVG( "circle", cx=out_conn_pos[ 0 ] + self.widths[ output_dict[ 'id' ] ] - margin, cy=out_conn_pos[ 1 ] - margin, r=5, fill="#ffffff" ) ) self.connectors.append( svgfig.Line( adjusted[ 0 ], adjusted[ 1 ] - margin, in_coords[ 0 ] - 10, in_coords[ 1 ], arrow_end="true" ).SVG() )
def addDuration(self, origin, duration, color, amplitude=1): freq = 0.8 # angular frequency duration = duration * self.ppux self.g.append( svgfig.SVG("line", stroke=color, stroke_opacity=0.8, stroke_width=1.1, x1=origin["x"], y1=origin["y"], x2=origin["x"] + duration, y2=origin["y"]))
def draw_shapes(self): # really ugly redraw everything self.scene.clear() self.webview = QGraphicsWebView() self.webview.setZoomFactor(3.0) self.scene.setBackgroundBrush(Qt.black) self.scene.addItem(self.webview) w = self.width()*.5 h = self.height()*.5 width = "%spx" % (w) height = "%spx" % (h) dx = (int(self.parent.gl_dx + 1)/2)*2 dy = (int(self.parent.gl_dy + 1)/2)*2 vx = dx dy = dy self.dx = dx self.dy = dy print dx, dy # TODO: clever viewbox calculation viewbox = "%d %d %d %d" % (-self.q*dx/2, -self.q*dy/2, self.q*dx, self.q*dy) rect = svgfig.Rect(-dx/2,-dy/2,dx/2,dy/2, fill='black', stroke=None).SVG(trans=self.trans) dot_field = self.draw_dot_field() print self.box.contentsRect() print width, height, viewbox svg_g = svgfig.SVG("g") svg_g.append(rect) for x in dot_field: svg_g.append(x) for shape in self.shapes: self.set_color(shape['type']) if 'shape' in shape: dispatch = { 'circle': self.circle, 'disc': self.disc, 'label': self.label, 'line': self.vertex, 'vertex': self.vertex, 'octagon': self.octagon, 'rect': self.rect, 'polygon': self.polygon, 'hole': self.hole, } shape_svg = dispatch.get(shape['shape'], self.skip)(shape) print shape_svg for x in shape_svg: svg_g.append(x) #print subs canvas = svgfig.canvas(svg_g, width=width, height=height, viewBox=viewbox) xml = canvas.standalone_xml() print xml self.webview.setContent(QtCore.QByteArray(xml))
def _ellipse(self, x, y, rx, ry, brush, w=0.05): stroke_width=None stroke=None fill=self.color if not brush: stroke = self.color stroke_width = w*self.q fill=None if rx-ry < 0.0001: (cx, cy) = self.trans(x,y) return [svgfig.SVG("circle",cx=cx,cy=cy,r=rx*self.q, stroke=stroke,stroke_width=stroke_width,fill=fill)] else: return [svgfig.Ellipse(x,y,rx,0,ry,stroke=stroke,stroke_width=stroke_width,fill=fill).SVG(trans=self.trans)]
def __init__(self, inputFile, orderFile=""): self.links = [] self.max_time = 0 self.nodeID = idGenerator() self.max_label_len = 0 self.g = svgfig.SVG("g") self.ppux = 10 # piwel per unit time if "json" in inputFile: with open(inputFile, 'r') as inFile: json_struct = json.loads(inFile.read()) for link_json in json_struct: link = Link.from_dict(link_json) self.addNode(link.u) self.addNode(link.v) if (link.t + link.duration) > self.max_time: self.max_time = link.t + link.duration self.links.append(link) else: with open(inputFile, 'r') as inFile: for line in inFile: contents = line.split(" ") t = float(contents[0]) u = int(contents[1]) v = int(contents[2]) d = 0 if len(contents) > 3: d = float(contents[3]) self.addNode(u) self.addNode(v) if t > self.max_time: self.max_time = t self.links.append(Link(t, u, v, duration=d)) if orderFile != "": tmp_nodes = set() with open(orderFile, 'r') as order: for i, n in enumerate(order): node = int(n) tmp_nodes.add(node) if self.nodeID.contains(node): self.nodeID.impose(node, i) self.nodes.append(node) else: print('The node', node, "is not present in the stream") exit() for node in self.nodeID.lookUp: if node not in tmp_nodes: print('The node', node, "is not present in", orderFile) exit()
def draw(self, outputFile): self.findOrder() offset = 1.5 * self.ppux # Define dimensions label_margin = 5 * self.max_label_len origleft = label_margin + 1 * self.ppux right_margin = self.ppux width = origleft + self.ppux * math.ceil(self.max_time) + right_margin svgfig._canvas_defaults["width"] = str(width) + 'px' arrow_of_time_height = 5 height = 5 + 10 * int(self.nodeID.size() + 1) + arrow_of_time_height svgfig._canvas_defaults["height"] = str(height) + 'px' origtop = 10 ################ # Draw background lines for node in self.nodeID.lookUp: horizonta_axe = self.ppux * self.nodeID.get(node) + origtop self.g.append( svgfig.SVG("text", str(node), x=str(label_margin), y=horizonta_axe + 2, fill="black", stroke_width=0, text_anchor="end", font_size="6")) self.g.append( svgfig.SVG("line", stroke_dasharray="2,2", stroke_width=0.5, x1=str(origleft - 5), y1=horizonta_axe, x2=width - right_margin, y2=horizonta_axe)) # Add timearrow self.g.append( svgfig.SVG("line", stroke_width=0.5, x1=self.ppux, y1=10 * (self.nodeID.size() + 1), x2=width - 5, y2=10 * (self.nodeID.size() + 1))) self.g.append( svgfig.SVG("line", stroke_width=0.5, x1=width - 8, y1=10 * (self.nodeID.size() + 1) - 3, x2=width - 5, y2=10 * (self.nodeID.size() + 1))) self.g.append( svgfig.SVG("line", stroke_width=0.5, x1=width - 8, y1=10 * (self.nodeID.size() + 1) + 3, x2=width - 5, y2=10 * (self.nodeID.size() + 1))) self.g.append( svgfig.SVG("text", str("Time"), x=width - 19, y=10 * (self.nodeID.size() + 1) - 3, fill="black", stroke_width=0, font_size="6")) # # Add time ticks for i in range(0, int(math.ceil(self.max_time) + 1), 5): x_tick = i * self.ppux + origleft self.g.append( svgfig.SVG("line", stroke_width=0.5, x1=str(x_tick), y1=10 * (self.nodeID.size() + 1) - 3, x2=str(x_tick), y2=10 * (self.nodeID.size() + 1) + 3)) self.g.append( svgfig.SVG("text", str(i), x=str(x_tick), y=10 * (self.nodeID.size() + 1) + 7, fill="black", stroke_width=0, font_size="6")) for link in self.links: ts = link.t node_1 = min(self.nodeID.get(link.u), self.nodeID.get(link.v)) node_2 = max(self.nodeID.get(link.u), self.nodeID.get(link.v)) offset = ts * self.ppux + origleft y_node1 = 10 * node_1 + origtop y_node2 = 10 * node_2 + origtop # Add nodes self.g.append( svgfig.SVG("circle", cx=offset, cy=y_node1, r=1, fill=link.color)) self.g.append( svgfig.SVG("circle", cx=offset, cy=y_node2, r=1, fill=link.color)) x = 0.2 * ( (10 * node_2 - 10 * node_1) / math.tan(math.pi / 3)) + offset y = (y_node1 + y_node2) / 2 param_d = "M" + str(offset) + "," + str(y_node1) +\ " C" + str(x) + "," + str(y) + " " + str(x) + "," + str(y) +\ " " + str(offset) + "," + str(y_node2) self.g.append(svgfig.SVG("path", stroke=link.color, d=param_d)) self.addDuration({ "x": x, "y": (y_node1 + y_node2) / 2 }, link.duration, link.duration_color) # Save to svg file viewBoxparam = "0 0 " + str(width) + " " + str(height) svgfig.canvas(self.g, viewBox=viewBoxparam).save(outputFile)
def draw(self, filename, graphshape=None, width=1280, height=720, show_labels=False): """This does the drawing. It starts by getting a function for the bottom most layer. As descrbed in Byron & Wattenberg this will control the overall shape of the graph. It then it prints a stacked graph on top of that bottom line, whatever shape it is. """ # Preprocess some stuff aspect_ratio = float(width) / float(height) self.canvas_aspect = aspect_ratio x_offset = int(-((100 * aspect_ratio) - 100) / 2.0) # Get a g_0 depending in desired shape g_0 = self.themeRiver() # Default (fallbacks) y_offset = 0 if str(graphshape) == "Stacked_Graph": g_0 = self.stackedGraph() y_offset = 0 if str(graphshape) == "Theme_River": g_0 = self.themeRiver() y_offset = -50 if str(graphshape) == "Wiggle": g_0 = self.wiggle() y_offset = -50 if str(graphshape) == "Weighted_Wiggle": g_0 = self.weighted_wiggle() y_offset = -50 # Initilize a streamgraph groups in SVG. graph = svgfig.SVG("g", id="StreamGraph") labels = svgfig.SVG("g", id="Labels") # Initilize a SVG Window object to do the transormations on each object window = svgfig.window(self.x_min, self.x_max, 0, self.y_max * 1.3, x_offset, y_offset, int(100 * aspect_ratio), 100) # Loop through each layer for layer in range(self.n_layers): points = [] point_range = range(self.n_points) # Forwards; draw top of the shape for i in point_range: x = self.data[layer][i][0] y = self.data[layer][i][1] # Start with g_0 and stack y_stacked = g_0[i] + y # Stack! for l in range(layer): y_stacked += self.data[l][i][1] # Add the points to the shape points.append((x, y_stacked)) # Backwards; draw bottom of the shape #point_range.reverse() point_range = reversed(point_range) for i in point_range: x = self.data[layer][i][0] # This time we don't include this layer y_stacked = g_0[i] # Stack! for l in range(layer): y_stacked += self.data[l][i][1] points.append((x, y_stacked)) # Shapes poly = svgfig.Poly(points, "smooth", stroke="#eeeeee", fill=self.rgb2hex(self.colors[layer]), stroke_width="0.05") graph.append(poly.SVG(window)) if show_labels: #label = self.placeLabel(points, layer) #label = self.test_placeLabel(points, layer) #label = self.test2_placeLabel(points, layer, window) label = self.placeLabel2(points, layer) #for l in label: # labels.append(l) labels.append(label.SVG(window)) # End Loop # Add objects to the canvas and save it w = str(int(width)) + "px" h = str(int(height)) + "px" canv = svgfig.canvas(graph, labels, width=w, height=h) canv.save(filename)
def placeLabel2(self, points, layer): def interp(a, b, val): slope = float(b[1] - a[1]) / float(b[0] - a[0]) inter = a[1] - slope * a[0] return (val * slope) + inter def f_bl(x): point_range = range(len(points)) #point_range.reverse() point_range = list(reversed(point_range)) last_x = 0 #for i in range(len(points) / 2): for i in range(int(len(points) / 2)): point = points[point_range[i]] #print str(point[0]) + " " +str(x) + " " + str(last_x) if x <= point[0] and x > last_x: #print "Bang!" return interp(point, points[point_range[i - 1]], x) last_x = point[0] return 0 def f_tl(x): last_x = 0 for i in range(int(len(points) / 2)): point = points[i] if x <= point[0] and x > last_x: return interp(point, points[i - 1], x) last_x = point[0] return 0 def is_box_in_shape(x1, y1, x2, y2): width = x2 - x1 for j in range(resolution): x = x1 + ((width / float(resolution)) * j) y_lo = f_bl(x) y_hi = f_tl(x) if y1 < y_lo or y2 > y_hi: return False return True # Get the label label = self.labels[layer] # Take a guess at the aspect ratio of the word label_aspect = len(label) * 0.7 #magic window_aspect = (self.x_max - self.x_min) / float(self.y_max * 1.3) total_aspect = (((1 / label_aspect) / window_aspect) * self.canvas_aspect) # How slow vs. how good num_guesses = 500 resolution = 15 height_max = 0 boxes = svgfig.SVG("g", id="boxes") x1_l = 0 x2_l = 0 y1_l = 0 y2_l = 0 for i in range(num_guesses): x1 = random.uniform(self.x_min, self.x_max) y_lo = f_bl(x1) y_hi = f_tl(x1) h = y_hi - y_lo y1 = random.uniform(y_lo, y_hi - (h / 8.0)) y2 = random.uniform(y1, y_hi) height = y2 - y1 x2 = x1 + height / float(total_aspect) if is_box_in_shape(x1, y1, x2, y2): if height_max < height: height_max = height x1_l = x1 y1_l = y1 x2_l = x2 y2_l = y2 label_x = x1_l + ((x2_l - x1_l) / 2.0) label_y = y1_l + ((y2_l - y1_l) / 6.5) font_scale = self.y_max / 100.0 font = ((y2_l - y1_l) / font_scale) * 0.9 #magic label = svgfig.Text(label_x, label_y, label, font_family="Droid Sans", font_size=str(font), fill="#e7e7e7") return label
def draw_boxes(xchrs, ychrs, xend, yend, linewidth, xheader='Chr', yheader='Chr'): origin = [0, 0] xstart = origin[0] ystart = origin[1] lines = svgfig.SVG('g') names = svgfig.SVG('g') xmiddle = chr_middle(xchrs, xend) ymiddle = chr_middle(ychrs, yend) stroke_def = "stroke-width:%ipx;stroke:#000000" % (linewidth) for achr in xchrs: xcoord = xchrs[achr] - (linewidth / float(2)) aline = svgfig.SVG('line', x1=xcoord, x2=xcoord, y1=ystart, y2=(yend + linewidth), style=stroke_def) lines.append(aline) aname = svgfig.SVG('text', (xheader + achr), x=xmiddle[achr], y=(ystart + 12), style='text-anchor:middle;text-align:center') names.append(aname) aline = svgfig.SVG('line', x1=(xend + (linewidth / float(2))), x2=(xend + (linewidth / float(2))), y1=ystart, y2=(yend + linewidth), style=stroke_def) lines.append(aline) for achr in ychrs: ycoord = ychrs[achr] - (linewidth / float(2)) aline = svgfig.SVG('line', x1=xstart, x2=xend + linewidth, y1=ycoord, y2=ycoord, style=stroke_def) lines.append(aline) aname = svgfig.SVG('text', yheader + achr, x=(xstart + 12), y=ymiddle[achr], style='text-anchor:middle;text-align:center', transform="rotate(270,%i,%i)" % (xstart + 12, ymiddle[achr])) names.append(aname) aline = svgfig.SVG('line', x1=xstart, x2=xend + linewidth, y1=(yend + (linewidth / float(2))), y2=(yend + (linewidth / float(2))), style=stroke_def) lines.append(aline) results = svgfig.SVG('svg') results.append(lines) results.append(names) return results
def draw_kakuro_svg(): import svgfig x_size = 8 y_size = 9 puzzle = (0, 0, 0, 0, 0, 0, (0, 16), (0, 3), 0, 0, 0, 0, 0, (8, 6), 1, 1, 0, (0, 16), (0, 6), 0, (14, 30), 1, 1, 1, (11, 0), 1, 1, (7, 0), 1, 1, (0, 6), 0, (10, 0), 1, 1, (13, 7), 1, 1, 1, (0, 16), 0, (14, 0), 1, 1, 1, (8, 0), 1, 1, 0, (0, 4), (9, 17), 1, 1, (11, 0), 1, 1, (12, 0), 1, 1, 1, 0, 0, 0, 0, (10, 0), 1, 1, 0, 0, 0, 0, 0) cells = [] CELL_WIDTH = 20 CELL_HEIGHT = 20 def draw_cell(cell_data): out = [] if cell_data == 0: out.append(svgfig.Rect(0, 0, CELL_WIDTH, CELL_HEIGHT, fill="black")) elif type(cell_data) == type(1): out.append(svgfig.Rect(0, 0, CELL_WIDTH, CELL_HEIGHT)) out.append( svgfig.Text( 10, 10, cell_data, text_anchor="middle", font_size=12, font_weight=600, dominant_baseline="middle", fill="brown", )) elif type(cell_data) == type(()): across = cell_data[0] down = cell_data[1] out.append(svgfig.Rect(0, 0, CELL_WIDTH, CELL_HEIGHT)) out.append( svgfig.Line( 0, 0, CELL_WIDTH, CELL_HEIGHT, stroke_width=1, )) if down == 0: points = ((0, 0), (0, CELL_HEIGHT), (CELL_WIDTH, CELL_HEIGHT)) out.append(svgfig.Poly(points, "lines", fill="black")) else: out.append( svgfig.Text( 2, 18, down, text_anchor="start", font_size=7, alignment_baseline="middle", )) if across == 0: points = ((0, 0), (CELL_WIDTH, 0), (CELL_WIDTH, CELL_HEIGHT)) out.append(svgfig.Poly(points, "lines", fill="black")) else: out.append( svgfig.Text( 19, 7, across, text_anchor="end", font_size=7, )) else: raise Exception("") return out def cell(x, y, cell_data): def t(xi, yi): return 1 + xi + x * (CELL_WIDTH), 1 + yi + y * (CELL_HEIGHT) fig = svgfig.Fig(*draw_cell(cell_data), trans=t) return fig.SVG() for y in range(y_size): for x in range(x_size): cells.append(cell(x, y, puzzle[y * x_size + x])) g = svgfig.SVG("g", *cells) c = svgfig.canvas(g, width="400px", height="400px", font_family='Arial Black', viewBox="0 0 %d %d" % (x_size * CELL_WIDTH + 2, y_size * CELL_HEIGHT + 2)) c.save('tmp.svg')
def main(opts, args): s = svg.SVG('g', id='viewport') # display legend for i, b in enumerate(bases): bt = svg.SVG("tspan", b, style="font-family:Verdana;font-size:20%") s.append( svg.SVG("text", bt, x=12 + (i * 10), y=3, stroke="none", fill="black")) s.append( svg.SVG("rect", x=14 + (i * 10), y=0, width=4, height=3, stroke="none", fill=colors[b], fill_opacity=0.5)) reader = open(opts.input_file, 'U') samples = [] for i in range(int(len(args) / 3)): index = i * 3 samples.append( dict(name=args[index], a_col=args[index + 1], totals_col=args[index + 2])) if opts.zoom == 'interactive': y = 35 else: y = 25 for i, sample in enumerate(samples): x = 23 + (i * (WIDTH + GAP)) t = svg.SVG("text", svg.SVG("tspan", sample['name'], style="font-family:Verdana;font-size:25%"), x=x, y=y, transform="rotate(-90 %i,%i)" % (x, y), stroke="none", fill="black") s.append(t) count = 1 for line in reader: row = line.split('\t') highlighted_position = False show_pos = True position = row[int(opts.position_col) - 1] ref = row[int(opts.ref_col) - 1].strip().upper() # validate if ref not in bases: stop_error( "The reference column (col%s) contains invalid character '%s' at row %i of the dataset." % (opts.ref_col, ref, count)) # display positions if opts.zoom == 'interactive': textx = 0 else: textx = 7 bt = svg.SVG("tspan", str(position), style="font-family:Verdana;font-size:25%") s.append( svg.SVG("text", bt, x=textx, y=34 + (count * (HEIGHT + GAP)), stroke="none", fill="black")) s.append( svg.SVG("rect", x=0, y=30 + (count * (HEIGHT + GAP)), width=14, height=HEIGHT, stroke='none', fill=colors[ref.upper()], fill_opacity=0.2)) for sample_index, sample in enumerate(samples): n_a = int(row[int(sample['a_col']) - 1]) n_c = int(row[int(sample['a_col']) + 1 - 1]) n_g = int(row[int(sample['a_col']) + 2 - 1]) n_t = int(row[int(sample['a_col']) + 3 - 1]) total = int(row[int(sample['totals_col']) - 1]) # validate base_error = validate_bases(n_a, n_c, n_g, n_t, total) if base_error: stop_error( "For sample %i (%s), the number of base %s reads is more than the coverage on row %i." % (sample_index + 1, sample['name'], base_error, count)) if total: x = 16 + (sample_index * (WIDTH + GAP)) y = 30 + (count * (HEIGHT + GAP)) width = WIDTH height = HEIGHT if count % 2: s.append( svg.SVG("rect", x=x, y=y, width=width, height=height, stroke='none', fill='grey', fill_opacity=0.25)) else: s.append( svg.SVG("rect", x=x, y=y, width=width, height=height, stroke='none', fill='grey', fill_opacity=0.25)) for base, value in enumerate([n_a, n_c, n_g, n_t]): width = int(math.ceil(value / total * WIDTH)) s.append( svg.SVG("rect", x=x, y=y, width=width, height=BAR_WIDTH, stroke='none', fill=colors[bases[base]], fill_opacity=0.6)) y = y + BAR_WIDTH count = count + 1 if opts.zoom == 'interactive': canv = svg.canvas(s) canv.save(opts.output_file) import fileinput flag = False for line in fileinput.input(opts.output_file, inplace=1): if line.startswith('<svg'): print '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">' flag = True continue else: if flag: print '<script type="text/javascript">%s</script>' % SVGPan flag = False print line, else: zoom = int(opts.zoom) w = "%ipx" % (x * (10 + zoom)) h = "%ipx" % (y * (2 + zoom)) canv = svg.canvas(s, width=w, height=h, viewBox="0 0 %i %i" % (x + 100, y + 100)) canv.save(opts.output_file)
import sys import pdb import svgfig import json import math argv = {} argv["json"] = 0 argv["max-time"] = 0 argv["max-nodes"] = 0 argv["silent"] = False g = svgfig.SVG("g") nodes = set() nodes_index = {} offset = 15 groups = {} # BEGIN FUNCTIONS def ask_args(): sys.stderr.write(" Input number of nodes[" + str(argv["max-nodes"]) + "]:\n") user_maxnodes = raw_input() if user_maxnodes != '': argv["max-nodes"] = int(user_maxnodes) sys.stderr.write(" Input maximum time [" + str(argv["max-time"]) + "]:\n") user_maxtime = raw_input() if user_maxtime != '': argv["max-time"] = int(user_maxtime)
def draw_dots(fname, xgenes, ygenes, xchrs, ychrs, noks=False): dots = svgfig.SVG('g') file_dict = {} if noks: offset = 2 else: offset = 0 with open(fname) as fh: for line in fh: if line.startswith('#'): continue if noks: myks = 200 else: columns = line.split() myks = columns[0] if myks == 'undef': myks = 200 if myks == 'NA': myks = 200 file_dict[line] = float(myks) file_list = list(file_dict) file_list.sort(key=lambda x: file_dict[x]) file_list.reverse() for line in file_list: columns = line.split() xgene = parse_dag_line(columns[3 - offset]) ygene = parse_dag_line(columns[7 - offset]) if not xgene['name'] in xgenes: if xgene['name'] in ygenes: xgene, ygene = ygene, xgene if not xgene['name'] in xgenes: continue if not xgene['chr'] in xchrs: continue if not ygene['name'] in ygenes: continue if not ygene['chr'] in ychrs: continue if noks: mycolor = 'green' else: ks = columns[0] mycolor = define_colors(ks) xcoord = xchrs[xgene['chr']] + xgenes[xgene['name']] ycoord = ychrs[ygene['chr']] + ygenes[ygene['name']] adot = svgfig.SVG('circle', cx=xcoord, cy=ycoord, r=1, fill=mycolor) dots.append(adot) return dots
def generate_workflow_image( trans, workflow_name, repository_metadata_id=None, repository_id=None ): """ Return an svg image representation of a workflow dictionary created when the workflow was exported. This method is called from both Galaxy and the tool shed. When called from the tool shed, repository_metadata_id will have a value and repository_id will be None. When called from Galaxy, repository_metadata_id will be None and repository_id will have a value. """ workflow_name = encoding_util.tool_shed_decode( workflow_name ) if trans.webapp.name == 'community': # We're in the tool shed. repository_metadata = suc.get_repository_metadata_by_id( trans, repository_metadata_id ) repository_id = trans.security.encode_id( repository_metadata.repository_id ) changeset_revision = repository_metadata.changeset_revision metadata = repository_metadata.metadata else: # We're in Galaxy. repository = suc.get_tool_shed_repository_by_id( trans, repository_id ) changeset_revision = repository.changeset_revision metadata = repository.metadata # metadata[ 'workflows' ] is a list of tuples where each contained tuple is # [ <relative path to the .ga file in the repository>, <exported workflow dict> ] for workflow_tup in metadata[ 'workflows' ]: workflow_dict = workflow_tup[1] if workflow_dict[ 'name' ] == workflow_name: break if 'tools' in metadata: tools_metadata = metadata[ 'tools' ] else: tools_metadata = [] workflow, missing_tool_tups = get_workflow_from_dict( trans=trans, workflow_dict=workflow_dict, tools_metadata=tools_metadata, repository_id=repository_id, changeset_revision=changeset_revision ) data = [] canvas = svgfig.canvas( style="stroke:black; fill:none; stroke-width:1px; stroke-linejoin:round; text-anchor:left" ) text = svgfig.SVG( "g" ) connectors = svgfig.SVG( "g" ) boxes = svgfig.SVG( "g" ) svgfig.Text.defaults[ "font-size" ] = "10px" in_pos = {} out_pos = {} margin = 5 # Spacing between input/outputs. line_px = 16 # Store px width for boxes of each step. widths = {} max_width, max_x, max_y = 0, 0, 0 for step in workflow.steps: step.upgrade_messages = {} module = module_factory.from_workflow_step( trans, repository_id, changeset_revision, tools_metadata, step ) tool_errors = module.type == 'tool' and not module.tool module_data_inputs = get_workflow_data_inputs( step, module ) module_data_outputs = get_workflow_data_outputs( step, module, workflow.steps ) step_dict = { 'id' : step.order_index, 'data_inputs' : module_data_inputs, 'data_outputs' : module_data_outputs, 'position' : step.position, 'tool_errors' : tool_errors } input_conn_dict = {} for conn in step.input_connections: input_conn_dict[ conn.input_name ] = dict( id=conn.output_step.order_index, output_name=conn.output_name ) step_dict[ 'input_connections' ] = input_conn_dict data.append( step_dict ) x, y = step.position[ 'left' ], step.position[ 'top' ] count = 0 module_name = get_workflow_module_name( module, missing_tool_tups ) max_len = len( module_name ) * 1.5 text.append( svgfig.Text( x, y + 20, module_name, **{ "font-size": "14px" } ).SVG() ) y += 45 for di in module_data_inputs: cur_y = y + count * line_px if step.order_index not in in_pos: in_pos[ step.order_index ] = {} in_pos[ step.order_index ][ di[ 'name' ] ] = ( x, cur_y ) text.append( svgfig.Text( x, cur_y, di[ 'label' ] ).SVG() ) count += 1 max_len = max( max_len, len( di[ 'label' ] ) ) if len( module.get_data_inputs() ) > 0: y += 15 for do in module_data_outputs: cur_y = y + count * line_px if step.order_index not in out_pos: out_pos[ step.order_index ] = {} out_pos[ step.order_index ][ do[ 'name' ] ] = ( x, cur_y ) text.append( svgfig.Text( x, cur_y, do[ 'name' ] ).SVG() ) count += 1 max_len = max( max_len, len( do['name' ] ) ) widths[ step.order_index ] = max_len * 5.5 max_x = max( max_x, step.position[ 'left' ] ) max_y = max( max_y, step.position[ 'top' ] ) max_width = max( max_width, widths[ step.order_index ] ) for step_dict in data: tool_unavailable = step_dict[ 'tool_errors' ] width = widths[ step_dict[ 'id' ] ] x, y = step_dict[ 'position' ][ 'left' ], step_dict[ 'position' ][ 'top' ] # Only highlight missing tools if displaying in the tool shed. if trans.webapp.name == 'community' and tool_unavailable: fill = "#EBBCB2" else: fill = "#EBD9B2" boxes.append( svgfig.Rect( x - margin, y, x + width - margin, y + 30, fill=fill ).SVG() ) box_height = ( len( step_dict[ 'data_inputs' ] ) + len( step_dict[ 'data_outputs' ] ) ) * line_px + margin # Draw separator line. if len( step_dict[ 'data_inputs' ] ) > 0: box_height += 15 sep_y = y + len( step_dict[ 'data_inputs' ] ) * line_px + 40 text.append( svgfig.Line( x - margin, sep_y, x + width - margin, sep_y ).SVG() ) # Define an input/output box. boxes.append( svgfig.Rect( x - margin, y + 30, x + width - margin, y + 30 + box_height, fill="#ffffff" ).SVG() ) for conn, output_dict in step_dict[ 'input_connections' ].iteritems(): in_coords = in_pos[ step_dict[ 'id' ] ][ conn ] # out_pos_index will be a step number like 1, 2, 3... out_pos_index = output_dict[ 'id' ] # out_pos_name will be a string like 'o', 'o2', etc. out_pos_name = output_dict[ 'output_name' ] if out_pos_index in out_pos: # out_conn_index_dict will be something like: # 7: {'o': (824.5, 618)} out_conn_index_dict = out_pos[ out_pos_index ] if out_pos_name in out_conn_index_dict: out_conn_pos = out_pos[ out_pos_index ][ out_pos_name ] else: # Take any key / value pair available in out_conn_index_dict. # A problem will result if the dictionary is empty. if out_conn_index_dict.keys(): key = out_conn_index_dict.keys()[0] out_conn_pos = out_pos[ out_pos_index ][ key ] adjusted = ( out_conn_pos[ 0 ] + widths[ output_dict[ 'id' ] ], out_conn_pos[ 1 ] ) text.append( svgfig.SVG( "circle", cx=out_conn_pos[ 0 ] + widths[ output_dict[ 'id' ] ] - margin, cy=out_conn_pos[ 1 ] - margin, r = 5, fill="#ffffff" ) ) connectors.append( svgfig.Line( adjusted[ 0 ], adjusted[ 1 ] - margin, in_coords[ 0 ] - 10, in_coords[ 1 ], arrow_end = "true" ).SVG() ) canvas.append( connectors ) canvas.append( boxes ) canvas.append( text ) width, height = ( max_x + max_width + 50 ), max_y + 300 canvas[ 'width' ] = "%s px" % width canvas[ 'height' ] = "%s px" % height canvas[ 'viewBox' ] = "0 0 %s %s" % ( width, height ) trans.response.set_content_type( "image/svg+xml" ) return canvas.standalone_xml()
def test2_placeLabel(self, points, layer, window): def interp(a, b, val): slope = float(b[1] - a[1]) / float(b[0] - a[0]) inter = a[1] - slope * a[0] return (val * slope) + inter def f_bl(x): point_range = range(len(points)) point_range.reverse() last_x = 0 for i in range(len(points) / 2): point = points[point_range[i]] #print str(point[0]) + " " +str(x) + " " + str(last_x) if x <= point[0] and x > last_x: #print "Bang!" return interp(point, points[point_range[i - 1]], x) last_x = point[0] return 0 def f_tl(x): last_x = 0 for i in range(len(points) / 2): point = points[i] if x <= point[0] and x > last_x: return interp(point, points[i - 1], x) last_x = point[0] return 0 def is_box_in_shape(x1, y1, x2, y2): width = x2 - x1 for j in range(resolution): x = x1 + ((width / float(resolution)) * j) y_lo = f_bl(x) y_hi = f_tl(x) if y1 < y_lo or y2 > y_hi: return False return True # Get the label label = self.labels[layer] # Take a guess at the aspect ratio of the word label_aspect = len(label) * 0.7 #magic window_aspect = (self.x_max - self.x_min) / float(self.y_max * 1.3) num_guesses = 400 resolution = 10 total_aspect = (((1 / label_aspect) / window_aspect) * self.canvas_aspect) height_max = 0 boxes = svgfig.SVG("g", id="boxes") x1_l = 0 x2_l = 0 y1_l = 0 y2_l = 0 for i in range(num_guesses): x1 = random.uniform(self.x_min, self.x_max) y_lo = f_bl(x1) y_hi = f_tl(x1) h = y_hi - y_lo y1 = random.uniform(y_lo, y_hi - (h / 8.0)) y2 = random.uniform(y1, y_hi) height = y2 - y1 x2 = x1 + height / float(total_aspect) if is_box_in_shape(x1, y1, x2, y2): if height_max < height: height_max = height x1_l = x1 y1_l = y1 x2_l = x2 y2_l = y2 boxes.append( svgfig.Rect(x1, y1, x2, y2, fill="#eeeeee", fill_opacity="10%", stroke_width="0").SVG(window)) boxes.append( svgfig.Rect(x1_l, y1_l, x2_l, y2_l, fill="#eeeeee", fill_opacity="23%", stroke_width="0").SVG(window)) label_x = x1_l + ((x2_l - x1_l) / 2.0) label_y = y1_l + ((y2_l - y1_l) / 6.0) #print (y2_l - y1_l) font = ((y2_l - y1_l) / 2.5) #magic self.current_label = svgfig.Text(label_x, label_y, label, font_family="Droid Sans", font_size=str(font)) return boxes
boxes = draw_boxes(xchrs, ychrs, xend, yend, linewidth, xheader=opts.xhead, yheader=opts.yhead) dots = draw_dots(opts.dag_file, xgenes, ygenes, xchrs, ychrs, noks=opts.noks) # Create new SVG myimage = svgfig.SVG('svg') myimage.append(dots) myimage.append(boxes) myimage.save(opts.out + ".tmp") with open(opts.out + ".tmp") as fh, open(opts.out + '.svg', 'w') as fh2: for x in fh: if x[:4] == '<svg': x = SVG_HEADER_INFO x2 = x.replace('height="400"', 'height="%i"' % (int(ymax) + 20)) x3 = x2.replace('width="400"', 'width="%i"' % (int(xmax) + 20)) fh2.write(x3) else: fh2.write(x)