def connect_line(self, cr: cairo.Context, x0, y0): cr.set_source_rgb(*colors[1]) cr.set_line_width(9e-3) cr.move_to(x0, y0) cr.line_to(*self.mousePos) cr.stroke() cr.stroke()
def draw(self, cr: cairo.Context) -> None: line = self._line stroke_color = self._stroke_color stroke_width = self._stroke_width scale_strokes = self._scale_strokes if line is None: return if line.pt0 == line.pt1: return clip_extents = Rect2(cr.clip_extents()) start = line.eval(x=clip_extents.x0) end = line.eval(x=clip_extents.x1) if not clip_extents.contains(start): start = line.eval(y=clip_extents.y0 if start.y < clip_extents.y0 else clip_extents.y1) if not clip_extents.contains(end): end = line.eval(y=clip_extents. y0 if end.y < clip_extents.y0 else clip_extents.y1) cr.move_to(*start) cr.line_to(*end) cr.save() if scale_strokes: cr.identity_matrix() cr.set_source_rgb(*stroke_color) cr.set_line_width(stroke_width) cr.stroke() cr.restore()
def draw_polyline(context: cairo.Context, polyline: symbols.Polyline) -> None: """draw a polyline""" if not polyline.lines: return # The gotchas for animation and joints will be handled by polyline_frac, not this. context.set_line_width(polyline.thickness) _set_color(context, polyline.color) if polyline.joint_type != '': context.set_line_join(polyline.joint_type) context.move_to(polyline.lines[0].start[0], polyline.lines[0].start[1]) if polyline.closed: for line in polyline.lines[:-1]: context.line_to(line.end[0], line.end[1]) context.close_path() else: for line in polyline.lines: context.line_to(line.end[0], line.end[1]) context.stroke()
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None): from cairo import SVGSurface, Context from numpy import array from ddd import spatial_sort_2d as sort if not scale_factor: scale_factor = size one = 1.0/size s = SVGSurface(fn, size, size) c = Context(s) c.set_line_width(0.1) paths = sort(paths) for path in paths: path *= scale_factor c.new_path() c.move_to(*path[0,:]) for p in path[1:]: c.line_to(*p) c.stroke() c.save()
def draw_base(self, cr: cairo.Context): cr.identity_matrix() cr.set_matrix(self.matrix) cr.rectangle(-1, -1, 2, 2) cr.set_source_rgb(*colors[0]) cr.fill() if self.gtk_mode: cr.rectangle(-1, .65, .15, .35) cr.set_source_rgb(*colors[1]) cr.fill() cr.set_source_rgb(*colors[1]) cr.set_line_width(9e-3) cr.arc(0, 0, self.radius, 0, 2 * PI) # cr.stroke() for theta in np.linspace(0, 2 * PI, self.radio_button + 1): cr.move_to(0, 0) x, y = self.radius * np.cos(theta), self.radius * np.sin(theta) cr.line_to(x, y) if (x, y) not in self.inter_sections: self.inter_sections.append((x, y)) cr.stroke()
def draw_precip_curve( self, context: cairo.Context, points: List[Tuple[int, int]], bottom: int, color, curviness: float = 7, ): # Draw the top curves for i, point in enumerate(points): if i == 0: context.move_to(*point) else: last_point = points[i - 1] context.curve_to( last_point[0] + curviness, last_point[1], point[0] - curviness, point[1], point[0], point[1], ) # Draw the rest and fill context.line_to(points[-1][0], bottom) context.line_to(points[0][0], bottom) context.close_path() context.set_source_rgb(*color) context.fill()
def _draw_cell(self, context: cairo.Context, cell_value: CrucipixelCellValue, area: Rectangle): r, g, b = self.crucipixel_cell_value_to_color[cell_value] context.set_source_rgb(r, g, b) context.rectangle(area.start.x, area.start.y, area.width, area.height) context.fill() if not self.victory_screen and cell_value == CrucipixelCellValue.EMPTY: # draw the X r, g, b = self.crucipixel_cell_value_to_color[ CrucipixelCellValue.SELECTED ] context.set_source_rgb(r, g, b) context.set_line_cap(cairo.LINE_CAP_ROUND) delta_x = self.cell_width // 2.8 delta_y = self.cell_height // 2.8 context.move_to(area.start.x + area.width - delta_x, area.start.y + delta_y) context.line_to(area.start.x + delta_x, area.start.y + area.height - delta_y) context.move_to(area.start.x + area.width - delta_x, area.start.y + area.width - delta_y) context.line_to(area.start.x + delta_x, area.start.y + delta_y) context.stroke()
def bezier(self, cr: cairo.Context, x0, y0, x1, y1, x2, y2, x3, y3): mesh_f = 35 cr.set_line_width(0.5e-2) p = [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] cr.move_to(*p[0]) cr.curve_to(*p[1], *p[2], *p[3]) cr.stroke() # cr.move_to(*p[0]) # # for j in p[1:]: # cr.line_to(*j) # cr.stroke() l = [] for i in range(len(p) - 1): lx = np.linspace(p[i][0], p[i + 1][0], mesh_f) ly = np.linspace(p[i][1], p[i + 1][1], mesh_f) l.append([lx, ly]) cr.set_line_width(0.5e-3) for l1, l2 in zip(l[:-1], l[1:]): for ix, iy, jx, jy in zip(l1[0], l1[1], l2[0], l2[1]): cr.move_to(ix, iy) cr.line_to(jx, jy) cr.stroke()
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None): from cairo import SVGSurface, Context from .ddd import spatial_sort_2d as sort if not scale_factor: scale_factor = size s = SVGSurface(fn, size, size) c = Context(s) c.set_line_width(0.1) paths = sort(paths) for path in paths: path *= scale_factor c.new_path() c.move_to(*path[0, :]) for p in path[1:]: c.line_to(*p) c.stroke() c.save()
def draw(self, cr: cairo.Context, drawing_options: DrawingOptions): cr.set_source_rgb(*drawing_options.sleeper_color) # The half-sleepers at either end cr.set_line_width(1) cr.move_to(0.5, -4) cr.line_to(0.5, 4) cr.move_to(self.length - 0.5, -4) cr.line_to(self.length - 0.5, 4) cr.stroke() # The sleepers in between cr.set_line_width(2) for x in range(4, int(self.length), 4): cr.move_to(x, -4) cr.line_to(x, 4) cr.stroke() cr.set_source_rgb(*drawing_options.rail_color) cr.set_line_width(1) cr.move_to(0, -2.5) cr.line_to(self.length, -2.5) cr.move_to(0, 2.5) cr.line_to(self.length, 2.5) cr.stroke()
def draw_line(context: cairo.Context, line: symbols.Line) -> None: """draw a line""" context.set_line_width(line.thickness) _set_color(context, line.color) context.move_to(line.start[0], line.start[1]) context.line_to(line.end[0], line.end[1]) context.stroke()
def draw_trains(self, layout: Layout, cr: Context): for train in layout.trains.values(): car_start = train.position annotation = train.meta.get("annotation") for i, car in enumerate(train.cars): front_bogey_offset, rear_bogey_offset = car.bogey_offsets bogey_spacing = rear_bogey_offset - front_bogey_offset front_bogey_position = car_start - front_bogey_offset front_bogey_xy = self.transform_track_point(front_bogey_position) rear_bogey_position, rear_bogey_xy = self.point_back( front_bogey_position, bogey_spacing ) cr.save() cr.translate(front_bogey_xy[0], front_bogey_xy[1]) cr.rotate( math.pi + math.atan2( front_bogey_xy[1] - rear_bogey_xy[1], front_bogey_xy[0] - rear_bogey_xy[0], ) ) cr.set_source_rgb(*hex_to_rgb(train.meta.get("color", "#a0a0ff"))) if i == 0 and annotation: cr.move_to(0, -10) cr.set_font_size(5) cr.show_text(annotation) cr.set_line_width(4) cr.move_to(-front_bogey_offset, 0) cr.line_to(car.length - front_bogey_offset, 0) cr.stroke() cr.set_line_width(6) cr.move_to(1 - front_bogey_offset, 0) cr.line_to(car.length - front_bogey_offset - 1, 0) cr.stroke() if i == 0 and train.lights_on: cr.set_source_rgba(1, 1, 0.2, 0.5) for y in (-2.5, 2.5): cr.move_to(-front_bogey_offset - 1, y) cr.arc( -front_bogey_offset - 1, y, 10, 6 / 7 * math.pi, math.pi * 8 / 7, ) cr.close_path() cr.fill() cr.restore() car_start = rear_bogey_position - (car.length - rear_bogey_offset + 1)
def draw_router_transmission(args, ld: Path, area, r, ctx: cairo.Context): ctx.rectangle(0, 0, area.x, area.y) ctx.set_source_rgba(*color_db(args)) ctx.fill() # transmitting circles for router in r: if not router.mm.visible: continue x, y = router.coordinates() if router.transmission_within_second: distance = \ max(router.interfaces.values(), key=lambda x: x['range'])[ 'range'] ctx.set_source_rgba(*color_transmission_circle(args)) ctx.move_to(x, y) ctx.arc(x, y, distance, 0, 2 * math.pi) ctx.fill() for router in r: if not router.mm.visible: continue x, y = router.coordinates() ctx.set_line_width(0.1) path_thickness = 6.0 # iterate over links for i, interface_name in enumerate(router.interfaces): range_ = router.interfaces[interface_name]['range'] # draw lines between links ctx.set_line_width(path_thickness) for r_id, r_obj in router.connections[interface_name].items(): if not r_obj.mm.visible: continue other_x, other_y = r_obj.coordinates() ctx.move_to(x, y) ctx.set_source_rgba(*color_tx_links(args)) ctx.line_to(other_x, other_y) ctx.stroke() path_thickness -= 4.0 if path_thickness < 2.0: path_thickness = 2.0 # draw dots over all for router in r: if not router.mm.visible: continue x, y = router.coordinates() ctx.set_line_width(0.0) ctx.set_source_rgba(*color_tx_links(args)) ctx.move_to(x, y) ctx.arc(x, y, 5, 0, 2 * math.pi) ctx.fill()
def draw_poly(poly: RegularPolygon, ctx: cairo.Context): ctx.save() v = poly.vertices() ctx.move_to(v[0][0], v[0][1]) for i in range(1, len(v)): ctx.line_to(v[i][0], v[i][1]) ctx.close_path() ctx.stroke() ctx.restore()
class Canvas: def __init__(self, width, height): self.xform = lambda x, y: (x, y) self.img = ImageSurface(FORMAT_RGB24, width, height) self.ctx = Context(self.img) self.ctx.move_to(0, 0) self.ctx.line_to(width, 0) self.ctx.line_to(width, height) self.ctx.line_to(0, height) self.ctx.line_to(0, 0) self.ctx.set_source_rgb(1, 1, 1) self.ctx.fill() self.width = width self.height = height def fit(self, left, top, right, bottom): xoff = left yoff = top xscale = self.width / float(right - left) yscale = self.height / float(bottom - top) if abs(xscale) > abs(yscale): xscale *= abs(yscale) / abs(xscale) elif abs(xscale) < abs(yscale): yscale *= abs(xscale) / abs(yscale) self.xform = lambda x, y: ((x - xoff) * xscale, (y - yoff) * yscale) def dot(self, x, y, size=4, fill=(.5, .5, .5)): x, y = self.xform(x, y) self.ctx.arc(x, y, size/2., 0, 2*pi) self.ctx.set_source_rgb(*fill) self.ctx.fill() def line(self, points, stroke=(.5, .5, .5), width=1): self.ctx.move_to(*self.xform(*points[0])) for (x, y) in points[1:]: self.ctx.line_to(*self.xform(x, y)) self.ctx.set_source_rgb(*stroke) self.ctx.set_line_cap(LINE_CAP_ROUND) self.ctx.set_line_width(width) self.ctx.stroke() def save(self, filename): self.img.write_to_png(filename)
class Canvas: def __init__(self, width, height): self.xform = lambda x, y: (x, y) self.img = ImageSurface(FORMAT_RGB24, width, height) self.ctx = Context(self.img) self.ctx.move_to(0, 0) self.ctx.line_to(width, 0) self.ctx.line_to(width, height) self.ctx.line_to(0, height) self.ctx.line_to(0, 0) self.ctx.set_source_rgb(1, 1, 1) self.ctx.fill() self.width = width self.height = height def fit(self, left, top, right, bottom): xoff = left yoff = top xscale = self.width / float(right - left) yscale = self.height / float(bottom - top) if abs(xscale) > abs(yscale): xscale *= abs(yscale) / abs(xscale) elif abs(xscale) < abs(yscale): yscale *= abs(xscale) / abs(yscale) self.xform = lambda x, y: ((x - xoff) * xscale, (y - yoff) * yscale) def dot(self, x, y, size=4, fill=(.5, .5, .5)): x, y = self.xform(x, y) self.ctx.arc(x, y, size / 2., 0, 2 * pi) self.ctx.set_source_rgb(*fill) self.ctx.fill() def line(self, points, stroke=(.5, .5, .5), width=1): self.ctx.move_to(*self.xform(*points[0])) for (x, y) in points[1:]: self.ctx.line_to(*self.xform(x, y)) self.ctx.set_source_rgb(*stroke) self.ctx.set_line_cap(LINE_CAP_ROUND) self.ctx.set_line_width(width) self.ctx.stroke() def save(self, filename): self.img.write_to_png(filename)
def draw_dodecahedron( ctx: cairo.Context, rng: Generator, pos_x: float, pos_y: float, radius: float, rotation: float = 0, ): # Outer boundary outer_points = list( points_along_arc(pos_x, pos_y, radius, rotation, rotation + tau, 10)) for prev_index, (bx, by) in enumerate(outer_points, -1): ax, ay = outer_points[prev_index] ctx.move_to(ax, ay) ctx.line_to(bx, by) ctx.stroke() # Frontside inner pentagon inner_fs_points = list( points_along_arc(pos_x, pos_y, 0.6 * radius, rotation, rotation + tau, 5)) for prev_index, (bx, by) in enumerate(inner_fs_points, -1): ax, ay = inner_fs_points[prev_index] ctx.move_to(ax, ay) ctx.line_to(bx, by) ctx.stroke() # Outer to frontside inner for (ax, ay), (bx, by) in zip(inner_fs_points, outer_points[::2]): ctx.move_to(ax, ay) ctx.line_to(bx, by) ctx.stroke() # backside inner pentagon offset = pi / 5 inner_bs_points = list( points_along_arc( pos_x, pos_y, 0.6 * radius, rotation + offset, rotation + offset + tau, 5, )) for prev_index, (bx, by) in enumerate(inner_bs_points, -1): ax, ay = inner_bs_points[prev_index] ctx.move_to(ax, ay) ctx.line_to(bx, by) ctx.stroke() # Outer to backside inner for (ax, ay), (bx, by) in zip(inner_bs_points, outer_points[1::2]): ctx.move_to(ax, ay) ctx.line_to(bx, by) ctx.stroke()
def draw(self, cr: cairo.Context, vp_matrix: np.ndarray): for i in range(len(self.normalized_vertices)): proximo_vp = self.normalized_vertices[i] @ vp_matrix cr.line_to(proximo_vp.x, proximo_vp.y) cr.close_path() if self.filled: cr.stroke_preserve() cr.fill() else: cr.stroke()
def draw(self, cr: Context, vp_matrix: np.ndarray): for v in self.vertices_ndc: next_vp = v @ vp_matrix cr.line_to(next_vp.x, next_vp.y) cr.close_path() if self.filled: cr.stroke_preserve() cr.fill() else: cr.stroke()
def draw_line_grid(self, cr: cairo.Context): cr.set_source_rgb(*colors[0]) cr.set_line_width(1e-3) for x in range(1, self.box_number[0]): nx = (self.box_size[0] * x) / self.width cr.move_to(nx, 1) cr.line_to(nx, -1) for y in range(1, self.box_number[1]): ny = (self.box_size[0] * y) / self.height cr.move_to(-1, ny) cr.line_to(1, ny) cr.stroke()
def _polygon(self, ctx: cairo.Context, points, color, outline=None): ctx.new_path() for point in points: ctx.line_to(*point) ctx.close_path() ctx.set_source_rgba(*color) if outline is not None: ctx.fill_preserve() ctx.set_source_rgba(*outline) ctx.set_line_width(1) ctx.stroke() else: ctx.fill()
def _show_polyline(self, cr: cairo.Context, polyline: _PointSequence) -> None: if len(polyline) <= 1: return polyline = cv2.approxPolyDP(np.asarray(polyline, dtype=np.float32), epsilon=0.5, closed=False).reshape(-1, 2) points_it = iter(polyline) cr.move_to(*next(points_it)) for point in points_it: cr.line_to(*point)
def draw_highlight(self, _area: Gtk.DrawingArea, context: Context) -> None: if self.current_region and self.t: poly: Polygon = self.current_region.poly poly = poly.buffer(1, single_sided=True) # TODO: 239, 134, 97, 0.7 taken from gtk.css, possible to get it from os???? context.set_source_rgba(239 / 255.0, 134 / 255.0, 97 / 255.0, 0.7) context.set_line_width( clamp(self.configurators['scale'].get_exp() * 12, 0.5, 5)) context.new_path() # Nice idea, but didnt work with scrolling: context.set_matrix(Matrix(1.0/self.t.scale, 0, 0, 1.0/self.t.scale, -self.t.tx, -self.t.ty)) for coord in poly.exterior.coords: context.line_to(*self.t.inverse(*coord)) context.close_path() context.stroke()
def draw(self, cr: Context, vp_matrix: np.ndarray): _min = self.min _max = self.max cr.move_to(_min.x, _min.y) for x, y in [ (_max.x, _min.y), (_max.x, _max.y), (_min.x, _max.y), (_min.x, _min.y), ]: cr.line_to(x, y) cr.move_to(x, y) cr.stroke()
def draw(self, cr: cairo.Context) -> None: line = self._line if line is None: return viewport_extents = self._parent.props.viewport_extents p0 = line.p0 p1 = line.p1 if p0 == p1: return start_point = line.eval_at(x=viewport_extents.x0) end_point = line.eval_at(x=viewport_extents.x1) if not viewport_extents.contains_point(start_point): if start_point.y < viewport_extents.y0: y_to_eval = viewport_extents.y0 else: y_to_eval = viewport_extents.y1 start_point = line.eval_at(y=y_to_eval) if not viewport_extents.contains_point(end_point): if end_point.y < viewport_extents.y0: y_to_eval = viewport_extents.y0 else: y_to_eval = viewport_extents.y1 end_point = line.eval_at(y=y_to_eval) p0, p1, start_point, end_point = map(self._parent._widget_coord_from_canvas, (p0, p1, start_point, end_point)) cr.move_to(*start_point) cr.line_to(*end_point) stroke_width = self.props.stroke_width stroke_color = self.props.stroke_color cr.set_line_width(stroke_width) cr.set_source_rgb(*stroke_color) # red, green, blue cr.stroke() # Draw the control points of the line. if self.props.draw_control_points: cr.arc(*p0, stroke_width*2, 0, 2*math.pi) cr.close_path() cr.arc(*p1, stroke_width*2, 0, 2*math.pi) cr.close_path() cr.fill()
def on_draw(self, wd, cr: cairo.Context): cr.identity_matrix() mat = cairo.Matrix(self.width, 0, 0, -self.height, self.width / 2, self.height / 2) cr.set_matrix(mat) cr.rectangle(-1, -1, 3, 2) cr.set_source_rgb(*colors[0]) cr.fill() cr.set_source_rgb(*colors[1]) cr.set_line_width(5e-3) cr.move_to(0, 0) cr.line_to(1, 1) cr.stroke()
def paint_foreground(self, ctx: Context): ctx.set_source_rgba(*Color.GRAY40) rect = Rectangle(ZERO_TOP_LEFT, self.size) center = rect.position(Anchor.CENTER_CENTER) r = min(*self.size) / 2 ctx.move_to(center.x, center.y) φ = 2 * math.pi * datetime.now().microsecond / 1000000 ctx.arc(*center, r, -math.pi / 2, φ - math.pi / 2) ctx.line_to(center.x, center.y) ctx.fill() ctx.move_to(center.x, center.y) ctx.line_to(center.x + r * math.sin(φ), center.y - r * math.cos(φ)) ctx.set_line_width(2) ctx.set_source_rgba(*Color.WHITE) ctx.stroke()
def draw_grid(self, cr: Context): cr.set_line_width(1 / self.drawing_options.scale) for x in range(-10, 10): v = 0.7 if (x % 3) == 0 else 0.8 cr.set_source_rgba(v, v, v, 0.4) cr.move_to(x * 32, -320) cr.line_to(x * 32, 320) cr.stroke() for y in range(-10, 10): v = 0.7 if (y % 3) == 0 else 0.8 cr.set_source_rgba(v, v, v, 0.4) cr.move_to(-320, y * 32) cr.line_to(320, y * 32) cr.stroke()
def turtle(self, cr: cairo.Context, command, theta, delta=1.0): cr.move_to(self.x, self.y) if command == 'A': angles = [i * self.angle for i in reversed(range(-1, 2))] else: angles = [i * self.angle for i in range(-1, 2)] for a in angles: ca = self.length * cos(a) t = (theta > 0) - (theta < 0) p1 = self.length * exp(1j * (a + theta)) p0 = ca * exp(1j * (theta)) px = self.x + ((p1 - p0) * delta + p0).real py = self.y + ((p1 - p0) * delta + p0).imag cr.line_to(px, py) self.x, self.y = px, py
def _draw_path(self, cr: cairo.Context, polyline: PolylineType) -> None: if len(polyline) <= 1: return if len(polyline) > self._APPROX_MAX_POINTS: polyline_reduced = itertools.islice( polyline, 0, None, len(polyline) // self._APPROX_MAX_POINTS) polyline = itertools.chain(polyline_reduced, [polyline[-1]]) points = iter(polyline) cr.move_to(*next(points)) for point in points: cr.line_to(*point)
def draw_grid(ctx: cairo.Context, width: float, height: float, rows: int, cols: int): rowheight = height // rows colwidth = width // cols with cairoctx.source(ctx, Color(0.5, 0.5, 0.5).to_pattern()): for col in range(1, cols + 1): x = col * colwidth ctx.move_to(x, 0) ctx.line_to(x, height) ctx.stroke() for row in range(1, rows + 1): y = row * rowheight ctx.move_to(0, y) ctx.line_to(width, y) ctx.stroke()
def on_draw(self, widget: Widget, context: cairo.Context): self.set_shape_from_context(context) shape = self.shape context.set_line_width(self.line_thickness) if self.orientation == Orientation.HORIZONTAL: context.move_to(shape.start.x - self.line_extension, shape.start.y) context.line_to(shape.start.x + shape.width, shape.start.y) else: context.move_to(shape.start.x, shape.start.y - self.line_extension) context.line_to(shape.start.x, shape.start.y + shape.height) context.stroke() for element in self._elements: context.move_to(*element.position) context.set_source_rgb(*element.color) context.show_text(element.label)
def export_svg(fn, paths, w, h, line_width=0.1): from cairo import SVGSurface, Context s = SVGSurface(fn, w, h) c = Context(s) c.set_line_width(line_width) for path in paths: c.new_path() c.move_to(*path[0, :]) for p in path[1:]: c.line_to(*p) c.stroke() c.save()
def export_svg(fn, paths, w, h, line_width=0.1): from cairo import SVGSurface, Context s = SVGSurface(fn, w, h) c = Context(s) c.set_line_width(line_width) for path in paths: c.new_path() c.move_to(*path[0,:]) for p in path[1:]: c.line_to(*p) c.stroke() c.save()
def on_draw(self, widget: Widget, context: cairo.Context): max_height = 0 max_width = 0 for line in self._lines: line.set_shape_from_context(context) max_height = max(max_height, line.shape.height) max_width = max(max_width, line.shape.width) offset = 0 if self._orientation == Orientation.HORIZONTAL: def handle_line(line: _GuideLine): nonlocal offset line.line_extension = max_height - line.shape.height line.set_translate(offset, 0) offset += line.shape.width else: def handle_line(line: _GuideLine): nonlocal offset line.line_extension = max_width - line.shape.width line.set_translate(0, offset) offset += line.shape.height for line in self._lines: handle_line(line) super().on_draw(self, context) context.set_line_width(self.THICK_LINE) if self._orientation == Orientation.HORIZONTAL: context.move_to(offset, 0) context.line_to(offset, -max_height) else: context.move_to(0, offset) context.line_to(-max_width, offset) context.stroke()
def _paint_panel(self, key, width, height, panel_h): self.db.IUD("update web_stat_panels set HEIGHT = %s where ID = %s" % (panel_h, key)) self.db.commit() color_x_line = (0.7, 0.7, 0.7) color_x_line_2 = (0.9, 0.9, 0.9) color_y_line = (0.9, 0.9, 0.9) color_y_line_date = (0.7, 0.7, 0.7) color_border = (0.5, 0.5, 0.5) left = 40 right = 10 bottom = 15 var_ids = "0" series = [0, 0, 0, 0] typ = 0 for row in self.db.select( "select SERIES_1, SERIES_2, SERIES_3, SERIES_4, TYP " " from web_stat_panels " " where ID = " + str(key) ): series = row var_ids = "%s, %s, %s, %s" % row[0:4] typ = row[4] width, height = int(width), int(height) if width <= 0: width = 300 if height <= 0: height = 150 interval = self.param("range") delta_x = 1 if interval == "-6 hour": delta_x = 6 * 3600 elif interval == "-12 hour": delta_x = 12 * 3600 elif interval == "-1 day": delta_x = 24 * 3600 elif interval == "-3 day": delta_x = 3 * 24 * 3600 elif interval == "-7 day": delta_x = 7 * 24 * 3600 elif interval == "-14 day": delta_x = 14 * 24 * 3600 elif interval == "-30 day": delta_x = 30 * 24 * 3600 elif interval == "-90 day": delta_x = 3 * 30 * 24 * 3600 elif interval == "-180 day": delta_x = 6 * 30 * 24 * 3600 elif interval == "-360 day": delta_x = 12 * 30 * 24 * 3600 min_x = int(self.param("start")) - delta_x // 2 max_x = min_x + delta_x min_x_q = min_x - delta_x # // 100 max_x_q = max_x + delta_x # // 100 max_y = -9999 min_y = 9999 # Делаем полную выборку данных. Выкидываем подозрительные точки и # собираем статистику. prev_vals = [-9999] * 4 chart_data = [[], [], [], []] zoom_step = delta_x / (width * 5) if zoom_step < 1 or typ != 0: zoom_step = 1 x_min_max_values = [] mi_x = max_x_q ma_x = min_x_q tt = -100 for row in self.db.select( "select UNIX_TIMESTAMP(CHANGE_DATE) D, MIN(VALUE) + (MAX(VALUE) - MIN(VALUE)) VALUE, VARIABLE_ID " " from core_variable_changes " " where VARIABLE_ID in (%s) " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " " group by 3, ROUND(UNIX_TIMESTAMP(CHANGE_DATE) / %s)" " order by 3, 1 " % (var_ids, min_x_q, max_x_q, zoom_step) ): ind = series.index(row[2]) chart_data[ind] += [row] if row[0] > min_x and row[0] < max_x: max_y = max(max_y, row[1]) min_y = min(min_y, row[1]) if tt == -100: tt = row[2] if tt != row[2]: v = [tt, mi_x, ma_x] x_min_max_values += [v] mi_x = max_x_q ma_x = min_x_q tt = row[2] if row[0] < mi_x: mi_x = row[0] if row[0] > ma_x: ma_x = row[0] if tt != -1: v = [tt, mi_x, ma_x] x_min_max_values += [v] # print(x_min_max_values) # print(series) """ for row in self.db.select("select UNIX_TIMESTAMP(CHANGE_DATE) D, VALUE, VARIABLE_ID, ID " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " "order by CHANGE_DATE " % (min_x_q, max_x_q)): """ """ try: self.db.IUD("set @rn := 0") sql = ("select UNIX_TIMESTAMP(CHANGE_DATE) D, VALUE, VARIABLE_ID, ID " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " "order by CHANGE_DATE " % (min_x_q, max_x_q)) for c in self.db.select("select count(*) c " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " % (min_x_q, max_x_q)): cou = c[0] ccc = 1000 * 4 if cou > ccc: sql = ("select UNIX_TIMESTAMP(CHANGE_DATE) D, VALUE, VARIABLE_ID, ID, @rn := @rn + 1 rownum " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " "having mod(rownum, %s) = 0 " "order by VARIABLE_ID, CHANGE_DATE " % (min_x_q, max_x_q, math.ceil(cou / ccc))) for row in self.db.select(sql): ind = series.index(row[2]) prev_vals[ind] = row[1] if abs(prev_vals[ind] - row[1]) < 10: chart_data[ind] += [row] if row[0] > min_x and row[0] < max_x: max_y = max(max_y, row[1]) min_y = min(min_y, row[1]) prev_vals[ind] = row[1] except: pass """ if min_y is None or max_y is None or min_y == 9999 or max_y == -9999 or min_y == max_y: max_y = 1 min_y = 0 min_y = math.floor(min_y) max_y = math.ceil(max_y) if typ == 2: if min_y < 0 and max_y < 0: max_y = 0 elif min_y > 0 and max_y > 0: min_y = 0 # Определяем цвета colors = [[1, 0, 0], [0, 0.65, 0.31], [0, 0, 1], [1, 0, 1]] off_y = (max_y - min_y) / 10 min_y -= off_y max_y += off_y try: kx = (max_x - min_x) / (width - left - right) ky = (max_y - min_y) / (height - bottom) if ky == 0: ky = 1 except: kx, ky = 1, 1 img = ImageSurface(FORMAT_ARGB32, width, height) ctx = Context(img) width -= right ctx.set_line_width(1) # Рисуем сетку ctx.set_font_size(12) try: b_w, b_h = ctx.text_extents("00-00-0000")[2:4] # Метки на оси Y count = math.ceil(max_y) - math.ceil(min_y) space_count = math.ceil(count / ((height - bottom) / (b_h * 1.5))) sc = 0 for i in range(math.ceil(min_y), math.ceil(max_y)): if sc == 0: y = height - bottom + (min_y - i) / ky ctx.set_source_rgb(*(color_x_line)) ctx.move_to(left, y) ctx.line_to(width, y) ctx.stroke() ctx.set_source_rgb(0, 0, 0) num = str(i) tw, th = ctx.text_extents(num)[2:4] ctx.move_to(left - 5 - tw, y + th // 2) ctx.show_text(num) sc = space_count sc -= 1 # Метки на оси Х x_step = 3600 if interval == "-6 hour" or interval == "-12 hour" or interval == "-1 day": # Дополнительно метки часов x_step = 3600 for i in range(math.ceil(min_x / x_step), math.ceil(max_x / x_step)): x = (i * x_step - min_x) / kx + left ctx.set_source_rgb(*(color_x_line_2)) ctx.move_to(x, 0) ctx.line_to(x, height - bottom) ctx.stroke() num = datetime.datetime.fromtimestamp(i * x_step).strftime("%H") tw, th = ctx.text_extents(num)[2:4] ctx.move_to(x + 2, height - bottom - 3) ctx.set_source_rgb(*(color_x_line)) ctx.show_text(num) x_step = 3600 * 24 space_count = 1 count = math.ceil(max_x / x_step) - math.ceil(min_x / x_step) try: if (width / count) < b_w: space_count = 2 except: pass sc = 0 tz = 3600 * 2 tx_prev = -100 for i in range(math.ceil(min_x / x_step), math.ceil(max_x / x_step) + 1): if sc == 0: d_i = datetime.datetime.fromtimestamp(i * x_step) x = (i * x_step - min_x - tz) / kx + left ctx.set_source_rgb(0, 0, 0) num = d_i.strftime("%d-%m-%Y %H") x -= (int(d_i.strftime("%H")) * 3600 - tz) / kx tw, th = ctx.text_extents(num)[2:4] tx = x - tw // 2 ctx.move_to(tx, height - bottom + th + 5) if tx - tx_prev > tw: ctx.show_text(num) tx_prev = tx ctx.set_source_rgb(*(color_y_line_date)) else: ctx.set_source_rgb(*(color_y_line)) if x >= left and x < width: ctx.move_to(x, 0) ctx.line_to(x, height - bottom) ctx.stroke() sc = space_count sc -= 1 except Exception as e: pass # Рисуем верхний и правый бордер ctx.set_source_rgb(*color_border) ctx.move_to(left, 0) ctx.line_to(width, 0) ctx.line_to(width, height - bottom) ctx.stroke() # Рисуем сами графики ctx.rectangle(left, 0, width - left, height) ctx.clip() is_first = True currVarID = -1 prevX = -1 if typ == 0: # Линейная for ind in range(4): """ if len(chart_data[ind]) > 0: for i in range(len(chart_data[ind]) - 1): chart_data[ind][i] = list(chart_data[ind][i]) r1 = chart_data[ind][i] r2 = chart_data[ind][i + 1] chart_data[ind][i][0] += (r2[0] - r1[0]) / 2 chart_data[ind][i][1] += (r2[1] - r1[1]) / 2 """ ctx.set_source_rgb(*colors[ind]) is_first = True for row in chart_data[ind]: x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky if is_first: ctx.move_to(x, y) else: if row[0] - prevX > 10000: ctx.move_to(x, y) else: ctx.line_to(x, y) prevX = row[0] is_first = False ctx.stroke() elif typ == 1: # Точечная for ind in range(4): if chart_data[ind]: ctx.set_source_rgb(*colors[ind]) for row in chart_data[ind]: x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky ctx.rectangle(x - 3, y - 3, 6, 6) ctx.fill() elif typ == 2: # Столбчатая cy = height - bottom - (-min_y) / ky for ind in range(4): for row in chart_data[ind]: if currVarID != row[2]: ctx.fill() for i in range(4): if series[i] == row[2]: ctx.set_source_rgb(*colors[i]) x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky ctx.rectangle(x - 5, y, 10, cy - y) currVarID = row[2] ctx.fill() else: # Линейчастая # one_vals = self._get_one_val(series, min_x_q, max_x_q) one_vals = self._get_one_val(series, x_min_max_values, min_x_q, max_x_q) for ind in range(4): if series[ind]: is_now = True for r in one_vals[ind]: if r[4] == 1: chart_data[ind].insert(0, r) else: chart_data[ind] += [r] is_now = False if is_now: if len(chart_data[ind]) > 0: r = list(chart_data[ind][len(chart_data[ind]) - 1]) r[0] = datetime.datetime.now().timestamp() chart_data[ind] += [r] color = colors[ind] color_fill = color.copy() color_fill += [0.3] is_first = True y0 = height - bottom + min_y / ky for row in chart_data[ind]: x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky if is_first: is_first = False else: ctx.set_source_rgb(*color) ctx.move_to(prevX, prevY) ctx.line_to(x, prevY) ctx.line_to(x, y) ctx.stroke() ctx.set_source_rgba(*color_fill) rx, ry, rw, rh = prevX, y0, x - prevX, prevY - y0 ctx.rectangle(rx, ry, rw, rh) ctx.fill() prevX, prevY = x, y # Рисуем оси ctx.set_source_rgb(0, 0, 0) ctx.move_to(left, 0) ctx.line_to(left, height - bottom) ctx.line_to(width, height - bottom) ctx.stroke() # --------------------------- del ctx byt = BytesIO() img.write_to_png(byt) byt.seek(0) return byt.read()
[tags.pop() for x in range(len(segment) - 1)] VERTS.extend(verts) CODES.extend(codes) start = end+1 # Draw glyph ctx.new_path() ctx.set_source_rgba(0.8,0.5,0.8, 1) i = 0 while (i < len(CODES)): if (CODES[i] == MOVETO): ctx.move_to(VERTS[i][0],VERTS[i][1]) i += 1 elif (CODES[i] == LINETO): ctx.line_to(VERTS[i][0],VERTS[i][1]) i += 1 elif (CODES[i] == CURVE3): ctx.curve_to(VERTS[i][0],VERTS[i][1], VERTS[i+1][0],VERTS[i+1][1], # undocumented VERTS[i+1][0],VERTS[i+1][1]) i += 2 elif (CODES[i] == CURVE4): ctx.curve_to(VERTS[i][0],VERTS[i][1], VERTS[i+1][0],VERTS[i+1][1], VERTS[i+2][0],VERTS[i+2][1]) i += 3 ctx.fill_preserve() ctx.set_source_rgb(0,0,0) ctx.set_line_width(6) ctx.stroke()
def main(marker, paper, format, bbox, emergency, place, recipient, sender, text, sender_is_recipient, map_href): """ """ mark = Location(*marker) handle, filename = mkstemp(prefix='safetymap-', suffix='.pdf') close(handle) if paper == 'a4': surf = PDFSurface(filename, 210*ptpmm, 297*ptpmm) elif paper == 'letter': surf = PDFSurface(filename, 8.5*ptpin, 11*ptpin) ctx = Context(surf) ctx.scale(ptpmm, ptpmm) set_font_face_from_file(ctx, 'assets/HelveticaNeue.ttc') if paper == 'a4': draw_a4_master(ctx, format, map_href) ctx.translate(19, 24) elif paper == 'letter': draw_letter_master(ctx, format, map_href) ctx.translate(21, 18) ctx.set_line_width(.25 * mmppt) ctx.set_source_rgb(*md_gray) ctx.set_dash([3 * mmppt]) reps = {'4up': 4, '2up-fridge': 2, 'poster': 0} if reps[format]: card_img, mark_point = get_map_image(bbox, 84, 39, mark) for i in range(reps[format]): # dashed outlines ctx.move_to(0, 61) ctx.line_to(0, 0) ctx.line_to(173, 0) ctx.line_to(173, 61) #ctx.move_to(86, 0) #ctx.line_to(86, 61) ctx.stroke() # two card sides and contents draw_card_left(ctx, recipient, sender, text, sender_is_recipient) ctx.translate(86.5, 0) draw_card_right(ctx, card_img, mark_point, emergency, place) ctx.translate(-86.5, 61) if format == '4up': # bottom dashed outline ctx.move_to(0, 0) ctx.line_to(172, 0) ctx.stroke() elif format == '2up-fridge': # prepare to draw sideways ctx.translate(0, 122.5) ctx.rotate(-pi/2) ctx.rectangle(0, 0, 122.5, 173) ctx.stroke() poster_img, mark_point = get_map_image(bbox, 109, 77, mark) draw_small_poster(ctx, poster_img, mark_point, emergency, place, recipient, sender, text, sender_is_recipient) elif format == 'poster': ctx.rectangle(0, 0, 173, 245) ctx.stroke() poster_img, mark_point = get_map_image(bbox, 153, 108, mark) draw_large_poster(ctx, poster_img, mark_point, emergency, place, recipient, sender, text, sender_is_recipient) surf.finish() chmod(filename, 0644) return filename
def on_draw(self, widget: Widget, context: cairo.Context): self.min_size = 200, 150 super().on_draw(widget, context) context.save() context.set_font_size(self.font_size) if self._table_extents is None: self._update_table_extents(context) skip = max(self.skip, 0) how_many = self.how_many table_extents = self._table_extents title_extents = self._table_extents.title_extents expected_height = title_extents.total_height + self.margin entries = self.entries base = skip up_to = skip over = False while up_to < len(entries) and not over: expected_height += table_extents[up_to].total_height over = expected_height >= self._max_height if not over: up_to += 1 while base > 0 and not over: expected_height += table_extents[base-1].total_height over = expected_height >= self._max_height if not over: base -= 1 how_many = up_to - base skip = base self.base = base entries = self.entries[skip:skip + how_many] def table_extents_iterator(): return table_extents.iter_over( skip, how_many ) start_x, start_y = context.get_current_point() start_y += title_extents.total_height h = title_extents.total_height self.title_height = h for (index, cell), data in zip(enumerate(title_extents), self.title): context.save() offset = title_extents.get_cell_data_left(index) context.rectangle(start_x + offset, start_y - h, cell.width, 2*h) context.clip() context.move_to( start_x + offset, start_y ) context.show_text(data) context.restore() # start_y += self.margin curr_x, curr_y = start_x, start_y# + title_extents.total_height for line_index, (line_extent, entry) in enumerate(zip(table_extents_iterator(), entries)): h = line_extent.total_height curr_y += h if curr_y + self.margin >= self._max_height: break for (cell_index, cell), data in zip(enumerate(line_extent), entry): context.save() offset = line_extent.get_cell_data_left(cell_index) context.rectangle(curr_x + offset, curr_y - h, cell.width, 2*h) context.clip() context.move_to( curr_x + offset, curr_y ) context.show_text(data) context.restore() curr_x = start_x end_x = table_extents.entries_width curr_y = start_y + self.margin end_y = table_extents.get_height_up_to(skip, how_many) + start_y + self.margin + 1 self.table_height = end_y self.table_width = end_x for line in table_extents_iterator(): context.move_to(curr_x, curr_y) context.line_to(end_x, curr_y) context.stroke() curr_y += line.total_height context.move_to(curr_x, curr_y) context.line_to(end_x, curr_y) context.stroke() curr_x = start_x curr_y = start_y - 1 + self.margin if self._how_many > 0: line = table_extents[0] for cell in line: context.move_to(curr_x, curr_y) context.line_to(curr_x, end_y) context.stroke() curr_x += cell.total_width + 2 * self.margin context.move_to(curr_x, curr_y) context.line_to(curr_x, end_y) context.stroke() if self._to_highlight is not None: r, g, b = global_constants.highlight context.set_source_rgba(r, g, b, .6) index = self._to_highlight base = start_y + table_extents.get_height_up_to(skip, index) + self.margin h = table_extents.get_height_of(skip, how_many, index) context.rectangle(start_x, base, table_extents.entries_width, h) context.fill() context.restore() self._shown = how_many
ctx.translate(0, -(cbox.yMax + cbox.yMin)) # difference! Curve_Tag = [FT_Curve_Tag(tag) for tag in outline.tags] start, end = 0, 0 VERTS, CODES = [], [] # Iterate over each contour ctx.set_source_rgb(0.5,0.5,0.5) for i in range(len(outline.contours)): end = outline.contours[i] ctx.move_to(outline.points[start][0],outline.points[start][1]) for j in range(start, end+1): point = outline.points[j] ctx.line_to(point[0],point[1]) #back to origin ctx.line_to(outline.points[start][0], outline.points[start][1]) start = end+1 ctx.fill_preserve() ctx.set_source_rgb(0,1,0) ctx.stroke() start, end = 0, 0 for i in range(len(outline.contours)): end = outline.contours[i] ctx.new_path() ctx.set_source_rgb(0,0,1) for j in range(start, end+1): if ( Curve_Tag[j] == FT_Curve_Tag_On ):