def makePathSequencesGroup(self) -> G: """ Creates and returns a 'G' object for Path oligo sequences. """ _BW = self._base_width _BH = self._base_height _pX = self.PATH_X_PADDING + self._path_radius_scaled*3 id_coords = self.mapIdnumsToYcoords() oligo_list = self.cn_doc.getOligoList() g = G() g.setAttribute('id', 'PathOligoSequences') g.setAttribute('font-size', '8') g.setAttribute('font-family', 'Monaco') i = 0 for color, is_circular, strands in oligo_list: g_oligo = G() g_oligo.setAttribute('id', "oligo_seq_%s" % i) i += 1 for id_num, idx5, idx3, isfwd, seq in strands: x = _pX + idx5*_BW + _BW/4 if isfwd else _pX + idx5*_BW - _BW/4 y = id_coords[id_num] - _BH*1.1 if isfwd else id_coords[id_num] + _BH*2.2 t = Text('%s' % seq, x, y) t.set_style('fill:%s66' % color) strand_width = (idx3-idx5+1)*_BW if isfwd else (idx5-idx3+1)*_BW t.setAttribute('textLength', strand_width) if not isfwd: t.set_transform('rotate(180,%s,%s)' % (x+_BW/2, y-_BH/2)) g_oligo.addElement(t) g.addElement(g_oligo) return g
def makePathDefs(self) -> Defs: """ Creates Defs object for reusable `Insertion` and `Skip` elements. """ _BW, _BH = self._base_width, self._base_height _hBW, _hBH = _BW/2, _BH/2 _67BW, _67BH = _BW/1.5, _BH/1.5 p = Path() p.appendMoveToPath(_hBW, _hBH) p.appendQuadraticCurveToPath(-_67BW, -_BH, 0, -_BH) p.appendQuadraticCurveToPath(_67BW, 0, 0, _BH) p.set_stroke_linecap("round") g_insertion = G() g_insertion.setAttribute('id', "insertion") g_insertion.addElement(p) d = 0.5 # small delta to compensate for round endcap line1 = Line(d, d, _BW-d, _BH-d, style="stroke:#cc0000; stroke-width:2") line2 = Line(_BW-d, d, d, _BH-d, style="stroke:#cc0000; stroke-width:2") line1.set_stroke_linecap("round") line2.set_stroke_linecap("round") g_skip = G() g_skip.setAttribute('id', "skip") g_skip.addElement(line1) g_skip.addElement(line2) path_defs = Defs() path_defs.addElement(g_insertion) path_defs.addElement(g_skip) return path_defs
def makePathInsertionsGroup(self) -> G: part = self.cn_doc.part id_coords = self.mapIdnumsToYcoords() _BW = self._base_width _hBW = _BW/2 _BH = self._base_height _hBH = _BH/2 _pX = self.PATH_X_PADDING + self._path_radius_scaled*3 g = G() g.setAttribute('id', "PathInsertions") g.setAttribute('font-size', "5") g.setAttribute("font-family", "'SourceSansPro-Regular'") g.setAttribute("text-anchor", "middle") insertions = self.cn_doc.insertions for id_num in sorted(insertions.keys(), reverse=True): fwd_ins_y = id_coords[id_num] - _BH rev_ins_y = id_coords[id_num] for ins_idx, ins_len, fwd_col, rev_col in insertions[id_num][::-1]: ins_g = G() ins_g.setAttribute('id', "Ins %s[%s]" % (id_num, ins_idx)) ins_x = _BW*ins_idx + _pX ins_fwd, ins_rev = part.hasStrandAtIdx(id_num, ins_idx) if ins_fwd: u = Use() u.setAttribute('xlink:href', '#insertion') u.setAttribute('x', ins_x) u.setAttribute('y', fwd_ins_y) fwd_style = 'fill:none; stroke:%s; stroke-width:2' % fwd_col u.set_style(fwd_style) ins_g.addElement(u) t = Text('%s' % ins_len, ins_x+_hBW, fwd_ins_y) t.set_style('fill:#999999') ins_g.addElement(t) if ins_rev: u = Use() u.setAttribute('xlink:href', '#insertion') u.setAttribute('x', ins_x) u.setAttribute('y', rev_ins_y) rev_style = 'fill:none; stroke:%s; stroke-width:2' % rev_col u.set_style(rev_style) u.set_transform('rotate(180,%s,%s)' % (ins_x+_hBW, rev_ins_y+_hBH)) ins_g.addElement(u) t = Text('%s' % ins_len, ins_x+_hBW, rev_ins_y+_BH*1.3) t.set_style('fill:#999999') ins_g.addElement(t) g.addElement(ins_g) # print(g.getXML()) return g
def _add_label(self, group: Group, v_offset: int) -> Group: acc = Text(self.full_description, 5, 20 + v_offset) if self.prefix == "knownclusterblast": desc = "%80s (%s), %s" % (self.description, self.similarity_string, self.cluster_type) acc = Text( '<a xlink:href="https://mibig.secondarymetabolites.org/go/' + self.accession + '/%s" target="_blank">' % self.ref_cluster_number + self.accession + '</a>: ' + desc, 5, 20 + v_offset) elif self.prefix == "general": acc = Text( '<a xlink:href="https://antismash-db.secondarymetabolites.org/go/' + self.accession + '/%s" target="_blank">' % self.ref_cluster_number + self.full_description.replace(":", "</a>:", 1), 5, 20 + v_offset) # Don't do any linking for subclusterblast acc.set_class("clusterblast-acc") group.addElement(acc) group.setAttribute('label', self.accession) group.setAttribute('description', self.full_description) group.set_class('clusterblast-cluster') return group
def get_svg_groups(self, h_offset: int = 0, v_offset: int = 0, scaling: float = 1., screenwidth: int = 1024, colours: Dict[str, str] = None, overview: bool = False, prefix: str = "dummy") -> List[Group]: """ Returns all SVG elements required to draw the Cluster """ if not colours: colours = {} groups = [] group = Group() self._add_label(group, v_offset) line_y = 35 + v_offset group.addElement(ShapeBuilder().createLine(10, line_y, 10 + (screenwidth * 0.75), line_y, strokewidth=1, stroke="grey")) groups.append(group) # Add gene arrows arrow_y = line_y + 5 offset = h_offset - self.start if self.reversed: offset = h_offset + self.end for i, gene in enumerate(self.genes): group = Group() arrow = gene.get_arrow_polygon(scaling=scaling, offset=offset, base=arrow_y, colour=colours.get(gene.name, "white")) if overview: label = "all_" else: label = "h" arrow.set_id("%s-%d_%s%d_%s_%s" % (prefix, self.query_cluster_number, label, self.query_cluster_number, self.rank, i)) group.addElement(arrow) # Can be used for domains group.set_id("a%s_00%s" % (self.query_cluster_number, i)) groups.append(group) return groups
def makeSliceVhGroup(self) -> Tuple: """ Creates and returns a 'G' object for Slice Virtual Helices. """ _SLICE_SCALE = self._scale vh_radius = self.cn_doc.vh_radius * _SLICE_SCALE g = G() g.setAttribute('id', "VirtualHelices") minx = 99999 miny = 99999 maxx = -99999 maxy = -99999 for id_num in self.cn_doc.vh_order[::-1]: vh_x, vh_y = self.cn_doc.vh_origins[id_num] x = vh_x * _SLICE_SCALE # + self.cn_doc.x_offset y = -vh_y * _SLICE_SCALE # + self.cn_doc.y_offset minx = min(minx, x) miny = min(miny, y) maxx = max(maxx, x) maxy = max(maxy, y) c = Circle(x, y, vh_radius) circle_style = 'fill:#f2ca9a; stroke:#cc6600; stroke-width:1;' c.set_style(circle_style) c.setAttribute('id', "circle_"+self.cn_doc.vh_props['name'][id_num]) g.addElement(c) minx = minx-vh_radius*2 miny = miny-vh_radius*2 width = round(maxx-minx+vh_radius*2, 3) height = round(maxy-miny+vh_radius*2, 3) transform = 'translate(%.3f %.3f)' % (-minx, -miny) g.set_transform(transform) return g, width, height, transform
def __init__(self, x, y, z, YZgridCoord): self.x = float(x)*SCALING_FACTOR self.y = float(y)*SCALING_FACTOR self.z = float(z)*SCALING_FACTOR print(str(self.z) + ' prism') self.startCoord = [YZgridCoord[0], YZgridCoord[1] + self.y + SPACING] self.out = G()
def genHoneycomb(self): outComb = G() circleStyle = StyleBuilder() #circleStyle.setStrokeWidth(0.5) circleStyle.setStroke('orange') circleStyle.setFilling('#edd239') CORNER = self.hCSlice.getBottomRight() circleY = [] circleY.append(CORNER[1] + (ROW_SPACE - CIRCLE_RADIUS)) for g in range(0, self.row): circleX = CORNER[0] - CIRCLE_RADIUS if (g != 0 and g % 2 != 0): circleY.append(circleY[g-1] + 2*CIRCLE_RADIUS) elif (g!= 0 and g % 2 == 0): circleY.append(circleY[g-1] + 2*(ROW_SPACE - CIRCLE_RADIUS)) #initCircle = Circle(circleX, circleY[g], CIRCLE_RADIUS) #outComb.addElement(initCircle) for i in range(0, self.col): newShift = TransformBuilder() xShift = -i*CIRCLE_RADIUS*math.sqrt(3) yShift = 0 if i % 2 != 0 and g % 2 != 0: yShift = CIRCLE_RADIUS elif i % 2 != 0 and g % 2 == 0: yShift = -1*CIRCLE_RADIUS newShift.setTranslation(str(xShift) + ' ' + str(yShift)) a = Circle(circleX, circleY[g], CIRCLE_RADIUS) a.set_transform(newShift.getTransform()) outComb.addElement(a) outComb.set_style(circleStyle.getStyle()) return outComb
def _draw_legend(self, categories): """ Draw legend for the given categories. Box in lower right corner Motivation for positioning in right corner: SVG text cannot be centered since the text width cannot be calculated and the first part of each event text is important. ergo: text needs to be left aligned. But then the probability is high that a lot of text is at the left bottom ergo: put the legend to the right. +----------+ | Name O | | Name O | +----------+ """ group = G() group.addElement(self._draw_categories_box(len(categories))) cur_y = self._get_categories_box_y(len(categories)) + OUTER_PADDING for cat in categories: color_box, label = self._draw_category( self._get_categories_box_width(), self._get_categories_item_height(), self._get_categories_box_x(), cur_y, cat) group.addElement(color_box) group.addElement(label) cur_y = cur_y + self._get_categories_item_height() + INNER_PADDING return group
def drawSideFacePair(topCorners, bottomCorners, color): pointList = [] pointList2 = [] output = G() XYStyle1 = StyleBuilder() #XYStyle1.setStroke('black') #XYStyle1.setStrokeWidth(1.5) XYStyle1.setFilling(color) #XYStyle1.setFillOpacity(0.8) XYStyle2 = StyleBuilder() XYStyle2.setStroke(color) XYStyle2.setStrokeWidth(0.5) XYStyle2.setFilling(color) pointList.append(strPathStart(topCorners[2])) pointList.append(strPathPoint(topCorners[3])) pointList.append(strPathPoint(bottomCorners[3])) pointList.append(strPathPoint(bottomCorners[2])) svgCode1 = pGram(pointList) pointList2.append(strPathStart(topCorners[0])) pointList2.append(strPathPoint(topCorners[1])) pointList2.append(strPathPoint(bottomCorners[1])) pointList2.append(strPathPoint(bottomCorners[0])) svgCode2 = pGram(pointList2) rightFace = Path(svgCode1) rightFace.set_style(XYStyle1.getStyle()) leftFace = Path(svgCode2) leftFace.set_style(XYStyle2.getStyle()) output.addElement(leftFace) output.addElement(rightFace) return output
def drawFrontFacePair(topCorners, bottomCorners, color): pointList = [] pointList2 = [] output = G() YZStyle1 = StyleBuilder() #YZStyle1.setStroke('black') #YZStyle1.setStrokeWidth(1.5) YZStyle1.setFilling(color) YZStyle1.setFillOpacity(0.75) YZStyle2 = StyleBuilder() YZStyle2.setStroke('black') YZStyle2.setStrokeWidth(0.5) YZStyle2.setFillOpacity(0.75) YZStyle2.setFilling('#ffffff') pointList.append(strPathStart(topCorners[1])) pointList.append(strPathPoint(topCorners[2])) pointList.append(strPathPoint(bottomCorners[2])) pointList.append(strPathPoint(bottomCorners[1])) svgCode1 = pGram(pointList) pointList2.append(strPathStart(topCorners[0])) pointList2.append(strPathPoint(topCorners[3])) pointList2.append(strPathPoint(bottomCorners[3])) pointList2.append(strPathPoint(bottomCorners[0])) svgCode2 = pGram(pointList2) frontFace = Path(svgCode1) frontFace.set_style(YZStyle1.getStyle()) backFace = Path(svgCode2) backFace.set_style(YZStyle2.getStyle()) output.addElement(backFace) output.addElement(frontFace) return output
def _get_bg(self): """ Draw background color Draw background Era strips and labels Draw major and minor strips, lines to all event boxes and baseline. Both major and minor strips have divider lines and labels. Draw now line if it is visible """ group = G() group.addElement(self._draw_background()) for era in self._timeline.get_all_periods(): group.addElement(self._draw_era_strip(era)) group.addElement(self._draw_era_text(era)) for strip in self._scene.minor_strip_data: group.addElement( self._draw_minor_strip_divider_line(strip.end_time)) group.addElement(self._draw_minor_strip_label(strip)) for strip in self._scene.major_strip_data: group.addElement( self._draw_major_strip_divider_line(strip.end_time)) group.addElement(self._draw_major_strip_label(strip)) group.addElement(self._draw_divider_line()) self._draw_lines_to_non_period_events(group, self._view_properties) if self._now_line_is_visible(): group.addElement(self._draw_now_line()) return group
def makePathSkipsGroup(self) -> G: """ Creates and returns a 'G' object for Path VirtualHelix Labels. Elements are sorted in reverse order so they are listed in ascending order in Illustrator. """ _BW = self._base_width _BH = self._base_height _pX = self.PATH_X_PADDING + self._path_radius_scaled*3 id_coords = self.mapIdnumsToYcoords() part = self.cn_doc.part g = G() g.setAttribute('id', "PathSkips") skips = self.cn_doc.skips for id_num in sorted(skips.keys(), reverse=True): fwd_skip_y = id_coords[id_num] - _BH rev_skip_y = id_coords[id_num] for skip_idx, _ in skips[id_num][::-1]: skip_g = G() skip_g.setAttribute('id', "Skip %s[%s]" % (id_num, skip_idx)) skip_x = _BW*skip_idx + _pX skip_fwd, skip_rev = part.hasStrandAtIdx(id_num, skip_idx) if skip_fwd: u = Use() u.setAttribute('xlink:href', '#skip') u.setAttribute('x', skip_x) u.setAttribute('y', fwd_skip_y) skip_g.addElement(u) if skip_rev: u = Use() u.setAttribute('xlink:href', '#skip') u.setAttribute('x', skip_x) u.setAttribute('y', rev_skip_y) skip_g.addElement(u) g.addElement(skip_g) return g
def makerow(self): frameStyle = StyleBuilder() frameStyle.setStrokeWidth(1.5) frameStyle.setStroke('black') frameStyle.setFilling('white') out = G() yCoord = 10 + (FRAMELEN + 20) * self.i for z in range(0, 4): newFrame = Rect(10 + (FRAMELEN + 20) * z, yCoord, FRAMELEN, FRAMELEN) newFrame.set_style(frameStyle.getStyle()) out.addElement(newFrame) self.rowCoords.append([10 + (FRAMELEN + 20) * z, yCoord]) return out
def _add_label(self, group: Group, v_offset: int) -> Group: acc = Text(self.full_description, 5, 20 + v_offset) if self.accession.startswith('BGC'): acc = Text('<a xlink:href="http://mibig.secondarymetabolites.org/repository/' + self.accession + '/index.html#cluster-1" target="_blank">' + self.accession + '</a>: ' + "%80s (%s)" % (self.description, self.similarity), 5, 20 + v_offset) elif self.accession.split("_")[0] in get_antismash_db_accessions(): acc = Text('<a xlink:href="http://antismash-db.secondarymetabolites.org/output/' + self.accession + '/index.html#cluster-%s" target="_blank">' % self.ref_cluster_number[1:] + self.full_description.replace(":", "</a>:"), 5, 20 + v_offset) acc.set_class("clusterblast-acc") group.addElement(acc) group.setAttribute('label', self.accession) group.setAttribute('description', self.full_description) group.set_class('clusterblast-cluster') return group
def makePathVhGroup(self) -> G: """ Creates and returns a 'G' object for Path Virtual Helices. """ g = G() g.setAttribute('id', "VirtualHelices") for i in range(len(self.cn_doc.vh_order)): id_num = self.cn_doc.vh_order[i] x = self.PATH_X_PADDING y = self.PATH_Y_PADDING + self._path_vh_margin*i c = Circle(x, y, self.cn_doc.vh_radius*self._scale) circle_style = 'fill:#f2ca9a; stroke:#cc6600; stroke-width:1;' c.set_style(circle_style) c.setAttribute('id', "circle_"+self.cn_doc.vh_props['name'][id_num]) g.addElement(c) return g
def _draw_event(self, event, rect): if self._scene.center_text(): style = self._small_centered_font_style else: style = self._small_font_style group = G() group.addElement(self._draw_event_rect(event, rect)) text_rect = rect.Get() if event.is_container() and EXTENDED_CONTAINER_HEIGHT.enabled(): text_rect = rect.Get() text_rect = (text_rect[0], text_rect[1] - Y_TEXT_OFFSET, text_rect[2], text_rect[3]) group.addElement(self._svg_clipped_text(event.text, text_rect, style, self._scene.center_text())) if event.has_data(): group.addElement(self._draw_contents_indicator(event, rect)) return group
def makePathGridlinesGroup(self) -> G: size = self.cn_doc.max_vhelix_length _BW = self._base_width _BH = self._base_height g = G() g.setAttribute('id', "GridLines") for i in range(len(self.cn_doc.vh_order)): id_num = self.cn_doc.vh_order[i] x = self.PATH_X_PADDING + self._path_radius_scaled*3 y = self.PATH_Y_PADDING + self._path_vh_margin*i h_lines = " ".join("M %s,%s h %s" % (x, y-_BH+j*_BH, _BW*size) for j in range(3)) v_lines = " ".join("M %s,%s v %s" % (x+j*_BW, y-_BH, _BH*2) for j in range(int(size)+1)) p = Path(h_lines + " " + v_lines) grid_style = 'fill:none; stroke:#666666; stroke-width:0.25' p.set_style(grid_style) p.setAttribute('id', "grid_"+self.cn_doc.vh_props['name'][id_num]) g.addElement(p) return g
def makePathEndpointsGroup(self) -> G: _BW = self._base_width _BH = self._base_height _pX = self.PATH_X_PADDING + self._path_radius_scaled*3 id_coords = self.mapIdnumsToYcoords() ends5p, ends3p = self.cn_doc.getOligoEndpointsList() g = G() g.setAttribute('id', "Endpoints") i = 0 for color, idnum5p, idx5p, isfwd5p in ends5p: if isfwd5p: x = _pX + idx5p*_BW + _BW*.25 y = id_coords[idnum5p] - _BH + _BH*.05 else: x = _pX + idx5p*_BW y = id_coords[idnum5p] + _BH*.05 r = Rect(x=x, y=y, width=_BW*0.75, height=_BH*.9) endpoint_style = 'fill:%s; stroke:none; stroke-width:0.5' % color r.set_style(endpoint_style) r.setAttribute('id', "end5p_%s" % i) i += 1 g.addElement(r) j = 0 for color, idnum3p, idx3p, isfwd3p in ends3p: if isfwd3p: x = _pX + idx3p*_BW y = id_coords[idnum3p] - _BH x1, y1 = x, y x2, y2 = x1+_BW*0.75, y1+_BH/2 x3, y3 = x, y1+_BH else: x = _pX + idx3p*_BW y = id_coords[idnum3p] x1, y1 = x+_BW, y x2, y2 = x+_BW*0.25, y1+_BH/2 x3, y3 = x+_BW, y+_BH pts = "%s,%s %s,%s %s,%s %s,%s" % (x1, y1, x2, y2, x3, y3, x1, y1) p = Polygon(points=pts) end3p_style = 'fill:%s; stroke:none; stroke-width:0.5' % color p.set_style(end3p_style) p.setAttribute('id', "end3p_%s" % j) j += 1 g.addElement(p) return g
def makePathOligosGroup(self) -> G: id_coords = self.mapIdnumsToYcoords() oligo_list = self.cn_doc.getOligoList() _BW = self._base_width _BH = self._base_height _pX = self.PATH_X_PADDING + self._path_radius_scaled*3 + _BW/2 g = G() g.setAttribute('id', "Oligos") i = 0 for color, is_circular, strands in oligo_list: prev_id, prev5, prev3, prevX, prevY = None, None, None, 0, 0 path_lines = [] if is_circular: strands.append(strands[0]) for id_num, idx5, idx3, isfwd, _ in strands: x = _pX + idx5*_BW if idx5 < idx3: # top strand y = id_coords[id_num] - _BH/2 else: y = id_coords[id_num] + _BH/2 dx = (idx3-idx5)*_BW if prev_id is not None and id_num != prev_id: # c dx1 dy1, dx2 dy2, dx dy if isfwd: x1 = x + abs(y-prevY)*0.03 else: x1 = x - abs(y-prevY)*0.03 y1 = (y+prevY)/2 path_lines.append("Q %s %s, %s %s" % (x1, y1, x, y)) path_lines.append("h %s" % dx) else: path_lines.append("M %s, %s h %s" % (x, y, dx)) prev_id, prev5, prev3, prevX, prevY = id_num, idx5, idx3, x, y p = Path(" ".join(path_lines)) oligo_style = 'fill:none; stroke:%s; stroke-width:2' % color p.set_style(oligo_style) p.setAttribute('id', "oligo_%s" % i) p.setAttribute("stroke-linejoin", "round") i += 1 g.addElement(p) return g
def makePathVhLabelGroup(self) -> G: """ Creates and returns a 'G' object for Path VirtualHelix Labels. """ g = G() g.setAttribute('id', "VirtualHelixLabels") g.setAttribute('font-size', "%s" % self._path_vh_fontsize) if self.useCS6font: g.setAttribute("font-family", "'SourceSansPro-Regular'") else: g.setAttribute("font-family", "'Source Sans Pro', sans-serif") g.setAttribute("text-anchor", "middle") for i in range(len(self.cn_doc.vh_order)): id_num = self.cn_doc.vh_order[i] x = self.PATH_X_PADDING y = self.PATH_Y_PADDING + self._path_vh_margin*i + self._path_radius_scaled/2. t = Text('%s' % id_num, x, y) t.setAttribute('id', "label_"+self.cn_doc.vh_props['name'][id_num]) g.addElement(t) return g
def genLabels(self): labels = G() labelStyle = StyleBuilder() labelStyle.setTextAnchor('middle') labelStyle.setFontSize(10) lineStyle = StyleBuilder() lineStyle.setStroke('#a9a9a9') dimLabelA = str(self.dimA) + ' nm' dimLabelB = str(self.dimB) + ' nm' # horizontal label cornerHL = self.view.getTopLeft() cornerHR = self.view.getTopRight() hLabelStart = [cornerHL[0], cornerHL[1] + 5] hLabelEnd = [cornerHR[0], cornerHR[1] + 5] hLine = Line(hLabelStart[0], hLabelStart[1], hLabelEnd[0], hLabelEnd[1]) hLabel = Text(dimLabelA, (hLabelStart[0] + hLabelEnd[0])/2, hLabelEnd[1] + 20) hLine.set_style(lineStyle.getStyle()) hLabel.set_style(labelStyle.getStyle()) cornerVL = self.view.getTopLeft() cornerVR = self.view.getBottomLeft() vLabelStart = [cornerVL[0] - 5, cornerVL[1]] vLabelEnd = [cornerVR[0] - 5, cornerVR[1]] vLine = Line(vLabelStart[0], vLabelStart[1], vLabelEnd[0], vLabelEnd[1]) vLabel = Text(dimLabelB, vLabelEnd[0] - 30, (vLabelStart[1] + vLabelEnd[1])/2) vLine.set_style(lineStyle.getStyle()) vLabel.set_style(labelStyle.getStyle()) labels.addElement(hLine) labels.addElement(hLabel) labels.addElement(vLine) labels.addElement(vLabel) #center = [self.gridCoord[0] + self.dimA*SCALING_FACTOR/2, self.gridCoord[1] + self.dimB*SCALING_FACTOR + LABEL_SHIFT] #dimLabel = str(self.dimA) + 'nm x ' +str(self.dimB) + 'nm' #labels = Text(dimLabel, center[0], center[1]) #labels.set_style(labelStyle.getStyle()) return labels
def makeSliceVhLabelGroup(self, transform) -> G: """ Creates and returns a 'G' object for Slice VirtualHelix Labels. """ _SLICE_SCALE = self._scale g = G() g.setAttribute('id', "VirtualHelixLabels") g.setAttribute('font-size', "%s" % self._slice_vh_fontsize) if self.useCS6font: g.setAttribute("font-family", "'SourceSansPro-Regular'") else: g.setAttribute("font-family", "'Source Sans Pro', sans-serif") g.setAttribute("text-anchor", "middle") for id_num in self.cn_doc.vh_order[::-1]: vh_x, vh_y = self.cn_doc.vh_origins[id_num] x = vh_x # + self.cn_doc.x_offset y = -vh_y + self.cn_doc.vh_radius/2. t = Text('%s' % id_num, x*_SLICE_SCALE, y*_SLICE_SCALE - 1) t.setAttribute('id', "label_"+self.cn_doc.vh_props['name'][id_num]) g.addElement(t) g.set_transform(transform) return g
def genLabels(self): labels = G() labelStyle = StyleBuilder() labelStyle.setTextAnchor('middle') labelStyle.setFontSize(10) lineStyle = StyleBuilder() lineStyle.setStroke('#a9a9a9') dimLabelA = str(self.x/SCALING_FACTOR) + ' nm' dimLabelB = str(self.z/SCALING_FACTOR) + ' nm' # horizontal label cornerHL = self.hCSlice.getTopLeft() cornerHR = self.hCSlice.getTopRight() hLabelStart = [cornerHL[0], cornerHL[1] + 5] hLabelEnd = [cornerHR[0], cornerHR[1] + 5] hLine = Line(hLabelStart[0], hLabelStart[1], hLabelEnd[0], hLabelEnd[1]) hLabel = Text(dimLabelA, (hLabelStart[0] + hLabelEnd[0])/2, hLabelEnd[1] + 20) hLine.set_style(lineStyle.getStyle()) hLabel.set_style(labelStyle.getStyle()) cornerVL = self.hCSlice.getTopLeft() cornerVR = self.hCSlice.getBottomLeft() vLabelStart = [cornerVL[0] - 5, cornerVL[1]] vLabelEnd = [cornerVR[0] - 5, cornerVR[1]] vLine = Line(vLabelStart[0], vLabelStart[1], vLabelEnd[0], vLabelEnd[1]) vLabel = Text(dimLabelB, vLabelEnd[0] - 30, (vLabelStart[1] + vLabelEnd[1])/2) vLine.set_style(lineStyle.getStyle()) vLabel.set_style(labelStyle.getStyle()) labels.addElement(hLine) labels.addElement(hLabel) labels.addElement(vLine) labels.addElement(vLabel) return labels
def get_svg_groups(self, h_offset: int = 0, v_offset: int = 0, scaling: float = 1., screenwidth: int = 1024, colours: Dict[str, str] = None, overview: bool = False, prefix: str = "dummy") -> List[Group]: """ Returns all SVG elements required to draw the Cluster """ if not colours: colours = {} groups = [] group = Group() acc = Text(self.description, 5, 20) acc.set_class("clusterblast-acc") group.addElement(acc) line_y = 35 + v_offset group.addElement(ShapeBuilder().createLine(10, line_y, 10 + (screenwidth * 0.75), line_y, strokewidth=1, stroke="grey")) group.setAttribute('label', self.description) group.set_class('clusterblast-cluster') groups.append(group) base = line_y + 5 offset = h_offset + 10 - self.start # 10 for margin for index, gene in enumerate(self.genes): arrow = gene.get_arrow_polygon(scaling=scaling, offset=offset, base=base, colour=colours.get( gene.name, "white")) arrow.set_id("%s-%s_q%s_%s_%s" % (prefix, self.region_number, index, self.rank, "all")) group.addElement(arrow) return groups
def _svg_clipped_text(self, text, rect, style, center_text=False): group = G() group.set_clip_path("url(#%s)" % self._create_clip_path(rect)) group.addElement(self._draw_text(text, rect, style, center_text)) return group