Ejemplo n.º 1
0
    def draw_node(self, node: Node, painter):
        """Draw the specified node."""
        painter.setBrush(
            QBrush(
                self.selected_color
                if node is self.selected_node else self.regular_node_color,
                Qt.SolidPattern,
            ))

        node_position = node.get_position()
        node_radius = Vector(node.get_radius()).repeat(2)

        painter.drawEllipse(QPointF(*node_position), *node_radius)

        if self.labels_checkbox.isChecked():
            label = node.get_label()

            # scale font down, depending on the length of the label of the node
            painter.setFont(
                QFont(self.font_family, self.font_size / len(label)))

            # draw the node label within the node dimensions
            painter.drawText(
                QRectF(*(node_position - node_radius), *(2 * node_radius)),
                Qt.AlignCenter,
                label,
            )
Ejemplo n.º 2
0
    def get_vertex_position(self, n1: Node, n2: Node) -> Tuple[Vector, Vector]:
        """Return the position of the vertex on the screen."""
        # positions of the nodes
        n1_p = Vector(*n1.get_position())
        n2_p = Vector(*n2.get_position())

        # unit vector from n1 to n2
        uv = (n2_p - n1_p).unit()

        # start and end of the vertex to be drawn
        start = n1_p + uv * n1.get_radius()
        end = n2_p - uv * n2.get_radius()

        if self.graph.is_directed():
            # if the graph is directed and a vertex exists that goes the other way, we
            # have to move the start end end so the vertexes don't overlap
            if self.graph.does_vertex_exist(n2, n1):
                start = start.rotated(self.arrow_separation, n1_p)
                end = end.rotated(-self.arrow_separation, n2_p)

        return start, end
Ejemplo n.º 3
0
    def get_vertex_weight_rect(self, n1: Node, n2: Node, weight: float):
        """Get a RectF surrounding the weight of the node."""
        r = self.weight_rectangle_size

        # width adjusted to number of chars in weight label
        adjusted_width = len(str(weight)) / 3 * r + r / 3
        weight_vector = Vector(r if adjusted_width <= r else adjusted_width, r)

        if n1 is n2:
            # special case for a vertex pointing to itself
            mid = n1.get_position() - Vector(r * 3, r * 4)
        else:
            start, end = self.get_vertex_position(n1, n2)
            mid = (start + end) / 2

        return QRectF(*(mid - weight_vector), *(2 * weight_vector))
Ejemplo n.º 4
0
    def draw_vertex(self, n1: Node, n2: Node, weight: float, painter):
        """Draw the specified vertex."""
        # special case for a node pointing to itself
        if n1 is n2:
            r = n1.get_radius()
            x, y = n1.get_position()

            painter.setPen(QPen(Qt.black, Qt.SolidLine))
            painter.setBrush(QBrush(Qt.black, Qt.NoBrush))

            painter.drawEllipse(QPointF(x - r / 2, y - r), r / 2, r / 2)

            head = Vector(x, y) - Vector(0, r)
            uv = Vector(0, 1)

            painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
            painter.drawPolygon(
                QPointF(*head),
                QPointF(*(head +
                          (-uv).rotated(radians(10)) * self.arrowhead_size)),
                QPointF(*(head +
                          (-uv).rotated(radians(-50)) * self.arrowhead_size)),
            )
        else:
            start, end = self.get_vertex_position(n1, n2)

            # draw the head of a directed arrow, which is an equilateral triangle
            if self.graph.is_directed():
                uv = (end - start).unit()

                painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
                painter.drawPolygon(
                    QPointF(*end),
                    QPointF(
                        *(end +
                          (-uv).rotated(radians(30)) * self.arrowhead_size)),
                    QPointF(
                        *(end +
                          (-uv).rotated(radians(-30)) * self.arrowhead_size)),
                )

            painter.setPen(QPen(Qt.black, Qt.SolidLine))
            painter.drawLine(QPointF(*start), QPointF(*end))

        if self.graph.is_weighted():
            # set color according to whether the vertex is selected or not
            painter.setBrush(
                QBrush(
                    self.selected_color if self.selected_vertex is not None and
                    ((n1 is self.selected_vertex[0]
                      and n2 is self.selected_vertex[1]) or
                     (not self.graph.is_directed()
                      and n2 is self.selected_vertex[0]
                      and n1 is self.selected_vertex[1])) else
                    self.regular_vertex_weight_color,
                    Qt.SolidPattern,
                ))

            weight_rectangle = self.get_vertex_weight_rect(n1, n2, weight)
            painter.drawRect(weight_rectangle)

            painter.setFont(QFont(self.font_family, int(self.font_size / 4)))

            painter.setPen(QPen(Qt.white, Qt.SolidLine))
            painter.drawText(weight_rectangle, Qt.AlignCenter, str(weight))
            painter.setPen(QPen(Qt.black, Qt.SolidLine))