def write(self, path): """ Writes the page to the SVG file with the provided path. """ # Create a new SVG document doc = svg( x=0, y=0, width=mm_to_px(self.width), height=mm_to_px(self.height) ) # Draw all the content: first the background, then the content, # and finally the labels background_group = g() background_group.setAttribute('id', 'background') content_group = g() content_group.setAttribute('id', 'content') label_group = g() label_group.setAttribute('id', 'labels') contour_group = g() contour_group.setAttribute('id', 'contours') my_defs = defs() for c in self.containers: if c.has_background: c.draw_background(background_group) if c.needs_clipping and (c.has_content or c.has_labels): path_id = random_string(16) clprect = rect( x=mm_to_px(c.x), y=mm_to_px(c.y), width=mm_to_px(c.width), height=mm_to_px(c.height) ) clppath = clipPath(id=path_id) clppath.addElement(clprect) my_defs.addElement(clppath) # Draw content with clipping path if c.has_content: container_grp = g() container_grp.set_clip_path('url(#%s)' % path_id) c.draw_content(container_grp) content_group.addElement(container_grp) # The labels on top of the content if c.has_labels: container_grp = g() container_grp.set_clip_path('url(#%s)' % path_id) c.draw_labels(container_grp) label_group.addElement(container_grp) else: if c.has_content: c.draw_content(content_group) if c.has_labels: c.draw_labels(label_group) if c.has_contour: c.draw_contour(contour_group) # Add each of the base groups doc.addElement(my_defs) doc.addElement(background_group) doc.addElement(content_group) doc.addElement(label_group) doc.addElement(contour_group) # Write the SVG document to the file doc.save(path)
def draw_contour(self, elem): """ Draws a contour around the container. """ contour_rect = rect( x = mm_to_px(self.x), y = mm_to_px(self.y), width = mm_to_px(self.width), height = mm_to_px(self.height) ) contour_rect.set_style(self.contour_style.getStyle()) elem.addElement(contour_rect)
def draw_background(self, elem): """ Draws the background of the container. elem is a SVG element, and we should add our content to this element. The method doesn't return anything. """ bg_rect = rect( x = mm_to_px(self.x), y = mm_to_px(self.y), width = mm_to_px(self.width), height = mm_to_px(self.height) ) bg_rect.set_style(self.bg_style.getStyle()) elem.addElement(bg_rect)
def legend(self, elem, x, y, width, height, label_style): n = len(self.colors.colors) box_height = int(np.floor(float(height) / (n+2))) box_width = min(8, width/2) mark_style = StyleBuilder(self.mark_style) textsize = int(re.findall('([0-9]+)', label_style.get('font-size', "8") )[0]) label_x = x + box_width + self.mark_length + 1 for i in range(n): box = rect( x = mm_to_px(x), y = mm_to_px(y + (n-i-1)*box_height), width = mm_to_px(box_width), height = mm_to_px(box_height) ) s = deepcopy(self.styles[i].style_dict) s['stroke'] = 'black' box.set_style(StyleBuilder(s).getStyle()) elem.addElement(box) if i < (n-1): mark = line( X1=mm_to_px(x+box_width), Y1=mm_to_px(y+(n-i-1)*box_height), X2=mm_to_px(x+box_width+self.mark_length), Y2=mm_to_px(y+(n-i-1)*box_height) ) mark.set_style(mark_style.getStyle()) elem.addElement(mark) label = text( content="%0.*f" % (self.ndecimals, self.limits[i]), x=mm_to_px(label_x), y=mm_to_px(y+(n-i-1)*box_height)+(textsize/2) ) label.set_style(StyleBuilder(label_style).getStyle()) elem.addElement(label) label = text( content="Min: %0.*f" % (self.ndecimals, np.min(self.values)), x=mm_to_px(label_x), y=mm_to_px(y+n*box_height)+(textsize/2) ) label.set_style(StyleBuilder(label_style).getStyle()) elem.addElement(label) label = text( content="Max: %0.*f" % (self.ndecimals, np.max(self.values)), x=mm_to_px(label_x), y=mm_to_px(y+0*box_height)+(textsize/2) ) label.set_style(StyleBuilder(label_style).getStyle()) elem.addElement(label)
def num(txt, color): txt = str(txt) elems = [] r = rect(0, 0, 16, 16) s = StyleBuilder() s.setFilling(color) r.set_style(s.getStyle()) elems.append(r) if txt: style2 = StyleBuilder() #style2.setFontFamily('envy code r') style2.setFontFamily('arial') style2.setFontWeight('bold') style2.setFilling(ALUM_1) # shift text left and up by a bit if len(txt) == 1: x = 5 elif len(txt) == 2: x = 1.5 t = text(txt, x, 12.5) t.set_style(style2.getStyle()) elems.append(t) return elems
def draw_content(self, elem): contour = rect( x = mm_to_px(self.x), y = mm_to_px(self.y), width = mm_to_px(self.width), height = mm_to_px(self.height) ) contour.set_style(StyleBuilder(self.container_style).getStyle()) elem.addElement(contour) x = self.x + self.border y = self.y + self.border width = self.width - (2*self.border) height = self.height - (2*self.border) if self.title is not None: textsize = int(re.findall('([0-9]+)', self.title_style.get('font-size', "11") )[0]) t = text( content=self.title, x=mm_to_px(x), y=mm_to_px(y) + textsize ) t.set_style(StyleBuilder(self.title_style).getStyle()) elem.addElement(t) y += int(round(textsize)) if self.name is not None: textsize = int(re.findall('([0-9]+)', self.name_style.get('font-size', "11") )[0]) t = text( content=self.name, x=mm_to_px(x), y=mm_to_px(y) + textsize ) t.set_style(StyleBuilder(self.name_style).getStyle()) elem.addElement(t) y += int(round(textsize)) self.style.legend(elem, x, y, width, height, self.label_style)