Esempio n. 1
1
class Gauge(object):
    config = {
        'id'                    : None,
        'title'                 : 'Title',
        'titleFontColor'        : '#999999',
        'value'                 : 0,
        'valueFontColor'        : '#010101',
        'min'                   : 0,
        'max'                   : 100,
        'showMinMax'            : True,
        'gaugeWidthScale'       : 1.0,
        'gaugeColor'            : '#edebeb',
        'label'                 : "",
        'showInnerShadow'       : True,
        'shadowOpacity'         : 0.2,
        'shadowSize'            : 5,
        'shadowVerticalOffset'  : 3,
        'levelColors'           : ["#a9d70b", "#f9c802", "#ff0000"],
        'levelColorsGradient'   : True,
        'labelFontColor'        : "#b3b3b3",
        'showNeedle'            : False,
        'needleColor'           : "#b3b3b3",
        'canvasWidth'           : 400,
        'canvasHeight'          : 300,
    }

    def __init__(self, *args, **kwargs):
        for param_name, param_value in kwargs.items():
            if self.config.has_key(param_name):
                self.config[param_name] = param_value

        # Overflow values
        if self.config['value'] > self.config['max']:
            self.config['value'] = self.config['max']
        if self.config['value'] < self.config['min']:
            self.config['value'] = self.config['min']
        self.originalValue = self.config['value']

        self.canvas = Drawing(size=(self.config['canvasWidth'],
                                    self.config['canvasHeight']))

        canvasW = self.config['canvasWidth']
        canvasH = self.config['canvasHeight']

        self.canvas.add(self.canvas.rect(insert=(0, 0),
                                         size=(canvasW, canvasH),
                                         stroke="none",
                                         fill="#ffffff"))

        # widget dimensions
        widgetW, widgetH = None, None
        if ((canvasW / canvasH) > 1.25):
            widgetW = 1.25 * canvasH
            widgetH = canvasH
        else:
            widgetW = canvasW
            widgetH = canvasW / 1.25

        # delta 
        dx = (canvasW - widgetW)/2
        dy = (canvasH - widgetH)/2

        # title 
        titleFontSize = ((widgetH / 8) > 10) and (widgetH / 10) or 10
        titleX = dx + widgetW / 2
        titleY = dy + widgetH / 6.5

        # value 
        valueFontSize = ((widgetH / 6.4) > 16) and (widgetH / 6.4) or 16
        valueX = dx + widgetW / 2
        valueY = dy + widgetH / 1.4

        # label 
        labelFontSize = ((widgetH / 16) > 10) and (widgetH / 16) or 10
        labelX = dx + widgetW / 2
        labelY = valueY + valueFontSize / 2 + 6

        # min 
        minFontSize = ((widgetH / 16) > 10) and (widgetH / 16) or 10
        minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * self.config['gaugeWidthScale']) / 2
        minY = dy + widgetH / 1.126760563380282

        # max
        maxFontSize = ((widgetH / 16) > 10) and (widgetH / 16) or 10
        maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * self.config['gaugeWidthScale']) / 2
        maxY = dy + widgetH / 1.126760563380282

        # parameters
        self.params = {
            'canvasW'         : canvasW,
            'canvasH'         : canvasH,
            'widgetW'         : widgetW,
            'widgetH'         : widgetH,
            'dx'              : dx,
            'dy'              : dy,
            'titleFontSize'   : titleFontSize,
            'titleX'          : titleX,
            'titleY'          : titleY,
            'valueFontSize'   : valueFontSize,
            'valueX'          : valueX,
            'valueY'          : valueY,
            'labelFontSize'   : labelFontSize,
            'labelX'          : labelX,
            'labelY'          : labelY,
            'minFontSize'     : minFontSize,
            'minX'            : minX,
            'minY'            : minY,
            'maxFontSize'     : maxFontSize,
            'maxX'            : maxX,
            'maxY'            : maxY
        }

        # gauge
        self.gauge = self.gauge_path(self.config['max'], self.config['min'], self.config['max'],
                                     self.params['widgetW'], self.params['widgetH'], self.params['dx'],
                                     self.params['dy'], self.config['gaugeWidthScale'],
                                     stroke='none',
                                     fill=self.config['gaugeColor'])

        self.canvas.add(self.gauge)

        # level
        percent_value = (self.config['value'] - self.config['min']) / (self.config['max'] - self.config['min'])
        self.level = self.gauge_path(self.config['value'], self.config['min'], self.config['max'],
                                     self.params['widgetW'], self.params['widgetH'], self.params['dx'],
                                     self.params['dy'], self.config['gaugeWidthScale'],
                                     stroke='none',
                                     fill=self.get_color_for_value(percent_value,
                                                                   self.config['levelColors'],
                                                                   self.config['levelColorsGradient']))
        self.canvas.add(self.level)

        # needle
        if self.config['showNeedle']:
            self.needle = self.needle_path(self.config['value'], self.config['min'], self.config['max'],
                                           self.params['widgetW'], self.params['widgetH'], self.params['dx'],
                                           self.params['dy'], self.config['gaugeWidthScale'],
                                           stroke='none',
                                           fill=self.config['needleColor'])
            self.canvas.add(self.needle)

        # Value
        else:
            text_config = {
                "font-size"     : "%d" % self.params['valueFontSize'],
                "font-weight"   : "bold",
                "font-family"   : "Arial",
                "fill"          : self.config['valueFontColor'],
                "fill-opacity"  : "1",
                "text-anchor"  : 'middle'
            }
            value_text = self.canvas.text('',
                                          insert=('%d' % self.params['valueX'],
                                                  '%d' % self.params['valueY']),
                                          **text_config)
            value_tspan = self.canvas.tspan(self.originalValue,
                                            dy=[8])
            value_text.add(value_tspan)
            self.canvas.add(value_text)

        # Add min & max value
        self.show_minmax()


    def save(self, path):
        svg = self.canvas.tostring()
        svg2png = getattr(cairosvg, 'svg2png')
        png_byte = svg2png(bytestring=svg)
        f = open(path,'w')
        f.write(png_byte)
        f.close()


    def gauge_path(self, value, val_min, val_max, w, h, dx, dy, gws, **extra):
        alpha = (1 - (value - val_min) / (val_max - val_min)) * math.pi
        Ro = w / 2 - w / 10
        Ri = Ro - w / 6.666666666666667 * gws
        Cx = w / 2 + dx
        Cy = h / 1.25 + dy

        Xo = w / 2 + dx + Ro * math.cos(alpha)
        Yo = h - (h - Cy) + dy - Ro * math.sin(alpha)
        Xi = w / 2 + dx + Ri * math.cos(alpha)
        Yi = h - (h - Cy) + dy - Ri * math.sin(alpha)

        path = []
        path.append(u"M%d,%d " % ((Cx - Ri), Cy))
        path.append(u"L%d,%d " % ((Cx - Ro), Cy))
        path.append(u"A%d,%d 0 0,1 %d,%d " % (Ro, Ro, Xo, Yo))
        path.append(u"L%d,%d " % (Xi, Yi))
        path.append(u"A%d,%d 0 0,0 %d,%d " % (Ri, Ri, (Cx - Ri), Cy))
        path.append(u"z ")

        return Path(d=path, **extra)

    def needle_path(self, value, val_min, val_max, w, h, dx, dy, gws, **extra):
        xO = w / 2 + dx
        yO = h / 1.25 + dy

        Rext = w / 2 - w / 10
        Rint = Rext - w / 6.666666666666667 * gws

        x_offset = xO
        y_offset = h - (h - yO) + dy

        val = (value - val_min) / (val_max - val_min)

        angle_b = val<0.5 and val*math.pi or (math.pi - val*math.pi) # Angle de la pointe
        angle_a = math.pi/2 - angle_b
        angle_c = math.pi/2 - angle_b

        rayon_base = 7
        rayon_b = Rint + (Rext-Rint)*10/100

        xA = x_offset + -1 * rayon_base * math.cos(angle_a)
        yA = y_offset - (val<0.5 and -1 or 1) * rayon_base * math.sin(angle_a)

        xC = x_offset + 1 * rayon_base * math.cos(angle_c)
        yC = y_offset - (val<0.5 and 1 or -1) * rayon_base * math.sin(angle_c)

        xB = x_offset + (val<0.5 and -1 or 1) * rayon_b * math.cos(angle_b)
        yB = y_offset - rayon_b * math.sin(angle_b)

        path = []
        path.append(u"M%d,%d " % (xA, yA))
        path.append(u"L%d,%d " % (xB, yB))
        path.append(u"L%d,%d " % (xC, yC))
        path.append(u"A%d,%d 0 1,1 %d,%d " % (rayon_base, rayon_base, xA, yA))
        path.append(u"z ")

        return Path(d=path, **extra)

    def get_color_for_value(self, pct, color, grad):
        no = len(color);
        if no == 1: return color[0]

        HEX = r'[a-fA-F\d]{2}'
        HEX_COLOR = r'#(?P<red>%(hex)s)(?P<green>%(hex)s)(?P<blue>%(hex)s)' % {'hex': HEX}
        inc = grad and (1 / (no - 1)) or (1 / no)
        colors = []
        i = 0
        while i < no:
            percentage = (grad) and (inc * i) or (inc * (i + 1))
            parts = re.match(HEX_COLOR,color[i]).groupdict()

            rval = int(parts['red'], 16)
            gval = int(parts['green'], 16)
            bval = int(parts['blue'], 16)
            colors.append({
                'pct': percentage,
                'color': {
                    'r': rval,
                    'g': gval,
                    'b': bval
                 }
            })
            i+=1

        if pct == 0:
            return 'rgb(%d,%d,%d)' % (colors[0]['color']['r'],
                                      colors[0]['color']['g'],
                                      colors[0]['color']['b'])

        i = 0
        while i < len(colors):
            if pct <= colors[i]['pct']:
                if (grad == True):
                    lower = colors[i-1]
                    upper = colors[i]
                    _range = upper['pct'] - lower['pct']
                    rangePct = (pct - lower['pct']) / _range
                    pctLower = 1 - rangePct
                    pctUpper = rangePct
                    color = {
                      'r': math.floor(lower['color']['r'] * pctLower + upper['color']['r'] * pctUpper),
                      'g': math.floor(lower['color']['g'] * pctLower + upper['color']['g'] * pctUpper),
                      'b': math.floor(lower['color']['b'] * pctLower + upper['color']['b'] * pctUpper)
                    }
                    return 'rgb(%d,%d,%d)' % (color['r'], color['g'], color['b'])
                else:
                    return 'rgb(%d,%d,%d)' % (colors[i]['color']['r'],
                                              colors[i]['color']['g'],
                                              colors[i]['color']['b']) 
            i+=1

    def show_minmax(self):
        # min
        txtMin_config = {
            "font-size"    : '%d' % self.params['minFontSize'],
            "font-weight"  : "normal",
            "font-family"  : "Arial",
            "fill"         : self.config['labelFontColor'],
            "fill-opacity" : self.config['showMinMax'] and "1" or "0",
            "text-anchor"  : 'middle'
        }
        txtMin = self.canvas.text(self.config['min'],
                                  insert=(self.params['minX'],
                                          self.params['minY']),
                                  **txtMin_config)

        self.canvas.add(txtMin)

        # max
        txtMax_config = {
            "font-size"    : '%d' % self.params['maxFontSize'],
            "font-weight"  :"normal",
            "font-family"  :"Arial",
            "fill"         : self.config['labelFontColor'],   
            "fill-opacity" : self.config['showMinMax'] and "1" or "0",
            "text-anchor"  : 'middle'
        }
        txtMax = self.canvas.text(self.config['max'],
                                  insert=(self.params['maxX'],
                                          self.params['maxY']),
                                  **txtMax_config)
        self.canvas.add(txtMax)
Esempio n. 2
0
def save_radial_tree_plot(filename, root_list, step_size):
    
    #  define some params
    white = "rgb(255, 255, 255)"
    black = "rgb(0, 0, 0)"

    #  create the drawing surface
    svg_drawing = Drawing(
        filename=filename,
        size=(SVG_SIZE, SVG_SIZE),
        debug=True)
    

    #  create defs, in this case, just a single gradient
    rad_grad = svg_drawing.radialGradient(("50%", "50%"), "100%", ("50%", "50%"), id="rad_grad")
    rad_grad.add_stop_color("0%", black, 255)
    rad_grad.add_stop_color("100%", white, 255)
    svg_drawing.defs.add(rad_grad)
    
    tree_plot = svg_drawing.mask(
        id='treeplot',
        style='stroke: black; stroke-width: 3; fill: none; stroke-linecap: round; stroke-opacity: 0.5;')  
    
    tree_plot.add(svg_drawing.rect( (0, 0), (SVG_SIZE, SVG_SIZE) ).fill(white))

    for root in root_list:
        draw_radial_tree_node(svg_drawing, tree_plot, root, rad_grad, step_size)    
    
    base_rect = svg_drawing.rect( (0, 0), (SVG_SIZE, SVG_SIZE), mask="url(#treeplot)").fill(black)
    svg_drawing.add(base_rect)  
    svg_drawing.add(tree_plot)

    svg_drawing.save()  
Esempio n. 3
0
def add_grid(obj: svgwrite.Drawing, s=10):
    """
    function to add grid to SVG drawing, must be called after set_bg_color if used
    :param obj: svgwrite.Drawing object
    :param s: grid step
    :return: None
    """
    pattern_small_grid = obj.pattern(insert=None, size=(s, s), patternUnits='userSpaceOnUse')
    pattern_small_grid.attribs['id'] = "smallGrid"
    path_small = obj.path(f'M {s} 0 L 0 0 0 {s}', stroke='gray', fill='none', style=f'stroke-width:{0.5}')
    pattern_small_grid.add(path_small)

    pattern_large_grid = obj.pattern(insert=None, size=(s * 10, s * 10), patternUnits='userSpaceOnUse')
    pattern_large_grid.attribs['id'] = "grid"
    path_large = obj.path(f'M {s * 10} 0 L 0 0 0 {s * 10}', stroke='gray', fill='none', style=f'stroke-width:{1}')
    pattern_large_grid.add(path_large)

    rect_large = obj.rect(fill="url(#smallGrid)", size=(s * 10, s * 10))
    pattern_large_grid.add(rect_large)

    obj.defs.add(pattern_small_grid)
    obj.defs.add(pattern_large_grid)

    rect_grid = obj.rect(size=('100%', '100%'), fill="url(#grid)")
    obj.add(rect_grid)
Esempio n. 4
0
def _draw_measure_gate(drawing: Drawing,
                       bit_gate_rank: BitRankType,
                       measured_qubit: int,
                       target_clbit: int,
                       show_clbits: bool,
                       bit_mapping: dict) -> None:
    index_to_draw, _ = _helpers.get_max_index(bit_gate_rank,
                                              qubits=[measured_qubit],
                                              clbits=[target_clbit])

    x_coord = _helpers.get_x_from_index(index_to_draw)
    yq_coord = _helpers.get_y_from_quantum_register(measured_qubit, bit_mapping)
    if show_clbits:
        yc_coord = _helpers.get_y_from_classical_register(target_clbit,
                                                          len(bit_gate_rank['qubits']),
                                                          bit_mapping)
        # Draw the line between the 2 bits
        _draw_classical_double_line(drawing, x_coord, yq_coord, x_coord, yc_coord)

        # Draw the little thing that tell where we put the measure.
        drawing.add(drawing.rect(insert=(x_coord - _constants.MEASURE_GATE_CLBIT_SIZE/2,
                                         yc_coord - _constants.MEASURE_GATE_CLBIT_SIZE/2),
                                 size=(_constants.MEASURE_GATE_CLBIT_SIZE,
                                       _constants.MEASURE_GATE_CLBIT_SIZE),
                                 fill=_constants.MEASURE_GATE_CLBIT_FILL_COLOR,
                                 stroke=_constants.GATE_BORDER_COLOR,
                                 stroke_width=_constants.STROKE_THICKNESS))
        # Draw the "measure" gate.
        _draw_unitary_gate(drawing, bit_gate_rank, measured_qubit, "M",
                           bit_mapping, index_to_draw=index_to_draw)

    else:
        # Draw the "measure" gate.
        _draw_unitary_gate(drawing, bit_gate_rank, measured_qubit, "M" + str(target_clbit),
                           bit_mapping, index_to_draw=index_to_draw)
Esempio n. 5
0
    def draw_legend(self,
                    image: Drawing,
                    legend_title: str,
                    top: int,
                    range_max: float,
                    range_min: int = 0):
        # Generate up to 5 integer steps
        step = int(ceil((range_max - range_min) / 5))

        image.add(
            image.text(legend_title,
                       insert=(self.legend_grid['left'],
                               top + 3 * self.legend_grid['cell_height'] / 4),
                       class_='legend_title'))
        steps = list(range(range_min, int(range_max + 1), step))
        if max(steps) != int(range_max):
            steps.append(int(range_max))

        for offset, marker in enumerate(steps):
            left = self.legend_grid['left'] + offset * self.legend_grid['pitch']
            image.add(
                image.rect(
                    (left, top), (self.legend_grid['cell_width'],
                                  self.legend_grid['cell_height']),
                    fill=self.fractional_fill_color(
                        (marker - range_min) / (range_max - range_min))))
            image.add(
                image.text(
                    marker,
                    insert=(left + self.legend_grid['cell_width'] / 2,
                            top + 3 * self.legend_grid['cell_height'] / 4),
                    class_='key',
                    fill='#ffffff' if marker > range_max / 2 else '#000000'))
Esempio n. 6
0
def box_with_char(
    drawing: svgwrite.Drawing,
    text: str,
    x=0,
    y=0,
    width=BOX_SIZE,
    height=BOX_SIZE,
    border_width=BORDER_WIDTH,
    fill="#fff",
    border="#888",
    char_width=4,
    char_height=12,
):
    """Render a box with a single character inside of it"""
    drawing.add(
        drawing.rect(
            insert=(x, y),
            size=(width, height),
            fill=fill,
            stroke=border,
            stroke_width=border_width,
        ))
    text_x = x - char_width * len(str(text)) + width // 2
    text_y = y + height // 2 + char_height // 2
    drawing.add(
        drawing.text(text,
                     insert=(text_x, text_y),
                     fill=svgwrite.rgb(50, 50, 50)))
Esempio n. 7
0
def draw_big(x: int, y: int, dwg: svgwrite.Drawing, weather: WeatherForecast, air_quality: AirQuality,
             icons_location: str):
    shapes = dwg.add(dwg.g(id='shapes'))

    shapes.add(dwg.rect(insert=(x, y), size=(360 * px, 300 * px),
                        fill='white', stroke='black', stroke_width=1))

    paragraph = dwg.add(dwg.g(font_size=120))
    paragraph.add(dwg.text(f"{weather.temperature}°", (x + 240, y + 110), text_anchor="middle"))

    location = os.path.abspath(f"{icons_location}/{weather.summary.value}.svg")
    image = dwg.add(
        dwg.image(href=location, insert=(x + 5, y + 5),
                  size=(120 * px, 120 * px)))

    feels_like_text = dwg.add(dwg.g(font_size=36, font_family="Helvetica"))
    feels_like_text.add(dwg.text(f"Air quality: {air_quality}", (x + 10, y + 165)))

    wind_text = dwg.add(dwg.g(font_size=36, font_family="Helvetica"))
    wind_text.add(dwg.text(f"{weather.wind_name} {weather.wind_mps} m/s", (x + 10, y + 205), textLength=340))

    precipitation_text = dwg.add(dwg.g(font_size=36, font_family="Helvetica"))
    precipitation_text.add(dwg.text(f"{weather.precip_name} {weather.precip_mm} mm/h", (x + 10, y + 245)))

    pressure_text = dwg.add(dwg.g(font_size=36, font_family="Helvetica"))
    pressure_text.add(dwg.text(f"{int(weather.air_pressure)} hPa", (x + 10, y + 285)))
Esempio n. 8
0
def _draw_gate_rect(drawing: Drawing, x_coord: float, y_coord: float) -> None:
    anchor = tuple((x_coord - _constants.GATE_SIZE / 2,
                    y_coord - _constants.GATE_SIZE / 2))
    drawing.add(drawing.rect(insert=anchor,
                             size=(_constants.GATE_SIZE, _constants.GATE_SIZE),
                             fill=_constants.GATE_FILL_COLOR,
                             stroke=_constants.GATE_BORDER_COLOR,
                             stroke_width=_constants.STROKE_THICKNESS))
Esempio n. 9
0
def set_bg_color(obj: svgwrite.Drawing, plant_model):
    """
    function to set background color for SVG drawing must be called before function add_grid if it used
    :param obj: drawing t oset color on
    :param plant_model: PlantModel proteus object
    :param ctx: model context
    :return: None
    """
    bg_color = fetch_color_from_presentation(plant_model.find('Drawing').find('Presentation'))
    bg_color_rect = obj.rect((0, 0), ('100%', '100%'), fill=bg_color)
    obj.add(bg_color_rect)
Esempio n. 10
0
def leg_foot() -> str:
    drawing = Drawing()

    r = drawing.rect((-50, -50), (200, 200), stroke="black", fill="white")
    drawing.add(r)

    a = LegWithFoot(leg_length=50, leg_color="#606060", foot_color="#ff0000")
    g = a.render(drawing)
    g.translate(50, 50)

    drawing.add(g)
    return drawing.tostring()
Esempio n. 11
0
def arm_hand() -> str:
    drawing = Drawing()

    r = drawing.rect((-50, -50), (200, 200), stroke="black", fill="white")
    drawing.add(r)

    a = ArmWithHand(arm_length=50, arm_color="#606060", hand_color="#ff0000")
    g = a.render(drawing)
    g.translate(50, 50)

    drawing.add(g)
    return drawing.tostring()
Esempio n. 12
0
def draw_calendar(x: int, y: int, dwg: svgwrite.Drawing,
                  lines: List[str]):
    shapes = dwg.add(dwg.g())

    shapes.add(dwg.rect(insert=(x, y), size=(460 * px, 330 * px),
                        fill='white', stroke='black', stroke_width=1))

    offset = 35
    for line in lines:
        date_text = dwg.add(dwg.g(font_size=36, font_family="Helvetica"))
        date_text.add(dwg.text(line, (10 + x, offset + y)))
        offset += 40
Esempio n. 13
0
    def render(self, dwg: Drawing) -> Group:
        r = dwg.rect(insert=(0, 0),
                     size=(self.width, self.height),
                     fill=self.color)
        g = dwg.g()
        g.add(r)

        star_count = int(self.width * self.height * .001)
        for i in range(star_count):
            s = dwg.circle(center=(self.prng.randint(0, self.width),
                                   self.prng.randint(0, self.height)),
                           r=max(2, self.prng.gauss(1, 1)),
                           fill="white")
            g.add(s)

        return g
Esempio n. 14
0
def square_in_grid(image: Drawing,
                   row: int,
                   column: int,
                   fill,
                   offsets=(),
                   title=None):
    x_offset = offsets[0] if len(offsets) else 0
    y_offset = offsets[1] if len(offsets) > 1 else 0
    left = grid_square_left(column, x_offset)
    top = grid_square_top(row, y_offset)
    rect = image.rect(insert=(left, top),
                      size=(GRID_SQUARE, GRID_SQUARE),
                      fill=fill)
    if title is not None:
        rect.set_desc(title=title)
    return rect
Esempio n. 15
0
def create_empty_chart(full_file_name):
    """Creates a chart of the proper dimensions with a white background."""
    num_days_in_week = 7
    num_weeks = math.ceil(NUM_DAYS_TO_SHOW / 7.0)
    if date.today().weekday() + 1 < NUM_DAYS_TO_SHOW % 7:
        # We need to draw NUM_DAYS_TO_SHOW % 7 extra days, but on the last week
        # we have only space for date.today().weekday() + 1 days.
        num_weeks += 1

    width = 2 * MARGIN + num_weeks * DAY_BOX_SIZE + \
        (num_weeks - 1) * DAY_BOX_SEPARATION
    height = 2 * MARGIN + num_days_in_week * DAY_BOX_SIZE + \
        (num_days_in_week - 1) * DAY_BOX_SEPARATION

    chart = Drawing(full_file_name, size=(width, height))
    chart.add(chart.rect(insert=(0, 0), size=(width, height), fill='white'))
    return chart
Esempio n. 16
0
def draw_small(x: int, y: int, dwg: svgwrite.Drawing, time: str, weather: WeatherForecast, icons_location: str):
    shapes = dwg.add(dwg.g())

    shapes.add(dwg.rect(insert=(x, y), size=(220 * px, 145 * px),
                        fill='white', stroke='black', stroke_width=1))

    date_text = dwg.add(dwg.g(font_size=35, font_family="Helvetica"))
    date_text.add(dwg.text(time, (10 + x, 35 + y)))

    paragraph = dwg.add(dwg.g(font_size=55))
    paragraph.add(dwg.text(f"{weather.temperature}°", (x + 135, y + 90), text_anchor="middle"))

    location = os.path.abspath(f"{icons_location}/{weather.summary.value}.svg")
    image = dwg.add(
        dwg.image(href=location,
                  insert=(10 + x, 45 + y), size=(55 * px, 55 * px)))

    pressure_text = dwg.add(dwg.g(font_size=36, font_family="Helvetica"))
    pressure_text.add(dwg.text(f"{int(weather.air_pressure)} hPa", (10 + x, 130 + y)))
Esempio n. 17
0
def create_svg_image(styles, board_size, hexagons):
    """
    Creates SVG drawing.

    The drawing contains all given css styles, a board (background rectangle)
    of given size and all given hexagons. The board can be styled using '.board'.
    All hexagonal fields can be styled using '.hex-field'. Fields can be also
    styled using 'hex-field-X', where X is the type of the field.
    :param styles iterable of css styles (strings)
    :param board_size tuple representing board size (width, height)
    :param hexagons iterable of hexagons (tuples in a form of (vertices, type) )
    :returns SVG Drawing object
    """
    svg_image = Drawing()
    for style in styles:
        svg_image.add(svg_image.style(style))
    svg_image.add(svg_image.rect(size=board_size, class_="board"))
    for hexagon in hexagons:
        svg_image.add(svg_image.polygon(hexagon.vertices, class_="hex-field hex-field-%d" % hexagon.type))
    return svg_image
Esempio n. 18
0
    def render(self,
               size: Tuple[int, int] = (512, 512),
               view_box: str = "-0.5 -0.5 1.0 1.0",
               **extra) -> Drawing:
        drawing = Drawing("", size, viewBox=view_box, **extra)

        for view in self.views:
            projection = np.dot(view.camera.view, view.camera.projection)

            clip_path = drawing.defs.add(drawing.clipPath())
            clip_min = view.viewport.minx, view.viewport.miny
            clip_size = view.viewport.width, view.viewport.height
            clip_path.add(drawing.rect(clip_min, clip_size))

            # TODO: Handle Z-index with meshes
            for group in view.scene.groups:
                for g in self._create_group(drawing, projection, view.viewport,
                                            group):
                    g["clip-path"] = clip_path.get_funciri()
                    drawing.add(g)
        return drawing
Esempio n. 19
0
def display_svg():
    dwg = Drawing()
    hlines = dwg.add(dwg.g(id="hlines", stroke="green"))
    for y in range(20):
        hlines.add(
            dwg.line(start=(2 * cm, (2 + y) * cm),
                     end=(18 * cm, (2 + y) * cm)))
    vlines = dwg.add(dwg.g(id="vline", stroke="blue"))
    for x in range(17):
        vlines.add(
            dwg.line(start=((2 + x) * cm, 2 * cm),
                     end=((2 + x) * cm, 21 * cm)))
    shapes = dwg.add(dwg.g(id="shapes", fill="red"))

    # set presentation attributes at object creation as SVG-Attributes
    circle = dwg.circle(center=(15 * cm, 8 * cm),
                        r="2.5cm",
                        stroke="blue",
                        stroke_width=3)
    circle["class"] = "class1 class2"
    shapes.add(circle)

    # override the 'fill' attribute of the parent group 'shapes'
    shapes.add(
        dwg.rect(
            insert=(5 * cm, 5 * cm),
            size=(45 * mm, 45 * mm),
            fill="blue",
            stroke="red",
            stroke_width=3,
        ))

    # or set presentation attributes by helper functions of the Presentation-Mixin
    ellipse = shapes.add(
        dwg.ellipse(center=(10 * cm, 15 * cm), r=("5cm", "10mm")))
    ellipse.fill("green", opacity=0.5).stroke("black",
                                              width=5).dasharray([20, 20])

    return Response(dwg.tostring(), mimetype="image/svg+xml")
Esempio n. 20
0
    def render(self, dwg: Drawing) -> Group:
        g = dwg.g()

        head = self.head.render(dwg)

        socket_relative_width = 1.2

        socket_radius = (self.head_size * socket_relative_width, self.head_size*0.3)
        socket_relative_height = .3

        socket_left = (-self.head_size * socket_relative_width, self.head_size * .5)
        socket_left_bottom = (socket_left[0], socket_left[1] + self.head_size * socket_relative_height)
        socket_right: Tuple[float, float] = (self.head_size * socket_relative_width, self.head_size * .5)
        socket_right_bottom: Tuple[float, float] = (socket_right[0], socket_right[1] + self.head_size * socket_relative_height)

        size_factor = self.head_size / 50.0

        arm_length = 50 * size_factor
        arm_params = {
            "arm_length": arm_length,
            "arm_color": self.body_color,
            "hand_color": helper.colors.lighten_hex(self.body_color, 2),
            "thickness_shoulder": 30 * size_factor
        }
        arm_params.update(self.arm_params)

        for i in range(self.arm_count):
            left_arm = ArmWithHand(**arm_params) # type: ignore
            left_arm_g = left_arm.render(dwg)

            left_arm_x = socket_right_bottom[0] - left_arm.thickness_shoulder / 2 - (socket_right_bottom[0] - self.head_size * self.body_fatness) / (self.head_size * self.body_height) * i * left_arm.thickness_shoulder * 1.2

            left_arm_g.translate(left_arm_x, socket_right_bottom[1] + left_arm.thickness_shoulder / 2 + i * left_arm.thickness_shoulder * .8)
            left_arm_g.rotate(self.body_left_arm_angle / (math.pi) * 180 + (i * 20))

            g.add(left_arm_g)

            right_arm = ArmWithHand(reverse_shadow=True, **arm_params) # type: ignore
            right_arm_g = right_arm.render(dwg)

            right_arm_x = socket_left_bottom[0] + right_arm.thickness_shoulder / 2 + (-self.head_size * self.body_fatness - socket_left_bottom[0]) / (self.head_size * self.body_height) * i * right_arm.thickness_shoulder * 1.2

            right_arm_g.translate(right_arm_x, socket_left_bottom[1] + right_arm.thickness_shoulder / 2 + i * right_arm.thickness_shoulder * .8)
            right_arm_g.rotate(-self.body_right_arm_angle / (math.pi) * 180 - (i * 20))
            right_arm_g.scale(-1, 1)

            g.add(right_arm_g)

        leg_thickness_thigh = self.body_fatness * self.head_size
        leg_thickness_foot = leg_thickness_thigh * .7

        leg_length = self.head_size * 1

        boot_height = leg_length * .5
        foot_length = leg_length

        left_leg = LegWithFoot(leg_length=leg_length, # type: ignore
                               leg_color=self.body_color,
                               thickness_thigh=leg_thickness_thigh,
                               thickness_foot=leg_thickness_foot,
                               foot_color=helper.colors.lighten_hex(self.body_color, 2),
                               boot_height=boot_height,
                               foot_length=foot_length,
                               **self.leg_params)
        left_leg_g = left_leg.render(dwg)
        left_leg_g.translate(0, self.head_size * self.body_height)
        left_leg_g.rotate(-20)

        g.add(left_leg_g)

        right_leg = LegWithFoot(leg_length=leg_length, # type: ignore
                                leg_color=self.body_color,
                                thickness_thigh=leg_thickness_thigh,
                                thickness_foot=leg_thickness_foot,
                                foot_color=helper.colors.lighten_hex(self.body_color, 2),
                                boot_height=boot_height,
                                foot_length=foot_length,
                                **self.leg_params)
        right_leg_g = right_leg.render(dwg)
        right_leg_g.translate(0, self.head_size * self.body_height)
        right_leg_g.rotate(20)
        right_leg_g.scale(-1, 1)

        g.add(right_leg_g)

        body = dwg.path(fill=self.body_color)
        body.push("M %f %f" % (socket_right_bottom[0], socket_right_bottom[1]))
        body.push("L %f %f" % (self.head_size * self.body_fatness, self.head_size * self.body_height))
        body.push("L %f %f" % (self.head_size * (self.body_fatness - .2), self.head_size * (self.body_height + .2)))
        body.push("L %f %f" % (-self.head_size * (self.body_fatness - .2), self.head_size * (self.body_height + .2)))
        body.push("L %f %f" % (-self.head_size * self.body_fatness, self.head_size * self.body_height))
        body.push("L %f %f" % (socket_left_bottom[0], socket_left_bottom[1]))

        g.add(body)

        socket_background_color = helper.colors.darken_hex(self.socket_color)
        socket_background = dwg.ellipse(fill=socket_background_color, center=(0, self.head_size * .5), r=socket_radius)
        
        socket_foreground = dwg.path(fill=self.socket_color)
        socket_foreground.push("M %f %f" % socket_left)
        socket_foreground.push("A %f %f 0 0 0 %f %f" % (socket_radius[0], socket_radius[1], socket_right[0], socket_right[1]))
        socket_foreground.push("l 0 %f" % (self.head_size * .3))
        socket_foreground.push("A %f %f 0 0 1 %f %f" % (socket_radius[0], socket_radius[1], - self.head_size * socket_relative_width, self.head_size * .8))

        g.add(socket_background)
        g.add(head)
        g.add(socket_foreground)

        dome = dwg.path(fill="white", fill_opacity=.3)
        dome.push("M %f %f" % socket_left)
        dome.push("C %f %f %f %f %f %f" % (-self.head_size * (socket_relative_width + 1),
                                           -self.head_size * 3,
                                           self.head_size * (socket_relative_width + 1),
                                           -self.head_size * 3,
                                           socket_right[0],
                                           socket_right[1]))
        dome.push("A %f %f 0 0 1 %f %f" % (socket_radius[0], socket_radius[1], socket_left[0], socket_left[1]))

        refl_mask = dwg.defs.add(dwg.mask((self.head_size * -1.5, self.head_size * -2.5),
                                          (self.head_size * 3, self.head_size * 5),
                                          id="%s-dome-refl-mask" % self.id))
        refl_mask.add(dwg.rect((self.head_size * -1.5, self.head_size * -2.5),
                                          (self.head_size * 3, self.head_size * 5), fill="white"))
        refl_mask.add(dwg.circle((self.head_size * .3, -self.head_size * .25), r=self.head_size * 1.75, fill="black"))

        dome_reflection = dwg.path(fill="white", fill_opacity=.3, mask="url(#%s-dome-refl-mask)" % self.id)
        dome_reflection.push("M %f %f" % socket_left)
        dome_reflection.push("C %f %f %f %f %f %f" % (-self.head_size * (socket_relative_width + 1),
                                           -self.head_size * 3,
                                           self.head_size * (socket_relative_width + 1),
                                           -self.head_size * 3,
                                           socket_right[0],
                                           socket_right[1]))
        dome_reflection.push("A %f %f 0 0 1 %f %f" % (socket_radius[0], socket_radius[1], socket_left[0], socket_left[1]))
        dome_reflection.scale(.9)

        g.add(dome)
        g.add(dome_reflection)

        return g
def diode_svg_frame(illuminated, num_across=9, num_down=8, frame=0, single_route=-1):
    filename = "diode{:03d}.svg".format(frame)
    led_symbol = "resources/Symbol_LED.svg"
    image_width = 600
    image_height = 400
    right_margin = 30
    bottom_margin = 30
    dwg = Drawing(filename,
                  size=(image_width+right_margin, image_height+bottom_margin),
                  style="background-color:white")
    # create a white background rectangle
    dwg.add(dwg.rect(size=(image_width+right_margin, image_height+bottom_margin),
                     insert=(0, 0), fill="white"))

    LED_dimensions = [106.0, 71.0]
    LED_points = [[35, 68], [35, 31], [66, 50]]
    LED_entries = [[4, 50], [103, 50]]
    aspect_ratio = LED_dimensions[1]/LED_dimensions[0]
    new_width = image_width/num_across
    new_height = new_width*aspect_ratio
    LED_scale = 0.75
    LED_offsets = [new_width*LED_scale/2, new_height*LED_scale]
    junction_radius = 0.8
    elements = []
    for i in range(0, num_across):
        x_pos = new_width*(num_across-i-1)
        if illuminated[1] >= illuminated[0]:
            incoming_wire = illuminated[1] + 1
        else:
            incoming_wire = illuminated[1]
        if i == incoming_wire:
            connection = "+"
            text_fill = "red"
        elif i == illuminated[0]:
            connection = "-"
            text_fill = "black"
        else:
            connection = "NC"
            text_fill = "gray"
        wire_label = "{} {}".format(i+1, connection)
        # the input wire title
        dwg.add(dwg.text(wire_label, insert=(x_pos+new_width-10, 10),
                             fill=text_fill))
        for j in range(0, num_down):
            y_pos = (image_height/num_down)*j
            position = [x_pos+LED_offsets[0], y_pos+LED_offsets[1]]
            scale = [LED_scale*new_width/LED_dimensions[0],
                     LED_scale*new_height/LED_dimensions[1]]
            # the led svg
            dwg.add(dwg.image(led_symbol, insert=position,
                              size=(new_width*LED_scale, new_height*LED_scale)))
            if i == illuminated[0] and j == illuminated[1] and single_route == -1:
                points = []
                for point in LED_points:
                    points.append(transform_point(point, scale, position))
                # the illuminated svg box
                dwg.add(dwg.polygon(points=points, fill="yellow"))
                line_fill = "green"
                stroke_width = 1
                insert_pos = -1
            else:
                line_fill = "black"
                insert_pos = 0
                stroke_width = 0.5
            # for each LED, we want to generate a line going from the input
            # to its output
            entry_point = transform_point(LED_entries[0], scale, position)
            if i > j:
                incoming_line_points = [[new_width*(num_across-j)-LED_offsets[0], 0],
                                    [new_width*(num_across-j)-LED_offsets[0], y_pos+20],
                                    [entry_point[0], y_pos+20], entry_point]
            elif j > i:
                incoming_line_points = [
                    [new_width * (num_across - j - 1) - LED_offsets[0], 0],
                    [new_width * (num_across - j - 1) - LED_offsets[0],
                     entry_point[1] + LED_offsets[1]],
                    [entry_point[0], entry_point[1]+LED_offsets[1]], entry_point]
            elif i == j:
                incoming_line_points = [
                    [new_width * (num_across - j - 1) - LED_offsets[0], 0],
                    [new_width * (num_across - j - 1) - LED_offsets[0], entry_point[1]], entry_point]
            else:
                incoming_line_points = []
            elements.insert(insert_pos,
                            make_junction_line(dwg, incoming_line_points,
                                               junction_radius, line_fill,
                                               stroke_width))
            # outgoing line
            exit_point = transform_point(LED_entries[1], scale, position)
            outgoing_line_points = [exit_point,
                                    [x_pos+new_width-LED_offsets[0],
                                     exit_point[1]],
                                    [x_pos+new_width-LED_offsets[0], 0]]
            elements.insert(insert_pos,
                            make_junction_line(dwg, outgoing_line_points,
                                               junction_radius, line_fill,
                                               stroke_width))
            route_points = [[new_width * (num_across - j - 1) - LED_offsets[0],
                             0]]
            for point in range(0, single_route+1):
                if point < i:
                    route_points.append([new_width * (num_across - j - 1) - LED_offsets[0], 0])

            # now create the network
            nodes = []
            for i in range(0, num_across):
                for j in range(0, num_down):
                    nodes.append(entry_point)
                    nodes.append(exit_point)
    # flatten the elements structure
    elements = sum(elements, [])
    print(elements)
    # the lines should be drawn last so that they are layered on top of all
    # other elements
    #for element in elements:
    #    dwg.add(element)
    dwg.save()
    return convert(image_width, filename)
Esempio n. 22
0
def export_node(node, store, size=None):
    """Construct a SVG description for a workflow node.

    Args:
        node (NodeDef)
        store (dict of uid, def): elements definitions
        size (int, int): size of drawing in pixels

    Returns:
        (str) - SVG description of workflow node
    """
    pfs = port_font_size

    # node size
    pr = port_radius
    pspace = pr * 9
    nw = compute_node_width(node, node['name'], pspace)
    nh = label_font_size + 2 * pr + 2 * pfs + 2 + (2 * node_padding)

    # draw
    if size is None:
        size = (600, 600)

    paper = Drawing("workflow_node.svg", size, id="repr")

    lg = paper.linearGradient((0.5, 0), (0.5, 1.), id="in_port")
    lg.add_stop_color(0, color='#3333ff')
    lg.add_stop_color(1, color='#2222ff')
    paper.defs.add(lg)

    lg = paper.linearGradient((0.5, 0), (0.5, 1.), id="out_port")
    lg.add_stop_color(0, color='#ffff33')
    lg.add_stop_color(1, color='#9a9a00')
    paper.defs.add(lg)

    # body
    g = paper.add(paper.g())

    # background
    lg = paper.linearGradient((0.5, 0), (0.5, 1.))
    lg.add_stop_color(0, color='#8c8cff')
    lg.add_stop_color(1, color='#c8c8c8')
    paper.defs.add(lg)

    bg = paper.rect((-nw / 2, -nh / 2), (nw, nh),
                    rx=node_padding,
                    ry=node_padding,
                    stroke_width=1)
    bg.stroke('#808080')
    bg.fill(lg)
    g.add(bg)

    # label
    style = ('font-size: %dpx; font-family: %s; '
             'text-anchor: middle' % (label_font_size, label_font))
    frag = paper.tspan(node['name'], dy=[label_font_size // 3])
    label = paper.text("", style=style, fill='#000000')
    label.add(frag)
    g.add(label)

    # ports
    port_style = ('font-size: %dpx; ' % pfs + 'font-family: %s; ' % label_font)
    onstyle = port_style + 'text-anchor: end'
    instyle = port_style + 'text-anchor: start'
    istyle = port_style + 'text-anchor: middle'
    nb = len(node['inputs'])
    py = -nh / 2
    for i, pdef in enumerate(node['inputs']):
        px = i * pspace - pspace * (nb - 1) / 2
        pg = g.add(paper.g())
        pg.translate(px, py)
        idef = store.get(pdef['interface'], None)
        if idef is not None and 'url' in idef:
            link = pg.add(paper.a(href=idef['url'], target='_top'))
        else:
            link = pg

        port = paper.circle((0, 0), pr, stroke='#000000', stroke_width=1)
        port.fill("url(#in_port)")
        link.add(port)
        # port name
        frag = paper.tspan(pdef['name'], dy=[-2 * pr])
        label = paper.text("", style=instyle, fill='#000000')
        label.rotate(-45)
        label.add(frag)
        pg.add(label)
        # port interface
        if idef is None:
            itxt = pdef['interface']
        else:
            itxt = idef['name']
        if len(itxt) > 10:
            itxt = itxt[:7] + "..."
        frag = paper.tspan(itxt, dy=[pr + pfs])
        label = paper.text("", style=istyle, fill='#000000')
        label.add(frag)
        link.add(label)

    nb = len(node['outputs'])
    py = nh / 2
    for i, pdef in enumerate(node['outputs']):
        px = i * pspace - pspace * (nb - 1) / 2
        pg = g.add(paper.g())
        pg.translate(px, py)
        idef = store.get(pdef['interface'], None)
        if idef is not None and 'url' in idef:
            link = pg.add(paper.a(href=idef['url'], target='_top'))
        else:
            link = pg

        port = paper.circle((0, 0), pr, stroke='#000000', stroke_width=1)
        port.fill("url(#out_port)")
        link.add(port)
        # port name
        frag = paper.tspan(pdef['name'], dy=[2 * pr + pfs // 2])
        label = paper.text("", style=onstyle, fill='#000000')
        label.rotate(-45)
        label.add(frag)
        pg.add(label)
        # port interface
        if idef is None:
            itxt = pdef['interface']
        else:
            itxt = idef['name']
        if len(itxt) > 10:
            itxt = itxt[:7] + "..."
        frag = paper.tspan(itxt, dy=[-pr - 2])
        label = paper.text("", style=istyle, fill='#000000')
        label.add(frag)
        link.add(label)

    # reformat whole drawing to fit screen
    xmin = -nw / 2 - draw_padding / 10.
    xmax = +nw / 2 + draw_padding / 10.
    if len(node['inputs']) == 0:
        inames_extend = 0
    else:
        inames = [(len(pdef['name']), pdef['name']) for pdef in node['inputs']]
        inames_extend = string_size(sorted(inames)[-1][1], pfs) * 0.7 + pfs
    ymin = -nh / 2 - pr - inames_extend - draw_padding / 10.
    if len(node['outputs']) == 0:
        onames_extend = 0
    else:
        onames = [(len(pdef['name']), pdef['name'])
                  for pdef in node['outputs']]
        onames_extend = string_size(sorted(onames)[-1][1], pfs) * 0.7 + pfs
    ymax = +nh / 2 + pr + onames_extend + draw_padding / 10.

    w = float(size[0])
    h = float(size[1])
    ratio = max((xmax - xmin) / w, (ymax - ymin) / h)
    xsize = ratio * w
    ysize = ratio * h

    bb = (xmin * xsize / (xmax - xmin), ymin * ysize / (ymax - ymin), xsize,
          ysize)

    paper.viewbox(*bb)
    return paper.tostring(), bb
Esempio n. 23
0
    def _draw(self, d: svgwrite.Drawing, size: XY, offset: XY, year: int):
        min_size = min(size.x, size.y)
        year_size = min_size * 4.0 / 80.0
        year_style = 'font-size:{}px; font-family:Arial;'.format(year_size)
        month_style = 'font-size:{}px; font-family:Arial;'.format(min_size *
                                                                  3.0 / 80.0)
        day_style = 'dominant-baseline: central; font-size:{}px; font-family:Arial;'.format(
            min_size * 1.0 / 80.0)
        day_length_style = 'font-size:{}px; font-family:Arial;'.format(
            min_size * 1.0 / 80.0)

        d.add(
            d.text('{}'.format(year),
                   insert=offset.tuple(),
                   fill=self.poster.colors['text'],
                   alignment_baseline="hanging",
                   style=year_style))
        offset.y += year_size
        size.y -= year_size
        count_x = 31
        for month in range(1, 13):
            date = datetime.date(year, month, 1)
            (_, last_day) = calendar.monthrange(year, month)
            count_x = max(count_x, date.weekday() + last_day)

        cell_size = min(size.x / count_x, size.y / 36)
        spacing = XY((size.x - cell_size * count_x) / (count_x - 1),
                     (size.y - cell_size * 3 * 12) / 11)

        dow = ["M", "T", "W", "T", "F", "S", "S"]
        for month in range(1, 13):
            date = datetime.date(year, month, 1)
            y = month - 1
            y_pos = offset.y + (y * 3 + 1) * cell_size + y * spacing.y
            d.add(
                d.text(date.strftime("%B"),
                       insert=(offset.x, y_pos - 2),
                       fill=self.poster.colors['text'],
                       alignment_baseline="hanging",
                       style=month_style))

            day_offset = date.weekday()
            while date.month == month:
                x = date.day - 1
                x_pos = offset.x + (day_offset + x) * cell_size + x * spacing.x
                pos = (x_pos + 0.05 * cell_size, y_pos + 0.05 * cell_size)
                dim = (cell_size * 0.9, cell_size * 0.9)
                text_date = date.strftime("%Y-%m-%d")
                if text_date in self.poster.tracks_by_date:
                    tracks = self.poster.tracks_by_date[text_date]
                    length = sum([t.length for t in tracks])
                    color = self.color(self.poster.length_range_by_date,
                                       length,
                                       [t for t in tracks if t.special])
                    d.add(d.rect(pos, dim, fill=color))
                    d.add(
                        d.text("{:.1f}".format(self.poster.m2u(length)),
                               insert=(x_pos + cell_size / 2,
                                       y_pos + cell_size + cell_size / 2),
                               text_anchor="middle",
                               style=day_length_style,
                               fill=self.poster.colors['text']))
                else:
                    d.add(d.rect(pos, dim, fill='#444444'))

                d.add(
                    d.text(dow[date.weekday()],
                           insert=(offset.x + (day_offset + x) * cell_size +
                                   cell_size / 2, y_pos + cell_size / 2),
                           text_anchor="middle",
                           alignment_baseline="middle",
                           style=day_style))
                date += datetime.timedelta(1)
Esempio n. 24
0
    dwg = Drawing(join(OUTPUT_DIRECTORY, "next_available_grid.svg"),
                  (num_grid * spacing, num_grid * spacing))
    for x in range(num_grid):
        dwg.add(
            dwg.line(start=(0, x * spacing),
                     end=(num_grid * spacing, x * spacing),
                     stroke=rgb(10, 10, 16, '%')))
        dwg.add(
            dwg.line(start=(x * spacing, 0),
                     end=(x * spacing, num_grid * spacing),
                     stroke=rgb(10, 10, 16, '%')))
    start_point = [4, 4]

    dwg.add(
        dwg.rect(insert=(start_point[0] * spacing, start_point[1] * spacing),
                 size=(spacing, spacing),
                 fill=rgb(100, 100, 16, '%')))
    count = 0
    last_point = start_point
    for next_available in NextAvailableGrid(*start_point):
        dwg.add(
            dwg.line(start=((last_point[0] + 0.5) * spacing,
                            (last_point[1] + 0.5) * spacing),
                     end=((next_available[0] + 0.5) * spacing,
                          (next_available[1] + 0.5) * spacing),
                     stroke=rgb(100, 0, 0, '%')))
        last_point = next_available
        count += 1
        if count > 25:
            break
    dwg.save()
Esempio n. 25
0
 def export(self):
     dwg = Drawing(self.name, width=W, height=H)
     for r in self.rects:
         dwg.add(dwg.rect(insert=(r.x, r.y), size=(r.w, r.h), fill='black'))
     dwg.save()
Esempio n. 26
0
    def _draw(self, dr: svgwrite.Drawing, g: svgwrite.container.Group,
              size: XY, offset: XY, year: int) -> None:
        min_size = min(size.x, size.y)
        year_size = min_size * 4.0 / 80.0
        year_style = f"font-size:{year_size}px; font-family:Arial;"
        month_style = f"font-size:{min_size * 3.0 / 80.0}px; font-family:Arial;"
        day_style = f"dominant-baseline: central; font-size:{min_size * 1.0 / 80.0}px; font-family:Arial;"
        day_length_style = f"font-size:{min_size * 1.0 / 80.0}px; font-family:Arial;"

        g.add(
            dr.text(
                f"{year}",
                insert=offset.tuple(),
                fill=self.poster.colors["text"],
                alignment_baseline="hanging",
                style=year_style,
            ))
        offset.y += year_size
        size.y -= year_size
        count_x = 31
        for month in range(1, 13):
            date = datetime.date(year, month, 1)
            (_, last_day) = calendar.monthrange(year, month)
            count_x = max(count_x, date.weekday() + last_day)

        cell_size = min(size.x / count_x, size.y / 36)
        spacing = XY(
            (size.x - cell_size * count_x) / (count_x - 1),
            (size.y - cell_size * 3 * 12) / 11,
        )

        for month in range(1, 13):
            date = datetime.date(year, month, 1)
            y = month - 1
            y_pos = offset.y + (y * 3 + 1) * cell_size + y * spacing.y
            g.add(
                dr.text(
                    self.poster.month_name(month),
                    insert=(offset.x, y_pos - 2),
                    fill=self.poster.colors["text"],
                    alignment_baseline="hanging",
                    style=month_style,
                ))

            day_offset = date.weekday()
            while date.month == month:
                x = date.day - 1
                x_pos = offset.x + (day_offset + x) * cell_size + x * spacing.x
                pos = (x_pos + 0.05 * cell_size, y_pos + 1.15 * cell_size)
                dim = (cell_size * 0.9, cell_size * 0.9)
                text_date = date.strftime("%Y-%m-%d")
                if text_date in self.poster.tracks_by_date:
                    tracks = self.poster.tracks_by_date[text_date]
                    length = sum([t.length() for t in tracks])
                    has_special = len([t for t in tracks if t.special]) > 0
                    color = self.color(self.poster.length_range_by_date,
                                       length, has_special)
                    g.add(dr.rect(pos, dim, fill=color))
                    g.add(
                        dr.text(
                            utils.format_float(self.poster.m2u(length)),
                            insert=(
                                pos[0] + cell_size / 2,
                                pos[1] + cell_size + cell_size / 2,
                            ),
                            text_anchor="middle",
                            style=day_length_style,
                            fill=self.poster.colors["text"],
                        ))
                else:
                    g.add(dr.rect(pos, dim, fill="#444444"))

                g.add(
                    dr.text(
                        localized_day_of_week_name(date.weekday(), short=True),
                        insert=(
                            offset.x + (day_offset + x) * cell_size +
                            cell_size / 2,
                            pos[1] + cell_size / 2,
                        ),
                        text_anchor="middle",
                        alignment_baseline="middle",
                        style=day_style,
                    ))
                date += datetime.timedelta(1)
Esempio n. 27
0
def LQFP(name, offset, width1, width2, padh, padw, spaceing, padcount, bodyw,
         edge, pinh, pinw):

    # document sizes
    doc = (width1 + 2 * offset[0], width1 + 2 * offset[1])

    # basic SVG sheet
    svg = Drawing(filename=name, size=doc)

    #######################################################################################################
    # PCB Pads
    #######################################################################################################

    pads = svg.g(id="pads")

    # pins 51 to 75
    for n in range(0, padcount):
        x = offset[0] + ((width1 - width2) / 2) + (n * spaceing)
        y = offset[1]
        pad = svg.rect(insert=(x, y),
                       size=(padw, padh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#D4AA00")
        pads.add(pad)

    # pins 1 to 25
    for n in range(0, padcount):
        x = offset[0] + ((width1 - width2) / 2) + (n * spaceing)
        y = offset[1] + (width1 - padh)
        pad = svg.rect(insert=(x, y),
                       size=(padw, padh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#D4AA00")
        pads.add(pad)

    # pins 76 to 100
    for n in range(0, padcount):
        x = offset[0]
        y = offset[1] + ((width1 - width2) / 2) + (n * spaceing)
        pad = svg.rect(insert=(x, y),
                       size=(padh, padw),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#D4AA00")
        pads.add(pad)

    # pins 26 to 50
    for n in range(0, padcount):
        x = offset[0] + (width1 - padh)
        y = offset[1] + ((width1 - width2) / 2) + (n * spaceing)
        pad = svg.rect(insert=(x, y),
                       size=(padh, padw),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#D4AA00")
        pads.add(pad)

    svg.add(pads)

    #######################################################################################################
    # Part
    #######################################################################################################

    corner = (doc[0] / 2) - (bodyw / 2)

    part = svg.g(id="part")

    # pins 51 to 75
    for n in range(0, padcount):
        x = offset[0] + ((width1 - width2) / 2) + (
            (padw - pinw) / 2) + (n * spaceing)
        y = corner - pinh
        pad = svg.rect(insert=(x, y),
                       size=(pinw, pinh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#999999")
        part.add(pad)

    # pins 1 to 25
    for n in range(0, padcount):
        x = offset[0] + ((width1 - width2) / 2) + (
            (padw - pinw) / 2) + (n * spaceing)
        y = corner + bodyw
        pad = svg.rect(insert=(x, y),
                       size=(pinw, pinh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#999999")
        part.add(pad)

    # pins 76 to 100
    for n in range(0, padcount):
        x = corner - pinh
        y = offset[0] + ((width1 - width2) / 2) + (
            (padw - pinw) / 2) + (n * spaceing)
        pad = svg.rect(insert=(x, y),
                       size=(pinh, pinw),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#999999")
        part.add(pad)

    # pins 26 to 50
    for n in range(0, padcount):
        x = corner + bodyw
        y = offset[0] + ((width1 - width2) / 2) + (
            (padw - pinw) / 2) + (n * spaceing)
        pad = svg.rect(insert=(x, y),
                       size=(pinh, pinw),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#999999")
        part.add(pad)

    # plastic body
    points = [(corner, corner + edge), (corner + edge, corner),
              (corner + bodyw - edge, corner), (corner + bodyw, corner + edge),
              (corner + bodyw, corner + bodyw - edge),
              (corner + bodyw - edge, corner + bodyw),
              (corner + edge, corner + bodyw), (corner, corner + bodyw - edge)]

    body = svg.polygon(points=points,
                       stroke_width=0.05,
                       stroke="black",
                       fill="#333333")
    part.add(body)

    # pin 1 indicator
    ind = svg.circle(center=(corner + 1, corner + bodyw - 1),
                     r=0.5,
                     stroke_width=0.05,
                     stroke="black",
                     fill="#333333")
    part.add(ind)

    svg.add(part)

    svg.save()
Esempio n. 28
0
def export_node(node, store, size=None):
    """Construct a SVG description for a workflow node.

    Args:
        node (NodeDef)
        store (dict of uid, def): elements definitions
        size (int, int): size of drawing in pixels

    Returns:
        (str) - SVG description of workflow node
    """
    pfs = port_font_size

    # node size
    pr = port_radius
    pspace = pr * 9
    nw = compute_node_width(node, node['name'], pspace)
    nh = label_font_size + 2 * pr + 2 * pfs + 2 + (2 * node_padding)

    # draw
    if size is None:
        size = (600, 600)

    paper = Drawing("workflow_node.svg", size, id="repr")

    lg = paper.linearGradient((0.5, 0), (0.5, 1.), id="in_port")
    lg.add_stop_color(0, color='#3333ff')
    lg.add_stop_color(1, color='#2222ff')
    paper.defs.add(lg)

    lg = paper.linearGradient((0.5, 0), (0.5, 1.), id="out_port")
    lg.add_stop_color(0, color='#ffff33')
    lg.add_stop_color(1, color='#9a9a00')
    paper.defs.add(lg)

    # body
    g = paper.add(paper.g())

    # background
    lg = paper.linearGradient((0.5, 0), (0.5, 1.))
    lg.add_stop_color(0, color='#8c8cff')
    lg.add_stop_color(1, color='#c8c8c8')
    paper.defs.add(lg)

    bg = paper.rect((-nw / 2, -nh / 2), (nw, nh),
                    rx=node_padding, ry=node_padding,
                    stroke_width=1)
    bg.stroke('#808080')
    bg.fill(lg)
    g.add(bg)

    # label
    style = ('font-size: %dpx; font-family: %s; '
             'text-anchor: middle' % (label_font_size, label_font))
    frag = paper.tspan(node['name'], dy=[label_font_size // 3])
    label = paper.text("", style=style, fill='#000000')
    label.add(frag)
    g.add(label)

    # ports
    port_style = ('font-size: %dpx; ' % pfs +
                  'font-family: %s; ' % label_font)
    onstyle = port_style + 'text-anchor: end'
    instyle = port_style + 'text-anchor: start'
    istyle = port_style + 'text-anchor: middle'
    nb = len(node['inputs'])
    py = -nh / 2
    for i, pdef in enumerate(node['inputs']):
        px = i * pspace - pspace * (nb - 1) / 2
        pg = g.add(paper.g())
        pg.translate(px, py)
        idef = store.get(pdef['interface'], None)
        if idef is not None and 'url' in idef:
            link = pg.add(paper.a(href=idef['url'], target='_top'))
        else:
            link = pg

        port = paper.circle((0, 0), pr, stroke='#000000', stroke_width=1)
        port.fill("url(#in_port)")
        link.add(port)
        # port name
        frag = paper.tspan(pdef['name'], dy=[-2 * pr])
        label = paper.text("", style=instyle, fill='#000000')
        label.rotate(-45)
        label.add(frag)
        pg.add(label)
        # port interface
        if idef is None:
            itxt = pdef['interface']
        else:
            itxt = idef['name']
        if len(itxt) > 10:
            itxt = itxt[:7] + "..."
        frag = paper.tspan(itxt, dy=[pr + pfs])
        label = paper.text("", style=istyle, fill='#000000')
        label.add(frag)
        link.add(label)

    nb = len(node['outputs'])
    py = nh / 2
    for i, pdef in enumerate(node['outputs']):
        px = i * pspace - pspace * (nb - 1) / 2
        pg = g.add(paper.g())
        pg.translate(px, py)
        idef = store.get(pdef['interface'], None)
        if idef is not None and 'url' in idef:
            link = pg.add(paper.a(href=idef['url'], target='_top'))
        else:
            link = pg

        port = paper.circle((0, 0), pr, stroke='#000000', stroke_width=1)
        port.fill("url(#out_port)")
        link.add(port)
        # port name
        frag = paper.tspan(pdef['name'], dy=[2 * pr + pfs // 2])
        label = paper.text("", style=onstyle, fill='#000000')
        label.rotate(-45)
        label.add(frag)
        pg.add(label)
        # port interface
        if idef is None:
            itxt = pdef['interface']
        else:
            itxt = idef['name']
        if len(itxt) > 10:
            itxt = itxt[:7] + "..."
        frag = paper.tspan(itxt, dy=[- pr - 2])
        label = paper.text("", style=istyle, fill='#000000')
        label.add(frag)
        link.add(label)

    # reformat whole drawing to fit screen
    xmin = - nw / 2 - draw_padding / 10.
    xmax = + nw / 2 + draw_padding / 10.
    if len(node['inputs']) == 0:
        inames_extend = 0
    else:
        inames = [(len(pdef['name']), pdef['name']) for pdef in node['inputs']]
        inames_extend = string_size(sorted(inames)[-1][1], pfs) * 0.7 + pfs
    ymin = - nh / 2 - pr - inames_extend - draw_padding / 10.
    if len(node['outputs']) == 0:
        onames_extend = 0
    else:
        onames = [(len(pdef['name']), pdef['name']) for pdef in node['outputs']]
        onames_extend = string_size(sorted(onames)[-1][1], pfs) * 0.7 + pfs
    ymax = + nh / 2 + pr + onames_extend + draw_padding / 10.

    w = float(size[0])
    h = float(size[1])
    ratio = max((xmax - xmin) / w, (ymax - ymin) / h)
    xsize = ratio * w
    ysize = ratio * h

    bb = (xmin * xsize / (xmax - xmin),
          ymin * ysize / (ymax - ymin),
          xsize,
          ysize)

    paper.viewbox(*bb)
    return paper.tostring(), bb
Esempio n. 29
0
    def draw(self, dr: svgwrite.Drawing, g: svgwrite.container.Group, size: XY,
             offset: XY) -> None:
        if self.poster.tracks is None:
            raise PosterError("No tracks to draw")
        year_size = 200 * 4.0 / 80.0
        year_style = f"font-size:{year_size}px; font-family:Arial;"
        year_length_style = f"font-size:{110 * 3.0 / 80.0}px; font-family:Arial;"
        month_names_style = "font-size:2.5px; font-family:Arial"
        total_length_year_dict = self.poster.total_length_year_dict
        for year in self.poster.years.iter():
            g_year = dr.g(id=f"year{year}")
            g.add(g_year)

            start_date_weekday, _ = calendar.monthrange(year, 1)
            github_rect_first_day = datetime.date(year, 1, 1)
            # Github profile the first day start from the last Monday of the last year or the first Monday of this year
            # It depands on if the first day of this year is Monday or not.
            github_rect_day = github_rect_first_day + datetime.timedelta(
                -start_date_weekday)
            year_length = total_length_year_dict.get(year, 0)
            year_length_str = utils.format_float(self.poster.m2u(year_length))
            month_names = [
                locale.nl_langinfo(day)[:3]  # Get only first three letters
                for day in [
                    locale.MON_1,
                    locale.MON_2,
                    locale.MON_3,
                    locale.MON_4,
                    locale.MON_5,
                    locale.MON_6,
                    locale.MON_7,
                    locale.MON_8,
                    locale.MON_9,
                    locale.MON_10,
                    locale.MON_11,
                    locale.MON_12,
                ]
            ]
            km_or_mi = self.poster.u()
            g_year.add(
                dr.text(
                    f"{year}",
                    insert=offset.tuple(),
                    fill=self.poster.colors["text"],
                    alignment_baseline="hanging",
                    style=year_style,
                ))

            g_year.add(
                dr.text(
                    f"{year_length_str} {km_or_mi}",
                    insert=(offset.tuple()[0] + 165, offset.tuple()[1] + 2),
                    fill=self.poster.colors["text"],
                    alignment_baseline="hanging",
                    style=year_length_style,
                ))
            # add month name up to the poster one by one because of svg text auto trim the spaces.
            for num, name in enumerate(month_names):
                g_year.add(
                    dr.text(
                        f"{name}",
                        insert=(offset.tuple()[0] + 15.5 * num,
                                offset.tuple()[1] + 14),
                        fill=self.poster.colors["text"],
                        style=month_names_style,
                    ))

            rect_x = 10.0
            dom = (2.6, 2.6)
            # add every day of this year for 53 weeks and per week has 7 days
            for _i in range(54):
                rect_y = offset.y + year_size + 2
                for _j in range(7):
                    if int(github_rect_day.year) > year:
                        break
                    rect_y += 3.5
                    color = "#444444"
                    date_title = str(github_rect_day)
                    if date_title in self.poster.tracks_by_date:
                        tracks = self.poster.tracks_by_date[date_title]
                        length = sum([t.length() for t in tracks])
                        distance1 = self.poster.special_distance[
                            "special_distance"]
                        distance2 = self.poster.special_distance[
                            "special_distance2"]
                        has_special = distance1 < length < distance2
                        color = self.color(self.poster.length_range_by_date,
                                           length, has_special)
                        if length >= distance2:
                            special_color = self.poster.colors.get(
                                "special2") or self.poster.colors.get(
                                    "special")
                            if special_color is not None:
                                color = special_color
                        str_length = utils.format_float(
                            self.poster.m2u(length))
                        date_title = f"{date_title} {str_length} {km_or_mi}"

                    rect = dr.rect((rect_x, rect_y), dom, fill=color)
                    rect.set_desc(title=date_title)
                    g_year.add(rect)
                    github_rect_day += datetime.timedelta(1)
                rect_x += 3.5
            offset.y += 3.5 * 9 + year_size + 1.5
Esempio n. 30
0
    def plot(self, svg: Drawing) -> None:

        recolor: Optional[str] = None

        if isinstance(self.color, list):
            linear_gradient: LinearGradient = svg.linearGradient(
                self.map_((0, self.max_y)),
                self.map_((0, 1)),
                gradientUnits="userSpaceOnUse",
            )
            for index, color in enumerate(self.color):
                linear_gradient.add_stop_color(
                    index / (len(self.color) - 1), color.hex
                )

            gradient: LinearGradient = svg.defs.add(linear_gradient)
            recolor = gradient.get_funciri()

        if isinstance(self.color, Color):
            recolor = self.color.hex

        svg.add(
            svg.rect(
                insert=(0, 0),
                size=("100%", "100%"),
                rx=None,
                ry=None,
                fill=self.background_color.hex,
            )
        )
        self.draw_grid(svg)
        last_text_y = 0

        for xs, ys, color, title in self.data:

            if recolor:
                color = recolor

            assert len(xs) == len(ys)

            xs_second: list[float] = [
                (x - self.min_x).total_seconds() for x in xs
            ]
            points = []

            for index, x in enumerate(xs_second):
                y = ys[index]
                mapped: np.ndarray = map_array(
                    np.array((x, y)),
                    np.array((self.min_x_second, self.max_y)),
                    np.array((self.max_x_second, self.min_y)),
                    self.canvas.workspace[0],
                    self.canvas.workspace[1],
                )
                points.append(mapped)
            previous_point: Optional[np.ndarray] = None

            for point in points:
                if previous_point is not None:
                    line: Line = svg.line(
                        (previous_point[0], previous_point[1]),
                        (point[0], point[1]),
                        stroke=self.background_color.hex,
                        stroke_width=6,
                    )
                    svg.add(line)
                    line: Line = svg.line(
                        (previous_point[0], previous_point[1]),
                        (point[0], point[1]),
                        stroke=color,
                        stroke_width=2,
                    )
                    svg.add(line)
                previous_point = point

            for point in points:
                svg.add(
                    svg.circle(
                        (point[0], point[1]),
                        5.5,
                        fill=self.background_color.hex,
                    )
                )
                svg.add(svg.circle((point[0], point[1]), 3.5, fill=color))

            title: str
            text_y = max(last_text_y + 20, point[1] + 6)
            self.text(svg, (point[0] + 15, text_y), title.upper(), color)
            last_text_y = text_y

        with Path(svg.filename).open("w+") as output_file:
            svg.write(output_file)
Esempio n. 31
0
Image.fromarray(np.asarray(skeletonized, dtype='uint8') *
                255).save("skeletonized.png")

g = im_to_graph(skeletonized)
lines = list(partition_forest(g))
assert len(lines) == 1
line = lines.pop()
smoothed = gaussian_filter1d(np.asarray(line, dtype=float),
                             sigma=DEFAULT_SIGMA,
                             axis=0)

length = np.linalg.norm(np.diff(smoothed, axis=0), axis=1).sum()

dwg = Drawing("line.svg")
dwg.add(dwg.rect(size=drawn_arr.shape[::-1], fill="black"))
dwg.add(
    dwg.polyline([tuple(pair[::-1]) for pair in smoothed],
                 stroke="white",
                 stroke_width=4,
                 fill="none"))

dwg.save(pretty=True, indent=2)


def pad_dim(vals, pad, integer=True):
    vmin = vals.min()
    vmax = vals.max()
    vpad = (vmax - vmin) * pad
    if integer:
        vpad = int(np.ceil(vpad))
Esempio n. 32
0
def TSSOP(name,
          offset,
          width,
          height,
          padh,
          padw,
          spaceing,
          padcount,
          bodyw,
          bodyh,
          pinw,
          pinh,
          thermalw=0,
          thermalh=0):

    # document sizes
    doc = (width + 2 * offset[0], height + 2 * offset[1])

    # basic SVG sheet
    svg = Drawing(filename=name, size=doc)

    #######################################################################################################
    # PCB Pads
    #######################################################################################################

    pads = svg.g(id="pads")

    for n in range(0, padcount):
        x = offset[0] + (n * spaceing)
        y = offset[1]
        pad = svg.rect(insert=(x, y),
                       size=(padw, padh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#D4AA00")
        pads.add(pad)

    for n in range(0, padcount):
        x = offset[0] + (n * spaceing)
        y = offset[1] + height - padh
        pad = svg.rect(insert=(x, y),
                       size=(padw, padh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#D4AA00")
        pads.add(pad)

    if thermalw is not 0 and thermalh is not 0:
        # thermal pad
        t = svg.rect(insert=((doc[0] / 2) - (thermalw / 2),
                             (doc[1] / 2) - (thermalh / 2)),
                     size=(thermalw, thermalh),
                     stroke_width=0.05,
                     stroke="black",
                     fill="#D4AA00")
        pads.add(t)

    svg.add(pads)

    #######################################################################################################
    # Part
    #######################################################################################################

    cornerx = (doc[0] / 2) - (bodyw / 2)
    cornery = (doc[1] / 2) - (bodyh / 2)

    part = svg.g(id="part")

    for n in range(0, padcount):
        x = offset[0] + (n * spaceing) + ((padw - pinw) / 2)
        y = offset[1] + (padh - pinh)
        pin = svg.rect(insert=(x, y),
                       size=(pinw, pinh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#999999")
        part.add(pin)

    for n in range(0, padcount):
        x = offset[0] + (n * spaceing) + ((padw - pinw) / 2)
        y = offset[1] + (height - padh)
        pin = svg.rect(insert=(x, y),
                       size=(pinw, pinh),
                       stroke_width=0.05,
                       stroke="black",
                       fill="#999999")
        part.add(pin)

    body = svg.rect(insert=(cornerx, cornery),
                    size=(bodyw, bodyh),
                    stroke_width=0.05,
                    stroke="black",
                    fill="#333333")
    part.add(body)

    # pin 1 indicator
    ind = svg.circle(center=(cornerx + 0.5, cornery + bodyh - 0.5),
                     r=0.2,
                     stroke_width=0.05,
                     stroke="black",
                     fill="#333333")
    part.add(ind)

    svg.add(part)

    svg.save()
Esempio n. 33
0
    def draw(self, dr: svgwrite.Drawing, size: XY, offset: XY):
        if self.poster.tracks is None:
            raise PosterError("No tracks to draw")
        year_size = 200 * 4.0 / 80.0
        year_style = f"font-size:{year_size}px; font-family:Arial;"
        year_length_style = f"font-size:{110 * 3.0 / 80.0}px; font-family:Arial;"
        month_names_style = f"font-size:2.5px; font-family:Arial"
        total_length_year_dict = self.poster.total_length_year_dict
        for year in range(self.poster.years.from_year,
                          self.poster.years.to_year + 1):
            start_date_weekday, _ = calendar.monthrange(year, 1)
            github_rect_first_day = datetime.date(year, 1, 1)
            # Github profile the first day start from the last Monday of the last year or the first Monday of this year
            # It depands on if the first day of this year is Monday or not.
            github_rect_day = github_rect_first_day + datetime.timedelta(
                -start_date_weekday)
            year_length = total_length_year_dict.get(year, 0)
            year_length = format_float(self.poster.m2u(year_length))
            try:
                month_names = [
                    locale.nl_langinfo(day)[:3]  # Get only first three letters
                    for day in [
                        locale.MON_1,
                        locale.MON_2,
                        locale.MON_3,
                        locale.MON_4,
                        locale.MON_5,
                        locale.MON_6,
                        locale.MON_7,
                        locale.MON_8,
                        locale.MON_9,
                        locale.MON_10,
                        locale.MON_11,
                        locale.MON_12,
                    ]
                ]
                # support windows or others doesn't support locale Name, by Hard code
            except Exception as e:
                print(str(e))
                month_names = [
                    "Jan",
                    "Feb",
                    "Mar",
                    "Apr",
                    "May",
                    "Jun",
                    "Jul",
                    "Aug",
                    "Sep",
                    "Oct",
                    "Nov",
                    "Dec",
                ]
            km_or_mi = "mi"
            if self.poster.units == "metric":
                km_or_mi = "km"
            dr.add(
                dr.text(
                    f"{year}",
                    insert=offset.tuple(),
                    fill=self.poster.colors["text"],
                    alignment_baseline="hanging",
                    style=year_style,
                ))

            dr.add(
                dr.text(
                    f"{year_length} {km_or_mi}",
                    insert=(offset.tuple()[0] + 165, offset.tuple()[1] + 2),
                    fill=self.poster.colors["text"],
                    alignment_baseline="hanging",
                    style=year_length_style,
                ))
            # add month name up to the poster one by one because of svg text auto trim the spaces.
            for num, name in enumerate(month_names):
                dr.add(
                    dr.text(
                        f"{name}",
                        insert=(offset.tuple()[0] + 15.5 * num,
                                offset.tuple()[1] + 14),
                        fill=self.poster.colors["text"],
                        style=month_names_style,
                    ))

            rect_x = 10.0
            dom = (2.6, 2.6)
            # add every day of this year for 53 weeks and per week has 7 days
            for i in range(54):
                rect_y = offset.y + year_size + 2
                for j in range(7):
                    if int(github_rect_day.year) > year:
                        break
                    rect_y += 3.5
                    color = "#444444"
                    date_title = str(github_rect_day)
                    if date_title in self.poster.tracks_by_date:
                        tracks = self.poster.tracks_by_date[date_title]
                        length = sum([t.length for t in tracks])
                        distance1 = self.poster.special_distance[
                            "special_distance"]
                        distance2 = self.poster.special_distance[
                            "special_distance2"]
                        has_special = distance1 < length / 1000 < distance2
                        color = self.color(self.poster.length_range_by_date,
                                           length, has_special)
                        if length / 1000 >= distance2:
                            color = self.poster.colors.get(
                                "special2") or self.poster.colors.get(
                                    "special")
                        str_length = format_float(self.poster.m2u(length))
                        date_title = f"{date_title} {str_length} {km_or_mi}"

                    rect = dr.rect((rect_x, rect_y), dom, fill=color)
                    rect.set_desc(title=date_title)
                    dr.add(rect)
                    github_rect_day += datetime.timedelta(1)
                rect_x += 3.5
            offset.y += 3.5 * 9 + year_size + 1.5
Esempio n. 34
0
def add_graphelement_to_svg_drawing(element: GraphElement,
                                    drawing: svgwrite.Drawing,
                                    filters: Dict[str, Filter]) -> None:
    args = {}
    for attr, value in element.attr.items():
        if attr.startswith('.svg_tag'):
            continue
        if attr.startswith('.svg_'):
            name = attr[5:]
            if name == 'filter':
                args[name] = filters[value].get_funciri()
            else:
                args[name] = value
    if '.svg_tag' in element.attr:
        tag = element.attr['.svg_tag']
        if tag == 'rect':
            x = float(element.attr['x'])
            y = -float(element.attr['y'])
            width = float(element.attr.get('.svg_width', 0.1))
            height = float(element.attr.get('.svg_height', 0.1))
            x = x - width / 2
            y = y - height / 2
            drawing.add(drawing.rect((x*mult, y*mult), (width*mult, height*mult),
                                     **args))
        elif tag == 'path':
            drawing.add(drawing.path(**args))
        elif tag == 'circle':
            x = float(element.attr['x'])
            y = -float(element.attr['y'])
            args.setdefault('r', '1cm')
            args.setdefault('stroke_width', '0.1mm')
            args.setdefault('stroke', 'black')
            args.setdefault('fill', 'none')
            drawing.add(drawing.circle(center=(x * mult, y * mult), **args))
        elif tag == 'image':
            x = float(element.attr['x'])
            y = -float(element.attr['y'])
            width = float(element.attr.pop('.svg_width', 5))
            height = float(element.attr.pop('.svg_height', 5))
            x = x - width / 2
            y = y - height / 2
            center = ((x + width / 2), (y + height / 2))
            args.setdefault('insert', (x * mult, y * mult))
            args.setdefault('size', (width * mult, height * mult))
            if '.svgx_rotate' in element.attr:
                rotation = float(element.attr['.svgx_rotate'])
                args.setdefault('transform',
                                f'translate({center[0]*mult}, {center[1]*mult}) '
                                f'rotate({-rotation}) '
                                f'translate({-center[0]*mult}, {-center[1]*mult})'
                                )
            drawing.add(getattr(drawing, element.attr['.svg_tag'])(**args))
        elif tag != 'None' and tag is not None:
            drawing.add(getattr(drawing, element.attr['.svg_tag'])(**args))
    elif isinstance(element, Vertex):
        if '.helper_node' in element.attr and element.attr['.helper_node']:
            return
        x = float(element.attr['x'])
        y = -float(element.attr['y'])
        args.setdefault('r', '0.4cm')
        args.setdefault('stroke_width', '1mm')
        args.setdefault('stroke', 'black')
        args.setdefault('fill', 'none')
        drawing.add(drawing.circle(center=(x*mult, y*mult), **args))
    elif isinstance(element, Edge):
        v1 = element.vertex1
        v2 = element.vertex2
        x1 = float(v1.attr['x'])
        y1 = -float(v1.attr['y'])
        x2 = float(v2.attr['x'])
        y2 = -float(v2.attr['y'])
        args.setdefault('stroke_width', '1mm')
        args.setdefault('stroke', 'black')
        drawing.add(drawing.line(start=(x1*mult, y1*mult), end=(x2*mult, y2*mult),
                                 **args))
    else:
        raise ValueError