def createSmallArc(self, radius, a1, a2): a = (a2 - a1) / 2.0 x4 = radius * math.cos(a) y4 = radius * math.sin(a) x1 = x4 y1 = -y4 q1 = x1**2 + y1**2 q2 = q1 + x1*x4 + y1*y4 k2 = (4.0/3.0) * (math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4) x2 = x1 - k2 * y1 y2 = y1 + k2 * x1 x3 = x2 y3 = -y2 ar = a + a1 cos_ar = math.cos(ar) sin_ar = math.sin(ar) return { "p0": PDFCursor(self.center.x + (radius * math.cos(a1)), self.center.y - radius * math.sin(a1)), "p1": PDFCursor(self.center.x + (x2 * cos_ar - y2 * sin_ar), self.center.y - (x2 * sin_ar + y2 * cos_ar)), "p2": PDFCursor(self.center.x + (x3 * cos_ar - y3 * sin_ar), self.center.y - (x3 * sin_ar + y3 * cos_ar)), "p3": PDFCursor(self.center.x + (radius * math.cos(a2)), self.center.y - (radius * math.sin(a2))) }
def draw_tick(self, x1, y1, x2, y2): x = PDFCursor(x1, y1) y = PDFCursor(x2, y2) if self.axis: tick = PDFLine(self.session, self.page, x, y, self.base_color, "solid") tick._draw()
def _draw_legend_title(self, legend_title="Legend"): text_width = self.session.parent.document.font._string_width(legend_title) text_height = self.session.parent.document.font.font_size text_cursor = PDFCursor(self.legend_start_cursor.x + (self.legend_width - text_width) / 2.0, self.legend_start_cursor.y + 1.2 * text_height) legend_title = PDFText(self.session, self.page, "Legend", cursor=text_cursor) self.legend_data_start = PDFCursor(self.legend_start_cursor.x + 10, self.legend_start_cursor.y + 3 * text_height)
def draw_axis_titles(self, x_title=None, y_title=None): if x_title is not None: label_cursor_x = PDFCursor(self.origin.x + (self.width - self.padding[0])/ 2.0, self.origin.y + 0.8 * self.padding[1]) PDFText(self.session, self.page, x_title, cursor=label_cursor_x) if y_title is not None: if self.padding[0] == 0: self.padding = (self.width * 0.12, self.padding[1]) label_cursor_y = PDFCursor(self.origin.x - 0.8 * self.padding[0], self.origin.y - (self.height / 2.0) - 0.8 * self.padding[1]) text = PDFText(self.session, self.page, None, cursor=label_cursor_y) text.text_rotate(-90) text._text(y_title)
def draw_bars(self): x_space = int(self.bar_padding * self.x_delta) i = 0 for pair in self.data: draw, fill = self._get_colors(i) cursor1 = PDFCursor(self.x_array[i][1] + x_space, self.interpolate(pair[1], self.y_array)) cursor2 = PDFCursor(self.x_array[i][1] + self.x_delta - x_space, self.origin.y) rect = PDFRectangle(self.session, self.page, cursor1, cursor2, draw, fill, self.bar_style, "solid") rect._draw() i += 1
def get_cursors(self, cursors): xlist = [i.x for i in cursors] ylist = [i.y for i in cursors] min_x = min(xlist) min_y = min(ylist) max_x = max(xlist) max_y = max(ylist) x_sum = 0 y_sum = 0 xy_sum = 0 x2_sum = 0 y2_sum = 0 N = 0 for cursor in cursors: x = cursor.x y = cursor.y x_sum += x y_sum += y xy_sum += x * y x2_sum += x**2 y2_sum += y**2 N += 1 self.cursor_slope = ((N * xy_sum) - (x_sum * y_sum)) / ((N * x2_sum) - (x_sum**2)) self.cursor_intercept = ((x2_sum * y_sum) - (x_sum * xy_sum)) / ((N * x2_sum) - (x_sum**2)) x1 = 0 y1 = 0 if self.cursor_intercept < min_y: y1 = min_y x1 = self._get_x_at_y(y1) if self.cursor_intercept >= min_y: x1 = min_x y1 = self._get_y_at_x(x1) x2 = max_x y2 = self._get_y_at_x(x2) if y2 > max_y: y2 = max_y x2 = self._get_x_at_y(y2) return PDFCursor(x1, y1), PDFCursor(x2, y2)
def draw_y_axis(self, zero=True): # Draw y axis ticks self.y_array = [(self.y_range[0], self.origin.y)] try: y_delta = self.height / (float(self.y_range[1] - self.y_range[0]) / float(self.frequency[1])) except ZeroDivisionError: y_delta = self.height / 2.0 x_delta = 3 tick_y = self.origin.y j = self.y_range[0] k = 0 self.draw_tick(self.origin.x, tick_y, self.origin.x - x_delta, tick_y) if zero: self.draw_y_label(j, k, self.origin.x - x_delta, tick_y) while j < self.y_range[1]: j += self.frequency[1] tick_y -= y_delta self.y_array.append((j, tick_y)) self.draw_tick(self.origin.x, tick_y, self.origin.x - x_delta, tick_y) self.draw_y_label(j, k, self.origin.x - x_delta, tick_y) k += 1 # Draw axis lines cursor1 = PDFCursor(self.origin.x, tick_y) if self.axis: yaxis = PDFLine(self.session, self.page, cursor1, self.origin, self.base_color, stroke="solid") yaxis._draw()
def _draw_title(self): if self.title is not None: save_font = self.font self.session.parent.document.set_font(save_font.family, "b", save_font.font_size * 1.2) title_cursor = PDFCursor(self.origin.x + (self.width - self.session.parent.document.font._string_width(self.title))/ 2.0, self.origin.y - self.height - (self.padding[1] * 0.4)) title = PDFText(self.session, self.page, self.title, cursor=title_cursor, color=self.base_color) self.session.parent.document.set_font(font=save_font)
def draw_x_axis(self, zero=True): # Draw x axis ticks self.x_array = [(0, self.origin.x)] try: x_delta = self.width / (float(self.x_range[1] - self.x_range[0]) / float(self.frequency[0])) except ZeroDivisionError: x_delta = self.width / 2.0 self.x_delta = x_delta y_delta = 3 tick_x = self.origin.x i = self.x_range[0] k = 0 self.draw_tick(tick_x, self.origin.y, tick_x, self.origin.y + y_delta) if zero: self.draw_x_label(i, k, tick_x, self.origin.y) while i < self.x_range[1]: i += self.frequency[0] tick_x += x_delta self.x_array.append((i, tick_x)) self.draw_tick(tick_x, self.origin.y, tick_x, self.origin.y + y_delta) self.draw_x_label(i, k, tick_x, self.origin.y) k += 1 cursor2 = PDFCursor(tick_x, self.origin.y) if self.axis: xaxis = PDFLine(self.session, self.page, self.origin, cursor2, self.base_color, stroke="solid") xaxis._draw()
def __init__(self, orientation="P", layout="letter", margin=None): # Additional layout sizes may be added to this dictionary. # Width then height, in pixels, in portrait orientation. self.layout_dict = {'a3': (841.89, 1190.55), 'a4': (595.28, 841.89), 'a5': (420.94, 595.28), 'letter': (612, 792), 'legal': (612, 1008), '11x17': (792, 1224) } self.set_page_size(layout) # "P" or "L" self.orientation = orientation # Each page has a cursor. self.cursor = PDFCursor() # Initialize the Page Margin. self.margin = margin self.set_orientation(orientation) self.set_margins(margin) self.orientation_change = False self.buffer = ""
def _draw_dots(self, cursors): if self.dots is not None: for cursor in cursors: dot = PDFEllipse(self.session, self.page, cursor, PDFCursor(self.dots, self.dots), style="F") dot._draw()
def _draw_legend_box(self): end_cursor = PDFCursor( self.legend_start_cursor.x + self.legend_width, self.legend_data_start.y + 1.2 * self.session.parent.document.font.font_size) legend_box = PDFRectangle(self.session, self.page, self.legend_start_cursor, end_cursor, self.base_color) legend_box._draw()
def draw_y_label(self, i, k, x1, y1): if self.axis_labels is None: return elif self.axis_labels is "Auto": text = i else: text = self.axis_labels["y"][k] cursor = PDFCursor(x1 - self.font._string_width(text) - 1, y1 + 2) label = PDFText(self.session, self.page, '%s' % text, cursor=cursor)
def _draw_legend_line(self, index, series_name): end = PDFCursor(self.legend_data_start.x + 10, self.legend_data_start.y + 10) box = PDFRectangle(self.session, self.page, self.legend_data_start, end, None, self.fill_colors[index], style="F", stroke="solid") box._draw() end.x_plus(10) text = PDFText(self.session, self.page, series_name, cursor=end, color=self.base_color) w = end.x + 4 if w > self.max_x: self.max_x = w self.legend_data_start.y_plus(1.75 * self._legend_line_height)
def draw_bars(self): x_space = int(self.bar_padding * self.x_delta) sub_array = [] for x in self.x_array: sub_array.append((x[0], x[1] + x_space)) self.new_x_array = [sub_array] new_x_delta = self.x_delta / float(len(self.data)) for series in range(1, len(self.data)): sub_array = [] for pair in self.x_array: sub_array.append((pair[0], pair[1] + new_x_delta)) self.new_x_array.append(sub_array) if self.legend is not None: self._legend_line_height = self.session.parent.document.font.font_size self.legend_start_cursor.x_plus(-self.padding[0] * 0.5) self.legend_width += self.padding[0] * 0.55 self._draw_legend_title() j = 0 for series in self.data: values_list = series.values()[0] draw, fill = self._get_colors(j) if self.legend is not None: self._draw_legend_line(j, series.keys()[0]) i = 0 for pair in values_list: cursor1 = PDFCursor(self.new_x_array[j][i][1], self.interpolate(pair[1], self.y_array)) cursor2 = PDFCursor( self.new_x_array[j][i][1] + new_x_delta - x_space, self.origin.y) rect = PDFRectangle(self.session, self.page, cursor1, cursor2, draw, fill, self.bar_style, "solid") rect._draw() i += 1 j += 1 if self.legend is not None: self._draw_legend_box()
def _draw_background(self, width, height): if self.background.exists: cursor_end = PDFCursor(self.origin.x + width, self.origin.y + height) rectangle = PDFRectangle(self.session, self.page, self.origin, cursor_end, self.background.border_color, self.background.fill_color, self.background.style, self.background.stroke, self.background.size) rectangle._draw()
def _pad(self, width, height): self.origin.x_plus(self.padding[0]) self.origin.y_plus(-self.padding[1] + height) if self.legend == "right": self.width = (0.8 * width) - (2 * self.padding[0]) self.legend_width = 0.2 * width - (self.padding[0] * 0.2) self.height = height - 2 * self.padding[1] self.legend_height = self.height self.legend_start_cursor = PDFCursor(self.origin.x + self.width + self.padding[0], self.origin.y - self.height) else: self.width = width - 2 * self.padding[0] self.height = height - 2 * self.padding[1]
def _draw_legend_line(self, index, series_name): line_height = self.session.parent.document.font.font_size end = PDFCursor(self.legend_data_start.x + 15, self.legend_data_start.y) line = PDFLine(self.session, self.page, self.legend_data_start, end, color=self.line_colors[index]) line._draw() end.x_plus(10) end.y_plus(0.25 * line_height) text = PDFText(self.session, self.page, series_name, cursor=end) self.legend_data_start.y_plus(1.75 * line_height)
def draw_data(self): if self.legend is not None: self._draw_legend_title() i = 0 for series in self.data: if self.legend is not None: self._draw_legend_line(i, series.keys()[0]) series = series.values()[0] self._set_color(i) self.line = LinearRegressionLine() i += 1 cursors = [] for value in series: cursor = self.get_coord(value) cursors.append(cursor) self.line.add_data(value) self._draw_dots(cursors) if self.linear_regression: self.line.calculate_line() cursor1, cursor2 = self.line.get_cursors(cursors) trend = PDFLine(self.session, self.page, cursor1, cursor2) trend._draw() if self.linear_regression_equation: text = self.line.get_equation() text_width = self.session.parent.document.font._string_width( text) text_height = self.session.parent.document.font.font_size * 1.2 x = cursor2.x + (-text_width) y = self.line._get_y_at_x(x) + text_height PDFText(self.session, self.page, text, cursor=PDFCursor(x, y)) if self.legend is not None: self._draw_legend_box()
def draw_base_circle(self): circle = PDFEllipse(self.session, self.page, self.center_cursor, PDFCursor(self.radius, self.radius), self.base_color, None, style="S", stroke="solid", size=1) circle._draw()
def _set_center(self): self.center_cursor = PDFCursor(self.origin.x + self.width / 2.0, self.origin.y - self.height / 2.0) self.radius = min(self.width, self.height) / 2.0
def get_coord(self, tuple): x = self.interpolate(tuple[0], self.x_array) y = self.interpolate(tuple[1], self.y_array) return PDFCursor(x, y)
def draw_x_label(self, i, k, x1, y1): text = self.data[k][0] cursor = PDFCursor( x1 - (self.x_delta + self.font._string_width(text)) / 2.0, y1 + 9) label = PDFText(self.session, self.page, '%s' % text, cursor=cursor)