def draw(self, ar, can): center = self.center if not center: center = (ar.loc[0] + ar.size[0]/2.0, ar.loc[1] + ar.size[1]/2.0) base_radius = self.base_radius # the maximum radius of a wedge if not base_radius: base_radius = min(ar.size[0]/2.0, ar.size[1]/2.0) #* 0.8 sector_decrement = 1./(len(self.data)*2) * self.sector_width # each following sector diagram will have its sector width decremented by half this amount (in degrees) i = 0 for dataset in self.data: cur_angle = self.start_angle if self.sector_centred: cur_angle -= self.sector_width/2. fill = self.fill_styles[i] x_center = center[0] y_center = center[1] if not i: # draw directions around sector diagram once off dir_offset = base_radius + (self.dir_offset or base_radius * 0.04) directions = ['N', 'E', 'S', 'W'] angle = self.start_angle can.ellipsis(line_style.T(color=color.black, width=0.3, dash=line_style.dash1), None, x_center, y_center, base_radius, 1, 0, 360) # for d in directions: x_label, y_label = pychart_util.rotate(dir_offset, 0, angle) # coords for bottom left corner of box tw = font.text_width(d) half = 1/3. # normal arithmetic does not seem to apply to these text_box objects... if (angle == 0): # east y_label -= font.text_height(d)[0]*half # move down half elif (angle == -180): # west y_label -= font.text_height(d)[0]*half # move down half x_label -= font.text_width(d) # move left full elif (angle == 90): # north x_label -= font.text_height(d)[0]*half # move left half elif (angle == -90): # south y_label -= font.text_height(d)[0]*.8 # move down (couldn't figure out how to set this dynamically so I fudged...) x_label -= font.text_height(d)[0]*half # move left half canvas.show(x_label + x_center, y_label + y_center, d) angle -= 360/len(directions) for val in dataset[self.data_col]: # now draw the sectors radius = base_radius*val # scale the radius start = cur_angle-self.sector_width+i*sector_decrement stop = cur_angle-i*sector_decrement # these may seem confusing, but remember that we need to go counterclockwise can.ellipsis(self.line_style, fill, x_center, y_center, radius, 1, start, stop, self.shadow) cur_angle = (cur_angle - self.sector_width) % 360 # we want to go in anticlockwise direction (North, West, South, etc. as in meteorology) i = (i + 1) % len(self.fill_styles)
def draw_right(self, ar, can): x_base = ar.loc[0] + self.offset xmax = 0 tic_dic = {} for i in ar.y_tic_points(self.tic_interval): y_tic = ar.y_pos(i) tic_dic[i] = 1 can.line(self.line_style, x_base, y_tic, x_base + self.tic_len, y_tic) string = pychart_util.apply_format(self.format, (i,), 0) if self.tic_len > 0: string = "/hL" + string tic_height, base_height = font.text_height(string) x = x_base + self.tic_len + self.tic_label_offset[0] can.show(x, y_tic - tic_height/2.0 + self.tic_label_offset[1], string) xmax = max(xmax, x + font.text_width(string)) if self.minor_tic_interval: for i in ar.y_tic_points(self.minor_tic_interval): if tic_dic.has_key(i): # a major tic line was drawn already. pass else: y_tic = ar.y_pos(i) can.line(self.line_style, x_base, y_tic, x_base + self.minor_tic_len, y_tic) self.draw_label(ar, can, xmax + theme.default_font_size)
def draw_right(self, ar, can): x_base = ar.loc[0] + self.offset xmax = 0 tic_dic = {} for i in ar.y_tic_points(self.tic_interval): y_tic = ar.y_pos(i) tic_dic[i] = 1 can.line(self.line_style, x_base, y_tic, x_base + self.tic_len, y_tic) str = pychart_util.apply_format(self.format, (i, ), 0) if self.tic_len > 0: str = "/hL" + str tic_height, base_height = font.text_height(str) x = x_base + self.tic_len + self.tic_label_offset[0] can.show(x, y_tic - tic_height / 2.0 + self.tic_label_offset[1], str) xmax = max(xmax, x + font.text_width(str)) if self.minor_tic_interval: for i in ar.y_tic_points(self.minor_tic_interval): if tic_dic.has_key(i): # a major tic line was drawn already. pass else: y_tic = ar.y_pos(i) can.line(self.line_style, x_base, y_tic, x_base + self.minor_tic_len, y_tic) self.draw_label(ar, can, xmax + theme.default_font_size)
def get_dimension(self): x = self.loc[0] - self.left_fudge y = self.loc[1] - self.bottom_fudge width = font.text_width(self.text) + self.right_fudge + self.left_fudge height = (font.text_height( self.text))[0] + self.top_fudge + self.bottom_fudge return (x, y, width, height)
def draw(self, ar, can): center = self.center if not center: center = (ar.loc[0] + ar.size[0] / 2.0, ar.loc[1] + ar.size[1] / 2.0) radius = self.radius if not radius: radius = min(ar.size[0] / 2.0, ar.size[1] / 2.0) * 0.5 label_offset = radius + (self.label_offset or radius * 0.1) total = self._total() i = 0 cur_angle = self.start_angle for val in self.data: fill = self.fill_styles[i] degree = 360 * float(val[self.data_col]) / float(total) off = (0, 0) if len(self.arc_offsets) > i: off = pychart_util.rotate(self.arc_offsets[i], 0, cur_angle - degree / 2.0) x_center = center[0] + off[0] y_center = center[1] + off[1] can.ellipsis(self.line_style, fill, x_center, y_center, radius, 1, cur_angle - degree, cur_angle, self.shadow) label = pychart_util.apply_format(self.label_format, val, self.label_col) if label != None: (x_label, y_label) = pychart_util.rotate(label_offset, 0, cur_angle - degree / 2.0) (x_arrowtip, y_arrowtip) = pychart_util.rotate(radius, 0, cur_angle - degree / 2.0) # Labels on left side of pie need # their text to avoid obscuring the pie if x_label < 0: x_label = x_label - font.text_width(label) t = text_box.T(loc=(x_label + x_center, y_label + y_center), text=label, line_style=self.label_line_style, fill_style=self.label_fill_style) if self.arrow_style: t.add_arrow((x_arrowtip + x_center, y_arrowtip + y_center), None, self.arrow_style) t.draw(can) cur_angle = (cur_angle - degree) % 360 i = (i + 1) % len(self.fill_styles)
def draw(self, can=None): if can == None: can = canvas.default_canvas() x = self.loc[0] y = self.loc[1] text_width = font.text_width(self.text) text_height = font.text_height(self.text)[0] (halign, valign, angle) = font.get_align(self.text) if self.line_style or self.fill_style: width = text_width + self.left_fudge + self.right_fudge height = text_height + self.bottom_fudge + self.top_fudge can.round_rectangle(self.line_style, self.fill_style, x - self.left_fudge, y - self.bottom_fudge, x - self.left_fudge + width, y - self.bottom_fudge + height, self.radius, self.shadow) if halign == 'L': can.show(x, y, self.text) elif halign == 'C': can.show(x + text_width / 2.0, y, self.text) elif halign == 'R': can.show(x + text_width, y, self.text) else: raise Exception, "Unsupported alignment (" + halign + ")" # draw arrows for t in self._arrows: (tipLoc, tail, arrow) = t if tail: (x, y, width, height) = self.get_dimension() origin = [x, y] for ch in tail: if ch == 'l': origin[0] = x elif ch == 'c': origin[0] = x + width / 2.0 elif ch == 'r': origin[0] = x + width elif ch == 'b': origin[1] = y elif ch == 'm': origin[1] = y + height / 2.0 elif ch == 't': origin[1] = y + height else: raise ValueError, tail + ": unknown tail location spec." else: origin = self.choose_end_point(tipLoc[0], tipLoc[1]) arrow.draw((origin, tipLoc), can)
def draw(self, can = None): if can == None: can = canvas.default_canvas() x = self.loc[0] y = self.loc[1] text_width = font.text_width(self.text) text_height = font.text_height(self.text)[0] (halign, valign, angle) = font.get_align(self.text) if self.line_style or self.fill_style: width = text_width+self.left_fudge+self.right_fudge height = text_height+self.bottom_fudge+self.top_fudge can.round_rectangle(self.line_style, self.fill_style, x-self.left_fudge, y-self.bottom_fudge, x-self.left_fudge+width, y-self.bottom_fudge+height, self.radius, self.shadow) if halign == 'L': can.show(x, y, self.text) elif halign == 'C': can.show(x+text_width/2.0, y, self.text) elif halign == 'R': can.show(x+text_width, y, self.text) else: raise Exception, "Unsupported alignment (" + halign + ")" # draw arrows for t in self._arrows: (tipLoc, tail, arrow) = t if tail: (x, y, width, height) = self.get_dimension() origin = [x, y] for ch in tail: if ch == 'l': origin[0] = x elif ch == 'c': origin[0] = x+width/2.0 elif ch == 'r': origin[0] = x+width elif ch == 'b': origin[1] = y elif ch == 'm': origin[1] = y+height/2.0 elif ch == 't': origin[1] = y+height else: raise ValueError, tail + ": unknown tail location spec." else: origin = self.choose_end_point(tipLoc[0], tipLoc[1]) arrow.draw((origin, tipLoc), can)
def draw(self, ar, can): center = self.center if not center: center = (ar.loc[0] + ar.size[0]/2.0, ar.loc[1] + ar.size[1]/2.0) radius = self.radius if not radius: radius = min(ar.size[0]/2.0, ar.size[1]/2.0) * 0.5 label_offset = radius + (self.label_offset or radius * 0.1) total = self._total() i = 0 cur_angle = self.start_angle for val in self.data: fill = self.fill_styles[i] degree = 360 * float(val[self.data_col]) / float(total) off = (0, 0) if len(self.arc_offsets) > i: off = pychart_util.rotate(self.arc_offsets[i], 0, cur_angle - degree/2.0) x_center = center[0]+ off[0] y_center = center[1]+ off[1] can.ellipsis(self.line_style, fill, x_center, y_center, radius, 1, cur_angle - degree, cur_angle, self.shadow) label = pychart_util.apply_format(self.label_format, val, self.label_col) if label != None: (x_label, y_label) = pychart_util.rotate(label_offset, 0, cur_angle - degree/2.0) (x_arrowtip, y_arrowtip) = pychart_util.rotate(radius, 0, cur_angle - degree/2.0) # Labels on left side of pie need # their text to avoid obscuring the pie if x_label < 0: x_label = x_label - font.text_width(label) t = text_box.T(loc = (x_label + x_center, y_label + y_center), text = label, line_style = self.label_line_style, fill_style = self.label_fill_style) if self.arrow_style: t.add_arrow((x_arrowtip + x_center, y_arrowtip + y_center), None, self.arrow_style) t.draw(can) cur_angle = (cur_angle - degree) % 360 i = (i + 1) % len(self.fill_styles)
def draw(self, ar): self.type_check() self.tic_interval = self.tic_interval or ar.y_grid_interval x_base = ar.loc[0] + self.offset canvas.line(self.line_style, x_base, ar.loc[1], x_base, ar.loc[1]+ar.size[1]) xmin = x_base + ar.size[0] # somebigvalue tic_dic = {} for i in ar.y_tic_points(self.tic_interval): y_tic = ar.y_pos(i) tic_dic[i] = 1 canvas.line(self.line_style, x_base, y_tic, x_base - self.tic_len, y_tic) tic_label = pychart_util.apply_format(self.format, (i,), 0) x = x_base - self.tic_len + self.tic_label_offset[0] if self.tic_len > 0: tic_label = "/hR" + tic_label tic_height, base_height = font.text_height(tic_label) canvas.show(x, y_tic - tic_height/2.0 + self.tic_label_offset[1], tic_label) xmin = min(xmin, x - font.text_width(tic_label)) if self.minor_tic_interval: for i in ar.y_tic_points(self.minor_tic_interval): if tic_dic.has_key(i): # a major tic was drawn already. pass else: y_tic = ar.y_pos(i) canvas.line(self.line_style, x_base, y_tic, x_base - self.minor_tic_len, y_tic) if self.label != None: xlabel = xmin - theme.default_font_size/2.0 ylabel = ar.loc[1] + ar.size[1] / 2 if self.label_offset[0] != None: xlabel = xlabel + self.label_offset[0] if self.label_offset[1] != None: ylabel = ylabel + self.label_offset[1] canvas.show(xlabel, ylabel, "/a90/hC" + self.label)
def draw(self, ar): self.type_check() self.tic_interval = self.tic_interval or ar.y_grid_interval x_base = ar.loc[0] + self.offset canvas.line(self.line_style, x_base, ar.loc[1], x_base, ar.loc[1] + ar.size[1]) xmin = x_base + ar.size[0] # somebigvalue tic_dic = {} for i in ar.y_tic_points(self.tic_interval): y_tic = ar.y_pos(i) tic_dic[i] = 1 canvas.line(self.line_style, x_base, y_tic, x_base - self.tic_len, y_tic) tic_label = pychart_util.apply_format(self.format, (i, ), 0) x = x_base - self.tic_len + self.tic_label_offset[0] if self.tic_len > 0: tic_label = "/hR" + tic_label tic_height, base_height = font.text_height(tic_label) canvas.show(x, y_tic - tic_height / 2.0 + self.tic_label_offset[1], tic_label) xmin = min(xmin, x - font.text_width(tic_label)) if self.minor_tic_interval: for i in ar.y_tic_points(self.minor_tic_interval): if tic_dic.has_key(i): # a major tic was drawn already. pass else: y_tic = ar.y_pos(i) canvas.line(self.line_style, x_base, y_tic, x_base - self.minor_tic_len, y_tic) if self.label != None: xlabel = xmin - theme.default_font_size / 2.0 ylabel = ar.loc[1] + ar.size[1] / 2 if self.label_offset[0] != None: xlabel = xlabel + self.label_offset[0] if self.label_offset[1] != None: ylabel = ylabel + self.label_offset[1] canvas.show(xlabel, ylabel, "/a90/hC" + self.label)
def label_width(self): return font.text_width(" " + self.label)
def get_dimension(self): x = self.loc[0] - self.left_fudge y = self.loc[1] - self.bottom_fudge width = font.text_width(self.text) + self.right_fudge + self.left_fudge height = (font.text_height(self.text))[0] + self.top_fudge + self.bottom_fudge return (x, y, width, height)
def draw(self, can = None): if can == None: can = canvas.default_canvas() x = self.loc[0] y = self.loc[1] text_width = font.text_width(self.text) text_height = font.text_height(self.text)[0] (halign, valign, angle) = font.get_align(self.text) if self.line_style or self.fill_style: if self.callout == False: width = text_width+self.left_fudge+self.right_fudge height = text_height+self.bottom_fudge+self.top_fudge can.round_rectangle(self.line_style, self.fill_style, x-self.left_fudge, y-self.bottom_fudge, x-self.left_fudge+width, y-self.bottom_fudge+height, self.radius, self.shadow) else: width = text_width+self.left_fudge+self.right_fudge height = text_height+self.bottom_fudge+self.top_fudge cx = x + self.callout_shift cy = y csize = self.callout_size x1 = x-self.left_fudge y1 = y-self.bottom_fudge x2 = x-self.left_fudge+width y2 = y-self.bottom_fudge+height p0 = (cx,y1-csize) p1 = (cx-csize,y1) p2 = (cx+csize,y1) px0,py0 = p0 px1,py1 = p1 px2,py2 = p2 can.polygon(None, self.fill_style, [p0, p1, p2]) can.line(self.line_style, px0, py0, px1, py1) can.line(self.line_style, px0, py0, px2, py2) can.round_rectangle(None, self.fill_style, x-self.left_fudge, y-self.bottom_fudge, x-self.left_fudge+width, y-self.bottom_fudge+height, self.radius, self.shadow) can.line(self.line_style, x2, y1, x2, y2) can.line(self.line_style, x2, y2, x1, y2) can.line(self.line_style, x1, y2, x1, y1) can.line(self.line_style, x1, y1, px1, y1) can.line(self.line_style, px2, y1, x2, y1) if halign == 'L': can.show(x, y, self.text) elif halign == 'C': can.show(x+text_width/2.0, y, self.text) elif halign == 'R': can.show(x+text_width, y, self.text) else: raise Exception, "Unsupported alignment (" + halign + ")" # draw arrows for t in self._arrows: (tipLoc, tail, arrow) = t if tail: (x, y, width, height) = self.get_dimension() origin = [x, y] for ch in tail: if ch == 'l': origin[0] = x elif ch == 'c': origin[0] = x+width/2.0 elif ch == 'r': origin[0] = x+width elif ch == 'b': origin[1] = y elif ch == 'm': origin[1] = y+height/2.0 elif ch == 't': origin[1] = y+height else: raise ValueError, tail + ": unknown tail location spec." else: origin = self.choose_end_point(tipLoc[0], tipLoc[1]) arrow.draw((origin, tipLoc), can)