Пример #1
0
    def test_circle_with_stroke(self):
        r = 5
        cx = 10
        cy = 20

        stroke_half_width = 1.0

        circle = Circle(r=str(r), cx=str(cx), cy=str(cy))

        circle.style = Style("stroke-width:{};stroke:red".format(stroke_half_width * 2))

        self.assert_bounding_box_is_equal(circle,
                                          (cx - (r + stroke_half_width), cx + (r + stroke_half_width)),
                                          (cy - (r + stroke_half_width), cy + (r + stroke_half_width)))
Пример #2
0
    def test_regular_circle(self):
        r = 5
        cx = 10
        cy = 20

        circle = Circle(r=str(r), cx=str(cx), cy=str(cy))

        self.assert_bounding_box_is_equal(circle, (cx - r, cx + r), (cy - r, cy + r))
Пример #3
0
 def draw_reg_circles(self, cx, cy, r, name, colours, parent):
     for i in range(len(colours)):
         style = {'stroke': colours[i], 'stroke-width': str(r / len(colours)),
                  'fill': 'none'}
         circle_attribs = {'style': str(inkex.Style(style)),
                           'inkscape:label': name,
                           'cx': str(cx), 'cy': str(cy),
                           'r': str((r / len(colours)) * (i + 0.5))}
         parent.add(Circle(**circle_attribs))
Пример #4
0
 def drawCircle(self, group, color, point):
     style = inkex.Style({'stroke': 'none', 'fill': color})
     startCircle = group.add(
         Circle(cx=str(point[0]),
                cy=str(point[1]),
                r=str(
                    self.svg.unittouu(str(self.options.dotsize / 2) +
                                      "px"))))
     startCircle.style = style
Пример #5
0
 def test_parse(self):
     """Test Circle parsed from XML"""
     circle = Circle(attrib={"cx": "10px", "cy": "20px", "r": "30px"})
     self.assertEqual(circle.center.x, 10)
     self.assertEqual(circle.center.y, 20)
     self.assertEqual(circle.radius, 30)
     ellipse = Ellipse(attrib={"cx": "10px", "cy": "20px", "rx": "30px", "ry": "40px"})
     self.assertEqual(ellipse.center.x, 10)
     self.assertEqual(ellipse.center.y, 20)
     self.assertEqual(ellipse.radius.x, 30)
     self.assertEqual(ellipse.radius.y, 40)
Пример #6
0
    def test_circle_with_stroke_scaled(self):
        r = 5
        cx = 10
        cy = 20

        scale_x = 2
        scale_y = 3

        stroke_half_width = 1.0

        circle = Circle(r=str(r), cx=str(cx), cy=str(cy))

        circle.style = Style("stroke-width:{};stroke:red".format(stroke_half_width * 2))

        circle.transform = Transform(scale=(scale_x, scale_y))

        self.assert_bounding_box_is_equal(circle,
                                          (scale_x * (cx - (r + stroke_half_width)),
                                           scale_x * (cx + (r + stroke_half_width))),
                                          (scale_y * (cy - (r + stroke_half_width)),
                                           scale_y * (cy + (r + stroke_half_width))))
Пример #7
0
 def generateCircle(self, x, y, r, strokeWidth, stroke, fill, name):
     circle = Circle()
     circle.center = (x, y)
     circle.radius = r
     circle.style = {
         'stroke': stroke,
         'stroke-width': strokeWidth,
         'fill': fill
     }
     circle.label = name
     return circle
Пример #8
0
    def add_dot(self, node):
        """Add a dot label for this path element"""
        group = node.getparent().add(inkex.Group())
        dot_group = group.add(inkex.Group())
        num_group = group.add(inkex.Group())
        group.transform = node.transform

        style = inkex.Style({'stroke': 'none', 'fill': '#000'})

        for step, (x, y) in enumerate(node.path.end_points):
            circle = dot_group.add(Circle(cx=str(x), cy=str(y),\
                    r=str(self.svg.unittouu(self.options.dotsize) / 2)))
            circle.style = style
            num_group.append(
                self.add_text(
                    x + (self.svg.unittouu(self.options.dotsize) / 2),
                    y - (self.svg.unittouu(self.options.dotsize) / 2),
                    self.options.start + (self.options.step * step)))

        node.delete()
Пример #9
0
def draw_SVG_circle(
        rad, centre, params, style, name, parent
):  # draw an SVG circle with a given radius as trilinear coordinates
    if rad == 0:  # we want a dot
        r = style.d_rad  # get the dot width from the style
        circ_style = {
            'stroke': style.d_col,
            'stroke-width': str(style.d_th),
            'fill': style.d_fill
        }
    else:
        r = rad  # use given value
        circ_style = {
            'stroke': style.c_col,
            'stroke-width': str(style.c_th),
            'fill': style.c_fill
        }

    cx, cy = get_cartesian_pt(centre, params)
    circ_attribs = {'cx': str(cx), 'cy': str(cy), 'r': str(r)}
    elem = parent.add(Circle(**circ_attribs))
    elem.style = circ_style
    elem.label = name
Пример #10
0
def draw_circle(r, cx, cy, width, fill, name, parent):
    """Draw an SVG circle"""
    circle = parent.add(Circle(cx=str(cx), cy=str(cy), r=str(r)))
    circle.style = {'stroke': '#000000', 'stroke-width': str(width), 'fill': fill}
    circle.label = name
Пример #11
0
    def scanContours(self, node):
        if node.tag == inkex.addNS('path', 'svg'):
            if self.options.removefillsetstroke:
                self.adjustStyle(node)

            intersectionGroup = node.getparent().add(inkex.Group())

            raw = (Path(node.get('d')).to_arrays())
            subPaths, prev = [], 0
            for i in range(
                    len(raw)):  # Breaks compound paths into simple paths
                if raw[i][0] == 'M' and i != 0:
                    subPaths.append(raw[prev:i])
                    prev = i
            subPaths.append(raw[prev:])

            for simpath in subPaths:
                closed = False
                if simpath[-1][0] == 'Z':
                    closed = True
                    if simpath[-2][0] == 'L': simpath[-1][1] = simpath[0][1]
                    else: simpath.pop()
                points = []
                for i in range(len(simpath)):
                    if simpath[i][
                            0] == 'V':  # vertical and horizontal lines only have one point in args, but 2 are required
                        simpath[i][
                            0] = 'L'  #overwrite V with regular L command
                        add = simpath[i - 1][1][
                            0]  #read the X value from previous segment
                        simpath[i][1].append(
                            simpath[i][1][0]
                        )  #add the second (missing) argument by taking argument from previous segment
                        simpath[i][1][
                            0] = add  #replace with recent X after Y was appended
                    if simpath[i][
                            0] == 'H':  # vertical and horizontal lines only have one point in args, but 2 are required
                        simpath[i][
                            0] = 'L'  #overwrite H with regular L command
                        simpath[i][1].append(
                            simpath[i - 1][1][1]
                        )  #add the second (missing) argument by taking argument from previous segment
                    points.append(simpath[i][1][-2:])
                if points[0] == points[
                        -1]:  #if first is last point the path is also closed. The "Z" command is not required
                    closed = True

                if closed == False:
                    if self.options.highlight_opened:
                        style = {
                            'stroke-linejoin':
                            'miter',
                            'stroke-width':
                            str(
                                self.svg.unittouu(
                                    str(self.options.strokewidth) + "px")),
                            'stroke-opacity':
                            '1.0',
                            'fill-opacity':
                            '1.0',
                            'stroke':
                            self.options.color_opened,
                            'stroke-linecap':
                            'butt',
                            'fill':
                            'none'
                        }
                        node.attrib['style'] = Style(style).to_str()
                    if self.options.remove_opened:
                        try:
                            node.delete()
                        except AttributeError:
                            pass  #we ignore that parent can be None
                if closed == True:
                    if self.options.highlight_closed:
                        style = {
                            'stroke-linejoin':
                            'miter',
                            'stroke-width':
                            str(
                                self.svg.unittouu(
                                    str(self.options.strokewidth) + "px")),
                            'stroke-opacity':
                            '1.0',
                            'fill-opacity':
                            '1.0',
                            'stroke':
                            self.options.color_closed,
                            'stroke-linecap':
                            'butt',
                            'fill':
                            'none'
                        }
                        node.attrib['style'] = Style(style).to_str()
                    if self.options.remove_closed:
                        try:
                            node.delete()
                        except AttributeError:
                            pass  #we ignore that parent can be None

                #if one of the options is activated we also check for self-intersecting
                if self.options.highlight_selfintersecting or self.options.highlight_intersectionpoints:

                    #Style definitions
                    closingLineStyle = Style({
                        'stroke-linejoin':
                        'miter',
                        'stroke-width':
                        str(
                            self.svg.unittouu(
                                str(self.options.strokewidth) + "px")),
                        'stroke-opacity':
                        '1.0',
                        'fill-opacity':
                        '1.0',
                        'stroke':
                        self.options.color_intersectionpoints,
                        'stroke-linecap':
                        'butt',
                        'fill':
                        'none'
                    }).to_str()

                    intersectionPointStyle = Style({
                        'stroke':
                        'none',
                        'fill':
                        self.options.color_intersectionpoints
                    }).to_str()

                    intersectionStyle = Style({
                        'stroke-linejoin':
                        'miter',
                        'stroke-width':
                        str(
                            self.svg.unittouu(
                                str(self.options.strokewidth) + "px")),
                        'stroke-opacity':
                        '1.0',
                        'fill-opacity':
                        '1.0',
                        'stroke':
                        self.options.color_selfintersecting,
                        'stroke-linecap':
                        'butt',
                        'fill':
                        'none'
                    }).to_str()

                    try:
                        if len(
                                points
                        ) > 2:  #try to find self-intersecting /overlapping polygons. We need at least 3 points to detect for intersections (only possible if first points matched last point)
                            isect = poly_point_isect.isect_polygon(points)
                            if len(isect) > 0:
                                if closed == False and self.options.addlines == True:  #if contour is open and we found intersection points those points might be not relevant
                                    closingLine = intersectionGroup.add(
                                        inkex.PathElement())
                                    closingLine.set(
                                        'id',
                                        self.svg.get_unique_id('closingline-'))
                                    closingLine.path = [[
                                        'M', [points[0][0], points[0][1]]
                                    ], ['L', [points[-1][0], points[-1][1]]],
                                                        ['Z', []]]
                                    closingLine.attrib[
                                        'style'] = closingLineStyle

                                #draw polylines if option is enabled
                                if self.options.polypaths == True:
                                    polyNode = intersectionGroup.add(
                                        inkex.PathElement())
                                    polyNode.set(
                                        'id',
                                        self.svg.get_unique_id('polypath-'))
                                    polyNode.set('d',
                                                 str(self.getPolyline(node)))
                                    polyNode.attrib['style'] = closingLineStyle

                                #make dot markings at the intersection points
                                if self.options.highlight_intersectionpoints:
                                    for xy in isect:
                                        #Add a dot label for this path element
                                        intersectionPoint = intersectionGroup.add(
                                            Circle(cx=str(xy[0]),
                                                   cy=str(xy[1]),
                                                   r=str(
                                                       self.svg.unittouu(
                                                           str(self.options.
                                                               dotsize / 2) +
                                                           "px"))))
                                        intersectionPoint.set(
                                            'id',
                                            self.svg.get_unique_id(
                                                'intersectionpoint-'))
                                        intersectionPoint.style = intersectionPointStyle

                                if self.options.highlight_selfintersecting:
                                    node.attrib['style'] = intersectionStyle
                                if self.options.remove_selfintersecting:
                                    if node.getparent(
                                    ) is not None:  #might be already been deleted by previously checked settings so check again
                                        node.delete()

                        #draw intersections segment lines - useless at the moment. We could use this information to cut the original polyline to get a new curve path which included the intersection points
                        #isectSegs = poly_point_isect.isect_polygon_include_segments(points)
                        #for seg in isectSegs:
                        #    isectSegsPath = []
                        #    isecX = seg[0][0] #the intersection point - X
                        #    isecY = seg[0][1] #the intersection point - Y
                        #    isecSeg1X = seg[1][0][0][0] #the first intersection point segment - X
                        #    isecSeg1Y = seg[1][0][0][1] #the first intersection point segment - Y
                        #    isecSeg2X = seg[1][1][0][0] #the second intersection point segment - X
                        #    isecSeg2Y = seg[1][1][0][1] #the second intersection point segment - Y
                        #    isectSegsPath.append(['L', [isecSeg2X, isecSeg2Y]])
                        #    isectSegsPath.append(['L', [isecX, isecY]])
                        #    isectSegsPath.append(['L', [isecSeg1X, isecSeg1Y]])
                        #    #fix the really first point. Has to be an 'M' command instead of 'L'
                        #    isectSegsPath[0][0] = 'M'
                        #    polySegsNode = intersectionGroup.add(inkex.PathElement())
                        #    polySegsNode.set('id', self.svg.get_unique_id('intersectsegments-'))
                        #    polySegsNode.set('d', str(Path(isectSegsPath)))
                        #    polySegsNode.attrib['style'] = closingLineStyle

                    except AssertionError as e:  # we skip AssertionError
                        if self.options.show_debug is True:
                            inkex.utils.debug("AssertionError at " +
                                              node.get('id'))
                        continue
                    except IndexError as i:  # we skip IndexError
                        if self.options.show_debug is True:
                            inkex.utils.debug("IndexError at " +
                                              node.get('id'))
                        continue
                #if the intersectionGroup was created but nothing attached we delete it again to prevent messing the SVG XML tree
                if len(intersectionGroup.getchildren()) == 0:
                    intersectionGroupParent = intersectionGroup.getparent()
                    if intersectionGroupParent is not None:
                        intersectionGroup.delete()
                #put the node into the intersectionGroup to bundle the path with it's error markers. If removal is selected we need to avoid intersectionGroup.insert(), because it will break the removal
                elif self.options.remove_selfintersecting == False:
                    intersectionGroup.insert(0, node)
        children = node.getchildren()
        if children is not None:
            for child in children:
                self.scanContours(child)
Пример #12
0
    def render_pie(self, keys, values, pie_abs=False):
        """Draw pie chart"""
        pie_radius = self.options.pie_radius

        # Iterate all values to draw the different slices
        color = 0
        x = float(self.width) / 2
        y = float(self.height) / 2

        # Create the shadow first (if it should be created):
        if self.blur:
            shadow = Circle(cx=str(x), cy=str(y))
            shadow.set('r', str(pie_radius))
            shadow.style = self.blur + inkex.Style(fill='#000000')
            yield shadow

        # Add a grey background circle with a light stroke
        background = Circle(cx=str(x), cy=str(y))
        background.set("r", str(pie_radius))
        background.set("style", "stroke:#ececec;fill:#f9f9f9")
        yield background

        # create value sum in order to divide the slices
        try:
            valuesum = sum(values)
        except ValueError:
            valuesum = 0

        if pie_abs:
            valuesum = 100

        # Set an offsetangle
        offset = 0

        # Draw single slices
        for cnt, value in enumerate(values):
            # Calculate the PI-angles for start and end
            angle = (2 * 3.141592) / valuesum * float(value)
            start = offset
            end = offset + angle

            # proper overlapping
            if self.options.segment_overlap:
                if cnt != len(values) - 1:
                    end += 0.09  # add a 5° overlap
                if cnt == 0:
                    start -= 0.09  # let the first element overlap into the other direction

            # then add the slice
            pieslice = inkex.PathElement()
            pieslice.set('sodipodi:type', 'arc')
            pieslice.set('sodipodi:cx', x)
            pieslice.set('sodipodi:cy', y)
            pieslice.set('sodipodi:rx', pie_radius)
            pieslice.set('sodipodi:ry', pie_radius)
            pieslice.set('sodipodi:start', start)
            pieslice.set('sodipodi:end', end)
            pieslice.set(
                "style",
                "fill:" + self.get_color() + ";stroke:none;fill-opacity:1")
            ang = angle / 2 + offset

            # If text is given, draw short paths and add the text
            if keys:
                elem = inkex.PathElement()
                elem.path = [
                    Move(
                        (self.width / 2) + pie_radius * math.cos(ang),
                        (self.height / 2) + pie_radius * math.sin(ang),
                    ),
                    line(
                        (self.options.text_offset - 2) * math.cos(ang),
                        (self.options.text_offset - 2) * math.sin(ang),
                    ),
                ]

                elem.style = {
                    'fill': 'none',
                    'stroke': self.options.font_color,
                    'stroke-width': self.options.stroke_width,
                    'stroke-linecap': 'butt',
                }
                yield elem

                label = keys[cnt]
                if self.options.show_values:
                    label += ' ({}{})'.format(str(value), ('', '%')[pie_abs])

                # check if it is right or left of the Pie
                anchor = 'start' if math.cos(ang) > 0 else 'end'
                text = self.draw_text(label, anchor=anchor)

                off = pie_radius + self.options.text_offset
                text.set("x", (self.width / 2) + off * math.cos(ang))
                text.set("y", (self.height / 2) + off * math.sin(ang) +
                         self.fontoff)
                yield text

            # increase the rotation-offset and the colorcycle-position
            offset = offset + angle
            color = (color + 1) % 8

            # append the objects to the extension-layer
            yield pieslice

        yield self.draw_header(self.width / 2 - pie_radius)
Пример #13
0
 def test_circle_without_center(self):
     r = 10
     circle = Circle(r=str(r))
     self.assert_bounding_box_is_equal(circle, (-r, r), (-r, r))
Пример #14
0
 def test_circle_with_cy(self):
     cy = 10
     circle = Circle(cy=str(cy))
     self.assert_bounding_box_is_equal(circle, (0, 0), (cy, cy))
Пример #15
0
 def test_circle_with_cx(self):
     cx = 10
     circle = Circle(cx=str(cx))
     self.assert_bounding_box_is_equal(circle, (cx, cx), (0, 0))
Пример #16
0
 def test_circle_without_attributes(self):
     circle = Circle()
     self.assert_bounding_box_is_equal(circle, (0, 0), (0, 0))
Пример #17
0
 def test_new(self):
     """Test new circles"""
     elem = Circle.new((10, 10), 50)
     self.assertElement(elem, b'<circle cx="10.0" cy="10.0" r="50.0"/>')
     elem = Ellipse.new((10, 10), (15, 10))
     self.assertElement(elem, b'<ellipse cx="10.0" cy="10.0" rx="15.0" ry="10.0"/>')