Beispiel #1
0
 def make_arrow(self, color):
     key = color
     if key in self.arrows:
         return self.arrows[key]
     arrow = draw.Marker(-0.1, -0.5, 1.1, 0.5, scale=4)
     arrow.append(draw.Lines(1, -0.5, 1, 0.5, 0, 0, fill=color, close=True))
     self.arrows[key] = arrow
     return arrow
Beispiel #2
0
    def __init__(self,
                 is_gem_sbml=False,
                 pathway_id='rp_pathway',
                 central_species_group_id='central_species',
                 sink_species_group_id='rp_sink_species',
                 model_name=None,
                 document=None,
                 path=None,
                 rpcache=None):
        """Class constructor

        .. document private functions
        .. automethod:: hierarchyPos
        """
        super().__init__(is_gem_sbml,
                         pathway_id,
                         central_species_group_id,
                         sink_species_group_id,
                         model_name,
                         document,
                         path,
                         rpcache)
        #self.logger = logging.getLogger(__name__)
        self.logger = logging.getLogger(os.path.basename(__file__))
        self.mnx_cofactors = json.load(open('data/mnx_cofactors.json', 'r'))
        #some drawing constants
        self.arrowhead = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto', id='normal_arrow')
        self.arrowhead.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='black', close=True))
        self.arrowhead_flat = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient=0, id='flat_arrow')
        self.arrowhead_flat.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='black', close=True))
        self.rev_arrowhead_flat = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient=180, id='rev_flat_arrow')
        self.rev_arrowhead_flat.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='black', close=True))
        '''
        self.rev_arrowhead = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient=0, id='rev_flat_arrow')
        self.rev_arrowhead.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='black', close=True))
        '''
        self.arrowhead_comp_x = 7.0
        self.arrowhead_comp_y = 7.0
Beispiel #3
0
def drawSigil(points, canvas, color='white'): # draw sigil from coordinate list

    # setup sigil
    dash = svg.Marker(-0.5, -0.5, 0.5, 0.5, scale=5, orient='auto') # define line to terminate the sigil
    dash.append(svg.Line(-0., -0.5, 0., 0.5, stroke_width=0.2, stroke=color))
    dot = svg.Marker(-0.8, -0.5, 0.5, 0.5, scale=5, orient='auto') # define circle to start the sigil
    dot.append(svg.Circle(-0.3, 0.0, 0.3, stroke_width=0.2, stroke=color, fill='none'))
    p = svg.Path(stroke_width=7, stroke=color, fill='none', marker_start=dot, marker_end=dash)

    # draw sigil
    for point in points:
        if points.index(point) == 0:
            originX = point[0]
            originY = point[1]
            p.M(originX, originY)
        else:
            x = point[0] - originX # abs. to rel. coords
            y = point[1] - originY # abs. to rel. coords
            p.l(x, y) # draw
            originX = point[0]
            originY = point[1]

    # add to canvas
    canvas.append(p)
Beispiel #4
0
    def draw_constraint(self, url, dn, rc, stroke="red", stroke_width=1):

        d = self.d

        arrow = draw.Marker(-0.1,
                            -0.5,
                            0.9,
                            0.5,
                            scale=stroke_width * 1.5,
                            orient='auto')
        arrow.append(
            draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill=stroke, close=True))

        p = draw.Path(stroke=stroke,
                      stroke_width=stroke_width,
                      fill='none',
                      stroke_dasharray="4",
                      marker_end=arrow)

        t = self.tree
        bdn = t & dn
        p_bdn = bdn.up

        brc = t & rc
        p_brc = brc.up

        if bdn.x_coor > brc.x_coor:

            p = draw.Path(stroke=stroke,
                          stroke_width=stroke_width,
                          fill='none',
                          marker_end=arrow)
            p.M(bdn.x_coor, bdn.y_coor).L(brc.x_coor, brc.y_coor)
            d.append(p)
        else:

            p = draw.Path(stroke=stroke,
                          stroke_width=stroke_width,
                          fill='none',
                          marker_end=arrow)
            p.M(bdn.x_coor, bdn.y_coor).L(brc.x_coor, brc.y_coor)
            d.append(p)
        '''
        spacing = self.width / (self.n_leaves + 1)
        total_time = self.total_time
        width = self.width
        height = self.height
        d = self.d
        stroke_a = stroke_width / 2.0
       
        for n in self.tree.traverse():
            # Inner tree, vertical lines
            x_0, y_0, y_1 = n.x_coor, n.y_coor, self._y_scaling(n.dist)
            p = draw.Path(stroke=stroke, stroke_width=stroke_width, fill='none')  
            p.M(x_0, y_0).l(0, y_1)  
            d.append(p)                        
            if not n.is_leaf():        
                c1, c2 = n.get_children()                
                # Horizontal lines        
                # Inner Tree                
                p = draw.Path(stroke=stroke, stroke_width=stroke_width, fill='none')  
                p.M(c1.x_coor - stroke_a, n.y_coor).L(c2.x_coor + stroke_a, n.y_coor)
                d.append(p)            
        d.setRenderSize(h=self.height)
        d.saveSvg(url)
        return(d)
    
    
        if node2events[n.name] == "T":                    
                        p = draw.Path(stroke=stroke, stroke_width=stroke_width, fill='none', 
                                      stroke_dasharray="4", marker_end=arrow)  

                        if c1.x_coor > c2.x_coor:                    
                            p.M(c1.x_coor, n.y_coor).L(c2.x_coor + radius, n.y_coor)
                        else:
                            p.M(c1.x_coor, n.y_coor).L(c2.x_coor - radius, n.y_coor)

    
        '''
        d.saveSvg(url)
        return (d)
Beispiel #5
0
    def DrawGeneTree(self,
                     url,
                     genetreefile,
                     eventsgenetreefile,
                     stroke="red",
                     stroke_width=2,
                     displacement=2,
                     r_displacement=0,
                     symbol_scaling=1.5):

        spacing = self.width / (self.n_leaves + 1)
        total_time = self.total_time
        width = self.width
        height = self.height
        d = self.d
        radius = 0.1

        genetree_svg = list()

        r_displacement = random.uniform(-r_displacement, r_displacement)
        node2events = dict()
        node2displacement = dict()

        gtree = self._read_treefile(genetreefile)

        #################### This a patch to correct a bug in Zombi ################

        with open(eventsgenetreefile) as f:
            f.readline()
            o, e, nodes = f.readline().strip().split("\t")

            o_time = float(o)
            while e != "S" and e != "E" and e != "F" and e != "L" and e != "T" and e != "D":
                t, e, nodes = f.readline().strip().split("\t")
            gtree.dist = float(t) - float(o)

        #############################################################################

        # We add the coordinates
        for n in gtree.traverse():
            dist_to_origin = n.get_distance(gtree) + gtree.dist + o_time
            x_coor, _ = self.node2coor[n.name.split("_")[0]]
            y_coor = round(
                self._y_scaling(total_time) - self._y_scaling(dist_to_origin),
                2)

            n.add_feature("displacement", 0)
            n.add_feature("x_coor", x_coor)
            n.add_feature("y_coor", y_coor)

        # We add the displacement
        gtree.displacement = r_displacement
        gtree.x_coor += r_displacement
        for n in gtree.iter_descendants():
            parent_d = (n.up).displacement
            n.displacement = parent_d
            if n.name in node2displacement:
                n.displacement += node2displacement[n.name]
            n.x_coor += (n.displacement * displacement) + r_displacement
            #n.y_coor += (n.displacement*4)

        # We get a dict with the new coordinates in the gene tree

        gnode2x_coor = {n.name: n.x_coor for n in gtree.traverse()}

        ###### EVENT SYMBOLS ############

        arrow = draw.Marker(-0.1,
                            -0.5,
                            0.9,
                            0.5,
                            scale=stroke_width * 1.5,
                            orient='auto')
        arrow.append(
            draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill=stroke, close=True))

        ##################################

        # We add the symbols
        symbols = list()

        with open(eventsgenetreefile) as f:
            f.readline()
            for l in f:
                t, e, nodes = l.strip().split("\t")
                if nodes == "Root":
                    x_coor = gnode2x_coor["Root_1"]
                else:
                    x_coor = gnode2x_coor["_".join(nodes.split(";")[:2])]
                if e == "O":
                    o_time = float(t)
                    y_coor = self._y_scaling(total_time) - self._y_scaling(
                        float(t))
                    symbols.append(("O", x_coor, y_coor))
                if e == "D":
                    _, _, node1, num1, node2, num2 = nodes.split(";")
                    n1 = node1 + "_" + num1
                    n2 = node2 + "_" + num2
                    node2displacement[n1] = 1
                    node2displacement[n2] = -1
                    y_coor = self._y_scaling(total_time) - self._y_scaling(
                        float(t))
                    symbols.append(("D", x_coor, y_coor))
                if e == "L":
                    y_coor = self._y_scaling(total_time) - self._y_scaling(
                        float(t))
                    symbols.append(("L", x_coor, y_coor))
                if e == "T":
                    _, _, node1, num1, node2, num2 = nodes.split(";")
                    n1 = node1 + "_" + num1
                    n2 = node2 + "_" + num2
                    node2events["_".join(nodes.split(";")[0:2])] = "T"
                    node2displacement[n2] = 1
                    #x_coor, _ = self.node2coor[nodes.split(";")[4]]
                    #y_coor = self._y_scaling(float(t))

        for n in gtree.traverse():

            # Need to check 2 things: is leaf? and has_events?

            if n.is_leaf() and n.name in node2events:

                # Vertical line

                if node2events[n.name] == "L":
                    x_0, y_0, y_1 = n.x_coor, n.y_coor, self._y_scaling(n.dist)
                    p = draw.Path(stroke=stroke,
                                  stroke_width=stroke_width,
                                  fill='none',
                                  marker_end=cross)
                    p.M(x_0, y_0).l(0, y_1)
                else:
                    x_0, y_0, y_1 = n.x_coor, n.y_coor, self._y_scaling(n.dist)
                    p = draw.Path(stroke=stroke,
                                  stroke_width=stroke_width,
                                  fill='none')
                    p.M(x_0, y_0).l(0, y_1)
                genetree_svg.append(p)

            elif not n.is_leaf() and n.name in node2events:

                # Vertical line

                x_0, y_0, y_1 = n.x_coor, n.y_coor, self._y_scaling(n.dist)
                p = draw.Path(stroke=stroke,
                              stroke_width=stroke_width,
                              fill='none')
                p.M(x_0, y_0).l(0, y_1)
                genetree_svg.append(p)

                # Horizontal line

                c1, c2 = n.get_children()

                if node2events[n.name] == "T":
                    p = draw.Path(stroke=stroke,
                                  stroke_width=stroke_width,
                                  fill='none',
                                  stroke_dasharray="4",
                                  marker_end=arrow)

                    if c1.x_coor > c2.x_coor:
                        p.M(c1.x_coor, n.y_coor).L(c2.x_coor + radius,
                                                   n.y_coor)
                    else:
                        p.M(c1.x_coor, n.y_coor).L(c2.x_coor - radius,
                                                   n.y_coor)

                genetree_svg.append(p)

            elif n.is_leaf() and n.name not in node2events:

                # Vertical line

                x_0, y_0, y_1 = n.x_coor, n.y_coor, self._y_scaling(n.dist)
                p = draw.Path(stroke=stroke,
                              stroke_width=stroke_width,
                              fill='none')
                p.M(x_0, y_0).l(0, y_1)
                genetree_svg.append(p)

            elif not n.is_leaf() and n.name not in node2events:

                # Vertical line

                x_0, y_0, y_1 = n.x_coor, n.y_coor, self._y_scaling(n.dist)
                p = draw.Path(stroke=stroke,
                              stroke_width=stroke_width,
                              fill='none')
                p.M(x_0, y_0).l(0, y_1)
                genetree_svg.append(p)

                # Horizontal line

                c1, c2 = n.get_children()
                p = draw.Path(stroke=stroke,
                              stroke_width=stroke_width,
                              fill='none')
                p.M(c1.x_coor - (stroke_width / 2.0),
                    n.y_coor).L(c2.x_coor + (stroke_width / 2.0), n.y_coor)
                genetree_svg.append(p)

        # We add the symbols
        for e, x_coor, y_coor in symbols:
            if e == "O":
                p = draw.Circle(cx=x_coor,
                                cy=y_coor,
                                r=stroke_width * symbol_scaling,
                                stroke=stroke,
                                stroke_width=0,
                                fill='green')
                genetree_svg.append(p)
            if e == "D":
                p = draw.Circle(cx=x_coor,
                                cy=y_coor,
                                r=stroke_width * symbol_scaling,
                                stroke=stroke,
                                stroke_width=0,
                                fill='yellow')
                genetree_svg.append(p)
            if e == "L":
                p = draw.Circle(cx=x_coor,
                                cy=y_coor,
                                r=stroke_width * symbol_scaling,
                                stroke=stroke,
                                stroke_width=0,
                                fill='red')
                genetree_svg.append(p)

        for element in genetree_svg:
            d.append(element)
        d.setRenderSize(h=self.height)
        d.saveSvg(url)
        return (d)
Beispiel #6
0
             stroke_width=3,
             fill='none'))
d.append(
    draw.Arc(60,
             -20,
             20,
             270,
             60,
             cw=True,
             stroke='blue',
             stroke_width=1,
             fill='black',
             fill_opacity=0.3))

# Draw arrows
arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto')
arrow.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='red', close=True))
p = draw.Path(stroke='red', stroke_width=2, fill='none',
              marker_end=arrow)  # Add an arrow to the end of a path
p.M(20, -40).L(20, -27).L(0, -20)  # Chain multiple path operations
d.append(p)
d.append(
    draw.Line(30,
              -20,
              0,
              -10,
              stroke='red',
              stroke_width=2,
              fill='none',
              marker_end=arrow))  # Add an arrow to the end of a line
Beispiel #7
0
def arrow(scale, color):
    marker = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=scale, orient='auto')
    marker.append(
        draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill=color, close=True))
    return marker
Beispiel #8
0
def draw_genes(annotations, scale, color_table):
    '''Draw the genes in annotations.
    '''
    # Define the coordinate system to draw on.
    # x length is fixed, y depends on how many species/strains are in the
    # annotations (how many gff's were given to the script)
    y_len = 25*len(annotations) + 50 # Add 50 for the scale bar
    d = draw.Drawing(500, y_len, origin = (0,0), displayInline=False)

    for idx, (k, v) in enumerate(annotations.items()):
        genes, min, max = v[0], v[1], v[2]
        contig_length = (max - min)*scale
        offset = 35
        row = y_len-25*(idx+1)

        # Draw a line for each gff file and it's name
        d.append(draw.Line(offset, row, contig_length+offset, row, stroke='black', stroke_width=2, fill='none'))
        d.append(draw.Text(k[:10],6, 2, row-1, text_anchor="left", fill='black'))

        for gene in genes:
            color = color_table[gene[4]]
            arrow = draw.Marker(0, -0.5, 1, 0.5, scale=2, orient='auto')
            arrow.append(draw.Lines(0, -0.5, 0, 0.5, 1, 0, fill=color, close=True))

            # Draw genes
            gene_coords = ((gene[1] - min)*scale+offset, \
                            (gene[2] - min)*scale+offset)

            midpoint = int(gene_coords[0] + (gene_coords[1] - gene_coords[0]) / 2)

            arrow_positions = []

            # Shit code but extend the arrows from the midpoint in both
            # directions
            i = midpoint
            while i < int(gene_coords[1])-1:
                arrow_positions.append(i)
                i += int(600*scale)
            i = midpoint - int(600*scale)
            while i > int(gene_coords[0])+1:
                arrow_positions.append(i)
                i -= int(600*scale)

            # To draw arrows in correct orientation
            k = -1 if gene[3] == "+" else 1

            # Draw a line for each gene
            d.append(draw.Line(gene_coords[0], row, gene_coords[1], row, \
                        stroke=color, stroke_width=6, fill='none'))
            # Draw arrows on the gene, depending on orientation
            for a in arrow_positions:
                d.append(draw.Lines(a+k, row+2, a-k, row, a+k, row-2, \
                        stroke_width=0.2, stroke = "black",fill="none"))

            ## Draw labels
            # Gene name, skip hypothetical proteins
            if gene[4] != "hypothetical_protein":
                text_pos = gene_coords[0] + (gene_coords[1]-gene_coords[0])/2
                d.append(draw.Text(gene[4],5, text_pos,row-10, center=0.6, text_anchor="middle", fill='black'))

    # Draw a scale bar
    longest = int(450 / scale)
    row = 25
    d.append(draw.Line(offset, row, longest, row, stroke='black', stroke_width=1, fill='none'))
    for num in range(0,longest, 1000):
        scaled_num = num*scale + offset
        d.append(draw.Line(scaled_num, row+1.5, scaled_num, row-1.5, stroke='black', stroke_width=0.5, fill='none'))
        d.append(draw.Text(str(num), 3, scaled_num, row-5, center=True, fill='black'))

    d.setPixelScale(2)
    d.saveSvg('test.svg')
Beispiel #9
0
def draw_bloch_sphere(d,
                      inner_proj=euclid3d.identity(3),
                      label='',
                      axis=None,
                      rot_proj=None,
                      rot_deg=180,
                      outer_labels=(),
                      inner_labels=(),
                      extra_opacity=1,
                      inner_opacity=1,
                      background='white'):
    spin = euclid3d.rotation(3, 0, 2, 2 * np.pi / 16 / 2 * 1.001)
    tilt = euclid3d.rotation(3, 1, 2, np.pi / 8)
    trans = tilt @ spin @ euclid3d.axis_swap((1, 2, 0))
    proj = euclid3d.perspective3d(np.pi / 8, view_size=4) @ trans
    zx = euclid3d.axis_swap((2, 0, 1))
    xy = euclid3d.identity(3)
    yz = euclid3d.axis_swap((1, 2, 0))
    proj_zx = proj @ zx
    proj_xy = proj @ xy
    proj_yz = proj @ yz

    if background:
        d.append(draw.Rectangle(-100, -100, 200, 200, fill=background))

    def draw_band(proj,
                  trans,
                  r_outer=1,
                  r_inner=0.9,
                  color='black',
                  z_mul=1,
                  opacity=1,
                  divs=4,
                  d=d,
                  **kwargs):
        color = (color *
                 divs)[:divs] if isinstance(color, list) else [color] * divs
        points = np.array([[-1, -1, 1, 1], [-1, 1, 1, -1]]).T
        sqr12 = 0.5**0.5
        overlap = np.pi / 500 * (divs != 4)
        start_end_points = [
            np.array([[
                np.cos(pr - 2 * np.pi / divs - overlap),
                np.sin(pr - 2 * np.pi / divs - overlap)
            ], [np.cos(pr + overlap),
                np.sin(pr + overlap)],
                      [np.cos(pr - np.pi / divs),
                       np.sin(pr - np.pi / divs)]])
            for pr in np.linspace(0, 2 * np.pi, num=divs, endpoint=False)
        ]
        for i in range(divs):
            p = draw.Path(fill=color[i],
                          stroke='none',
                          stroke_width=0.002,
                          **kwargs,
                          opacity=opacity)
            z = trans.project_point(
                (r_inner + r_outer) / 2 * start_end_points[i][2])[2]
            e = shapes.EllipseArc.fromBoundingQuad(
                *proj.project_list(points * r_outer)[:, :2].flatten(),
                *proj.project_list(start_end_points[i] *
                                   r_outer)[:, :2].flatten(),
            )
            if e: e.drawToPath(p)
            if r_inner > 0:
                e = shapes.EllipseArc.fromBoundingQuad(
                    *proj.project_list(points * r_inner)[:, :2].flatten(),
                    *proj.project_list(start_end_points[i] *
                                       r_inner)[:, :2].flatten(),
                )
                if e:
                    e.reversed().drawToPath(p, includeL=True)
            p.Z()
            d.append(p, z=z * z_mul)
            if False:
                d.draw(shapes.EllipseArc.fromBoundingQuad(
                    *proj.project_list(
                        (r_outer + r_inner) / 2 * points)[:, :2].flatten(),
                    *proj.project_list((r_outer + r_inner) / 2 *
                                       start_end_points[i])[:, :2].flatten(),
                ),
                       fill='none',
                       stroke_width=0.02,
                       stroke=color[i],
                       **kwargs,
                       z=z * z_mul)

    xycolors = ['#56e', '#239', '#56e', '#56e']
    yzcolors = ['#e1e144', '#909022', '#e1e144', '#e1e144']
    zxcolors = ['#9e2', '#6a1', '#9e2', '#9e2']

    draw_band(proj_xy, trans @ xy, 1, 0.925, z_mul=10, color=xycolors)
    draw_band(proj_yz, trans @ yz, 1, 0.925, z_mul=10, color=yzcolors)
    draw_band(proj_zx, trans @ zx, 1, 0.925, z_mul=10, color=zxcolors)

    # Inner
    g = draw.Group(opacity=inner_opacity)
    z_center = trans.project_point((0, 0, 0))[2]
    d.append(g, z=z_center)
    inner_xy = proj @ inner_proj @ xy
    # Darker colors: #34b, #a8a833, #7b2
    draw_band(proj @ inner_proj @ xy,
              trans @ inner_proj @ xy,
              0.8,
              0.7,
              color=xycolors,
              d=g)
    draw_band(proj @ inner_proj @ yz,
              trans @ inner_proj @ yz,
              0.8,
              0.7,
              color=yzcolors,
              divs=4,
              d=g)
    draw_band(proj @ inner_proj @ zx,
              trans @ inner_proj @ zx,
              0.8,
              0.7,
              color=zxcolors,
              divs=8 // 2,
              d=g)
    elevation_lines = False
    if elevation_lines:
        for elevation in (*np.linspace(0, np.pi / 2, 4, True)[1:-1],
                          *np.linspace(-np.pi / 2, 0, 3, False)[1:]):
            y = 0.75 * np.sin(elevation)
            r = 0.75 * np.cos(elevation)
            draw_band(proj @ inner_proj @ xy @ euclid3d.translation((0, 0, y)),
                      trans @ inner_proj @ xy @ euclid3d.translation(
                          (0, 0, y)),
                      r_outer=r - 0.01,
                      r_inner=r + 0.01,
                      color='#bbb',
                      opacity=1,
                      d=g)
    arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto')
    arrow.append(
        draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='black', close=True))
    g.append(draw.Line(*inner_xy.p2(-0.65, 0, 0),
                       *inner_xy.p2(0.6, 0, 0),
                       stroke='black',
                       stroke_width=0.015,
                       marker_end=arrow),
             z=z_center)
    g.append(draw.Line(*inner_xy.p2(0, -0.65, 0),
                       *inner_xy.p2(0, 0.6, 0),
                       stroke='black',
                       stroke_width=0.015,
                       marker_end=arrow),
             z=z_center)
    g.append(draw.Line(*inner_xy.p2(0, 0, -0.65),
                       *inner_xy.p2(0, 0, 0.6),
                       stroke='black',
                       stroke_width=0.015,
                       marker_end=arrow),
             z=z_center)
    for pt, (x_off, y_off), elem in inner_labels:
        x, y = (proj @ inner_proj).p2(*pt)
        g.append(draw.Use(elem, x + x_off, y + y_off), z=10000)

    # Outer arrows and text
    arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto')
    arrow.append(
        draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='black', close=True))
    d.append(draw.Line(*proj_xy.p2(1, 0, 0),
                       *proj_xy.p2(1.2, 0, 0),
                       stroke='black',
                       stroke_width=0.02,
                       marker_end=arrow),
             z=100)
    d.append(draw.Line(*proj_xy.p2(0, 1, 0),
                       *proj_xy.p2(0, 1.2, 0),
                       stroke='black',
                       stroke_width=0.02,
                       marker_end=arrow),
             z=100)
    d.append(draw.Line(*proj_xy.p2(0, 0, 1),
                       *proj_xy.p2(0, 0, 1.2),
                       stroke='black',
                       stroke_width=0.02,
                       marker_end=arrow),
             z=100)
    d.append(
        draw.Line(*proj_xy.p2(-1, 0, 0),
                  *proj_xy.p2(-1.2, 0, 0),
                  stroke='black',
                  stroke_width=0.02))
    d.append(
        draw.Line(*proj_xy.p2(0, -1, 0),
                  *proj_xy.p2(0, -1.2, 0),
                  stroke='black',
                  stroke_width=0.02))
    d.append(
        draw.Line(*proj_xy.p2(0, 0, -1),
                  *proj_xy.p2(0, 0, -1.2),
                  stroke='black',
                  stroke_width=0.02))
    d.append(draw.Text(['X'],
                       0.2,
                       *proj_xy.p2(1.7, 0, 0),
                       center=True,
                       fill='black'),
             z=100)
    d.append(draw.Text(['Y'],
                       0.2,
                       *proj_xy.p2(0, 1.35, 0),
                       center=True,
                       fill='black'),
             z=100)
    d.append(draw.Text(['Z'],
                       0.2,
                       *proj_xy.p2(0, 0, 1.4),
                       center=True,
                       fill='black'),
             z=100)
    for pt, (x_off, y_off), elem in outer_labels:
        x, y = proj.p2(*pt)
        d.append(draw.Use(elem, x + x_off, y + y_off), z=10000)

    # Extra annotations
    #label='', axis=None, rot_proj=None
    if label:
        d.append(
            draw.Text([label],
                      0.4,
                      -0.6,
                      1.2,
                      center=True,
                      fill='#c00',
                      text_anchor='end',
                      opacity=extra_opacity))
    if axis:
        g = draw.Group(opacity=extra_opacity)
        axis = np.array(axis, dtype=float)
        axis_len = 1.18
        axis /= np.linalg.norm(axis)
        arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=3, orient='auto')
        arrow.append(
            draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='#e00', close=True))
        z = 100  #10 * proj_xy.project_point(axis*1)[2]
        g.append(
            draw.Line(*proj_xy.p2(0, 0, 0),
                      *proj_xy.p2(*axis * axis_len),
                      stroke='#e00',
                      stroke_width=0.04,
                      marker_end=arrow))
        d.append(g, z=z)

    if rot_proj is not None:
        rot_proj = inner_proj @ rot_proj
        r_inner, r_outer = 0.1, 0.16
        points = np.array([[-1, -1, 1, 1], [-1, 1, 1, -1]]).T
        start_end_points = np.array([[1, 0], [-1, 0], [0, 1]])
        p = draw.Path(fill='orange',
                      fill_rule='nonzero',
                      opacity=extra_opacity)
        z = 9 * (trans @ rot_proj).project_point(start_end_points[2])[2]
        e = shapes.EllipseArc.fromBoundingQuad(
            *(proj @ rot_proj).project_list(points * r_outer)[:, :2].flatten(),
            *(proj @ rot_proj).project_list(start_end_points *
                                            r_outer)[:, :2].flatten(),
        )
        if e: e.reversed().drawToPath(p)
        e = shapes.EllipseArc.fromBoundingQuad(
            *(proj @ rot_proj).project_list(points * r_inner)[:, :2].flatten(),
            *(proj @ rot_proj).project_list(start_end_points *
                                            r_inner)[:, :2].flatten(),
        )
        if e:
            e.drawToPath(p, includeL=True)
        sa = 2.5 * (r_outer - r_inner)
        xa = -(r_inner + r_outer) / 2
        p.L(*(proj @ rot_proj).p2(xa, 0.3 * sa))
        p.L(*(proj @ rot_proj).p2(xa + 0.5 * sa, 0.3 * sa))
        p.L(*(proj @ rot_proj).p2(xa, -0.7 * sa))
        p.L(*(proj @ rot_proj).p2(xa - 0.5 * sa, 0.3 * sa))
        p.L(*(proj @ rot_proj).p2(xa, 0.3 * sa))
        p.Z()
        d.append(p, z=z)

    return d
Beispiel #10
0
def draw_share_progress():
    goal = int(getattr(settings, "SHARE_PROGRESS_GOAL", "10") or "10")
    offset = int(getattr(settings, "SHARE_PROGRESS_OFFSET", "0") or "0")
    baseline = int(getattr(settings, "SHARE_PROGRESS_BASELINE", "0") or "0")
    baseline_progress = baseline / goal
    ordered = Share.objects.filter(
        cancelled_date__isnull=True).count() + offset
    ordered_progress = ordered / goal
    paid = Share.objects.filter(cancelled_date__isnull=True,
                                paid_date__isnull=False).count() + offset
    paid_progress = paid / goal

    d = draw.Drawing(1.8, 1.6, origin='center')

    arrow = draw.Marker(-0.2, -0.5, 0.9, 0.5, scale=20, orient='auto')
    arrow.append(
        draw.Lines(-0.2,
                   -0.5,
                   0,
                   0,
                   -0.2,
                   0.5,
                   0.9,
                   0,
                   fill='black',
                   close=True))

    arc = draw.Path(stroke='black',
                    stroke_width=0.002,
                    fill_opacity=0,
                    marker_end=arrow)
    arc.arc(0, 0, 0.6, 89, 94, cw=True)
    d.append(arc)

    d.append(draw.Text(f'{goal}', **on_arc(0.63, 0.99)))

    d.append(progress_arc(ordered_progress, fill_opacity=0.5))
    d.append(progress_arc(paid_progress))
    if baseline > 0:
        d.append(progress_arc(baseline_progress, fill='#083c00'))

    # text center
    if goal > ordered:
        d.append(draw.Text('Noch', 0.1, 0, 0.3, center=True))
        d.append(
            draw.Text(str(goal - ordered),
                      0.3,
                      0,
                      0.12,
                      center=True,
                      font_weight='bold'))
        d.append(draw.Text('Anteilscheine', 0.09, 0, -0.1, center=True))
        # labels
        d.append(
            draw.Text(f'{ordered-baseline} neue\nbestellt',
                      **on_arc(0.7, ordered_progress)))
        d.append(
            draw.Text(f'{paid-baseline} neue\nbezahlt',
                      **on_arc(0.5, paid_progress, 'inner')))
        if baseline > 0:
            d.append(
                draw.Text(f'{baseline}\nbisher',
                          fill='white',
                          **on_arc(0.5, baseline_progress - 0.025)))
    else:
        d.append(draw.Text('Wir haben es', 0.09, 0, 0.14, center=True))
        d.append(
            draw.Text('Geschafft!',
                      0.18,
                      0,
                      0,
                      center=True,
                      font_weight='bold'))

    # Display
    d.setRenderSize(w='100%', h='100%')
    svg = d.asSvg()
    return svg[:-6] + """<style type="text/css">