def __init__(self, tree_node, parent=None, **kwargs):
        self.tree_node = tree_node
        self.tree_node.graphics_item = self

        center, length, angle = tree_node.square
        self._center_point = center
        self.center = QPointF(*center)
        self.length = length
        self.angle = angle
        super().__init__(self._get_rect_attributes(), parent)
        self.setTransformOriginPoint(self.boundingRect().center())
        self.setRotation(degrees(angle))

        self.setBrush(kwargs.get('brush', QColor('#297A1F')))
        self.setPen(kwargs.get('pen', QPen(QColor('#000'))))

        self.setAcceptHoverEvents(True)
        self.setZValue(kwargs.get('zvalue', 0))
        self.z_step = Z_STEP

        # calculate the correct z values based on the parent
        if self.tree_node.parent != TreeAdapter.ROOT_PARENT:
            p = self.tree_node.parent
            # override root z step
            num_children = len(p.children)
            own_index = [1 if c.label == self.tree_node.label else 0
                         for c in p.children].index(1)

            self.z_step = int(p.graphics_item.z_step / num_children)
            base_z = p.graphics_item.zValue()

            self.setZValue(base_z + own_index * self.z_step)
Exemple #2
0
def path_link_disabled(basepath):
    """
    Return a QPainterPath 'styled' to indicate a 'disabled' link.

    A disabled link is displayed with a single disconnection symbol in the
    middle (--||--)

    Parameters
    ----------
    basepath : QPainterPath
        The base path (a simple curve spine).

    Returns
    -------
    path : QPainterPath
        A 'styled' link path
    """
    segmentlen = basepath.length()
    px = 5

    if segmentlen < 10:
        return QPainterPath(basepath)

    t = (px / 2) / segmentlen
    p1, _ = qpainterpath_simple_split(basepath, 0.50 - t)
    _, p2 = qpainterpath_simple_split(basepath, 0.50 + t)

    angle = -basepath.angleAtPercent(0.5) + 90
    angler = math.radians(angle)
    normal = QPointF(math.cos(angler), math.sin(angler))

    end1 = p1.currentPosition()
    start2 = QPointF(p2.elementAt(0).x, p2.elementAt(0).y)
    p1.moveTo(start2.x(), start2.y())
    p1.addPath(p2)

    def QPainterPath_addLine(path, line):
        path.moveTo(line.p1())
        path.lineTo(line.p2())

    QPainterPath_addLine(p1, QLineF(end1 - normal * 3, end1 + normal * 3))
    QPainterPath_addLine(p1, QLineF(start2 - normal * 3, start2 + normal * 3))
    return p1
Exemple #3
0
 def test_selection_no_data(self):
     self.widget.graph._update_selection(QPointF(0, 5), QPointF(0, 6), 1)
     selected = self.get_output(self.widget.Outputs.selected_data)
     self.assertIsNone(selected)
Exemple #4
0
def innerGlowBackgroundPixmap(color, size, radius=5):
    """ Draws radial gradient pixmap, then uses that to draw
    a rounded-corner gradient rectangle pixmap.

    Args:
        color (QColor): used as outer color (lightness 245 used for inner)
        size (QSize): size of output pixmap
        radius (int): radius of inner glow rounded corners
    """
    key = "InnerGlowBackground " + \
          color.name() + " " + \
          str(radius)

    bg = QPixmapCache.find(key)
    if bg:
        return bg

    # set background colors for gradient
    color = color.toHsl()
    light_color = color.fromHsl(color.hslHue(), color.hslSaturation(), 245)
    dark_color = color

    # initialize radial gradient
    center = QPoint(radius, radius)
    pixRect = QRect(0, 0, radius * 2, radius * 2)
    gradientPixmap = QPixmap(radius * 2, radius * 2)
    gradientPixmap.fill(dark_color)

    # draw radial gradient pixmap
    pixPainter = QPainter(gradientPixmap)
    pixPainter.setPen(Qt.NoPen)
    gradient = QRadialGradient(center, radius - 1)
    gradient.setColorAt(0, light_color)
    gradient.setColorAt(1, dark_color)
    pixPainter.setBrush(gradient)
    pixPainter.drawRect(pixRect)
    pixPainter.end()

    # set tl and br to the gradient's square-shaped rect
    tl = QPoint(0, 0)
    br = QPoint(size.width(), size.height())

    # fragments of radial gradient pixmap to create rounded gradient outline rectangle
    frags = [
        # top-left corner
        QPainter.PixmapFragment.create(
            QPointF(tl.x() + radius / 2,
                    tl.y() + radius / 2), QRectF(0, 0, radius, radius)),
        # top-mid 'linear gradient'
        QPainter.PixmapFragment.create(QPointF(tl.x() + (br.x() - tl.x()) / 2,
                                               tl.y() + radius / 2),
                                       QRectF(radius, 0, 1, radius),
                                       scaleX=(br.x() - tl.x() - 2 * radius)),
        # top-right corner
        QPainter.PixmapFragment.create(
            QPointF(br.x() - radius / 2,
                    tl.y() + radius / 2), QRectF(radius, 0, radius, radius)),
        # left-mid 'linear gradient'
        QPainter.PixmapFragment.create(QPointF(tl.x() + radius / 2,
                                               tl.y() + (br.y() - tl.y()) / 2),
                                       QRectF(0, radius, radius, 1),
                                       scaleY=(br.y() - tl.y() - 2 * radius)),
        # mid solid
        QPainter.PixmapFragment.create(QPointF(tl.x() + (br.x() - tl.x()) / 2,
                                               tl.y() + (br.y() - tl.y()) / 2),
                                       QRectF(radius, radius, 1, 1),
                                       scaleX=(br.x() - tl.x() - 2 * radius),
                                       scaleY=(br.y() - tl.y() - 2 * radius)),
        # right-mid 'linear gradient'
        QPainter.PixmapFragment.create(QPointF(br.x() - radius / 2,
                                               tl.y() + (br.y() - tl.y()) / 2),
                                       QRectF(radius, radius, radius, 1),
                                       scaleY=(br.y() - tl.y() - 2 * radius)),
        # bottom-left corner
        QPainter.PixmapFragment.create(
            QPointF(tl.x() + radius / 2,
                    br.y() - radius / 2), QRectF(0, radius, radius, radius)),
        # bottom-mid 'linear gradient'
        QPainter.PixmapFragment.create(QPointF(tl.x() + (br.x() - tl.x()) / 2,
                                               br.y() - radius / 2),
                                       QRectF(radius, radius, 1, radius),
                                       scaleX=(br.x() - tl.x() - 2 * radius)),
        # bottom-right corner
        QPainter.PixmapFragment.create(
            QPointF(br.x() - radius / 2,
                    br.y() - radius / 2), QRectF(radius, radius, radius,
                                                 radius)),
    ]

    # draw icon background to pixmap
    outPix = QPixmap(size.width(), size.height())
    outPainter = QPainter(outPix)
    outPainter.setPen(Qt.NoPen)
    outPainter.drawPixmapFragments(
        frags, gradientPixmap,
        QPainter.PixmapFragmentHints(QPainter.OpaqueHint))
    outPainter.end()

    QPixmapCache.insert(key, outPix)

    return outPix
Exemple #5
0
 def select_by_rectangle(self, value_rect):
     if self.scatterplot_item is not None:
         points = [point
                   for point in self.scatterplot_item.points()
                   if value_rect.contains(QPointF(point.pos()))]
         self.select(points)
Exemple #6
0
 def rect(self):
     if getattr(self, "_rect", QRectF()).isValid():
         return self._rect
     else:
         return QRectF(QPointF(0, 0), self.document().size()) | \
                getattr(self, "_rect", QRectF(0, 0, 1, 1))
 def _get_polygon(self) -> QPolygonF:
     return QPolygonF([QPointF(x, y) for x, y in self.get_points()])
 def _activate_cut_line(self, pos: QPointF):
     """Activate cut line selection an set cut value to `pos.x()`."""
     self.selection_method = 1
     self.cut_line.setValue(pos.x())
     self._selection_method_changed()
 def poly2qpoly(poly: Polygon) -> QPolygonF:
     return QPolygonF([QPointF(x, y)
                       for x, y in poly.exterior.coords])
Exemple #10
0
 def edge_in_point(self, edge):
     return edge.mapFromItem(
         self, QPointF(self.rect().center().x(),
                       self.rect().y()))
 def shape(self):
     if self.__shape is None:
         path = self.getPath()
         d = self.pixelLength(QPointF(0, self.opts["mouseWidth"]))
         self.__shape = shape_from_path(path, width=d)
     return self.__shape
Exemple #12
0
 def test_migrate_selection(self):
     c = QPointF()  # some we set an attribute to
     setattr(c, "selection", [False, True, True, False])
     settings = {"context_settings": [c]}
     OWHyper.migrate_settings(settings, 2)
     self.assertEqual(settings["imageplot"]["selection_group_saved"], [(1, 1), (2, 1)])
Exemple #13
0
    def _add_command(self, cmd):
        name = "Name"

        if not self.hasAttr2 and isinstance(
                cmd, (Move, MoveSelection, Jitter, Magnet)):
            # tool only supported if both x and y are enabled
            return

        if isinstance(cmd, Append):
            cls = self.selected_class_label()
            points = np.array([(p.x(), p.y() if self.hasAttr2 else 0, cls)
                               for p in cmd.points])
            self.undo_stack.push(UndoCommand(Append(points), self, text=name))
        elif isinstance(cmd, Move):
            self.undo_stack.push(UndoCommand(cmd, self, text=name))
        elif isinstance(cmd, SelectRegion):
            indices = [
                i for i, (x, y) in enumerate(self.__buffer[:, :2])
                if cmd.region.contains(QPointF(x, y))
            ]
            indices = np.array(indices, dtype=int)
            self._selected_indices = indices
        elif isinstance(cmd, DeleteSelection):
            indices = self._selected_indices
            if indices is not None and indices.size:
                self.undo_stack.push(
                    UndoCommand(DeleteIndices(indices), self, text="Delete"))
        elif isinstance(cmd, MoveSelection):
            indices = self._selected_indices
            if indices is not None and indices.size:
                self.undo_stack.push(
                    UndoCommand(
                        Move(
                            (self._selected_indices, slice(0, 2)),
                            np.array([cmd.delta.x(),
                                      cmd.delta.y()]),
                        ),
                        self,
                        text="Move",
                    ))
        elif isinstance(cmd, DeleteIndices):
            self.undo_stack.push(UndoCommand(cmd, self, text="Delete"))
        elif isinstance(cmd, Insert):
            self.undo_stack.push(UndoCommand(cmd, self))
        elif isinstance(cmd, AirBrush):
            data = create_data(
                cmd.pos.x(),
                cmd.pos.y(),
                self.brushRadius / 1000,
                int(1 + self.density / 20),
                cmd.rstate,
            )
            self._add_command(Append([QPointF(*p) for p in zip(*data.T)]))
        elif isinstance(cmd, Jitter):
            point = np.array([cmd.pos.x(), cmd.pos.y()])
            delta = -apply_jitter(self.__buffer[:, :2], point,
                                  self.density / 100.0, 0, cmd.rstate)
            self._add_command(Move((..., slice(0, 2)), delta))
        elif isinstance(cmd, Magnet):
            point = np.array([cmd.pos.x(), cmd.pos.y()])
            delta = -apply_attractor(self.__buffer[:, :2], point,
                                     self.density / 100.0, 0)
            self._add_command(Move((..., slice(0, 2)), delta))
        else:
            assert False, "unreachable"
Exemple #14
0
 def _select_data(self):
     self.widget.graph._update_selection(QPointF(0, 5), QPointF(0, 6), True)
     assert len(self.widget.selection) == 30
     return self.widget.selection
Exemple #15
0
 def test_selection_no_group(self):
     self.send_signal(self.widget.Inputs.data, self.housing)
     self.widget.graph._update_selection(QPointF(0, 30), QPointF(0, 40), 1)
     selected = self.get_output(self.widget.Outputs.selected_data)
     self.assertEqual(len(selected), 53)
Exemple #16
0
def innerShadowPixmap(color, size, pos, length=5):
    """
    Args:
        color (QColor): shadow color
        size (QSize): size of pixmap
        pos (int): shadow position int flag, use bitwise operations
            1 - top
            2 - right
            4 - bottom
            8 - left
        length (int): length of cast shadow
    """
    key = "InnerShadow " + \
          color.name() + " " + \
          str(size) + " " + \
          str(pos) + " " + \
          str(length)
    # get cached shadow if it exists
    finalShadow = QPixmapCache.find(key)
    if finalShadow:
        return finalShadow

    # get shadow template pixmap (1-pixel linear gradient line)
    shadowTemplate = QPixmapCache.find("TabButtonShadowTemplate" + str(length))
    if shadowTemplate is None:
        shadowTemplate = shadowTemplatePixmap(color, length)
        QPixmapCache.insert("TabButtonShadowTemplate" + str(length),
                            shadowTemplate)

    finalShadow = QPixmap(size)
    finalShadow.fill(Qt.transparent)
    shadowPainter = QPainter(finalShadow)
    shadowPainter.setCompositionMode(QPainter.CompositionMode_Darken)

    # top/bottom rect
    targetRect = QRect(0, 0, size.width(), length)

    # shadow on top
    if pos & 1:
        shadowPainter.drawPixmap(targetRect, shadowTemplate,
                                 shadowTemplate.rect())
    # shadow on bottom
    if pos & 4:
        shadowPainter.save()

        shadowPainter.translate(QPointF(0, size.height()))
        shadowPainter.scale(1, -1)
        shadowPainter.drawPixmap(targetRect, shadowTemplate,
                                 shadowTemplate.rect())

        shadowPainter.restore()

    # left/right rect
    targetRect = QRect(0, 0, size.height(), shadowTemplate.rect().height())

    # shadow on the right
    if pos & 2:
        shadowPainter.save()

        shadowPainter.translate(QPointF(size.width(), 0))
        shadowPainter.rotate(90)
        shadowPainter.drawPixmap(targetRect, shadowTemplate,
                                 shadowTemplate.rect())

        shadowPainter.restore()
    # shadow on left
    if pos & 8:
        shadowPainter.save()

        shadowPainter.translate(0, size.height())
        shadowPainter.rotate(-90)
        shadowPainter.drawPixmap(targetRect, shadowTemplate,
                                 shadowTemplate.rect())

        shadowPainter.restore()

    shadowPainter.end()

    # cache shadow
    QPixmapCache.insert(key, finalShadow)

    return finalShadow
Exemple #17
0
 def _select_data(self):
     self.widget.select_area(
         1,
         QMouseEvent(QEvent.MouseButtonPress, QPointF(), Qt.LeftButton,
                     Qt.LeftButton, Qt.NoModifier))
     return [2, 3, 9, 23, 29, 30, 34, 35, 37, 42, 47, 49]
Exemple #18
0
 def projection(point, line):
     norm = line.normalVector()
     norm.translate(point - norm.p1())
     p = QPointF()
     type = line.intersect(norm, p)
     return p
Exemple #19
0
 def _update_bar_size(self):
     if self._silplot is not None:
         self._set_bar_height()
         self.scene.setSceneRect(
             QRectF(QPointF(0, 0),
                    self._silplot.effectiveSizeHint(Qt.PreferredSize)))
    def __init__(self, data, variable, parent=None, height=200,
                 width=300, side_padding=5, top_padding=20, bar_spacing=4,
                 border=0, border_color=None, color_attribute=None, n_bins=10):
        super().__init__(parent)
        self.height, self.width = height, width
        self.padding = side_padding
        self.bar_spacing = bar_spacing

        self.data = data
        self.attribute = data.domain[variable]

        self.x = data.get_column_view(self.attribute)[0].astype(np.float64)
        self.x_nans = np.isnan(self.x)
        self.x = self.x[~self.x_nans]

        if self.attribute.is_discrete:
            self.n_bins = len(self.attribute.values)
        elif self.attribute.is_continuous:
            # If the attribute is continuous but contains fewer values than the
            # bins, it is better to assign each their own bin. We will require
            # at least 2 bins so that the histogram still visually makes sense
            # except if there is only a single value, then we use 3 bins for
            # symmetry
            num_unique = ut.nanunique(self.x).shape[0]
            if num_unique == 1:
                self.n_bins = 3
            else:
                self.n_bins = min(max(2, num_unique), n_bins)

        # Handle target variable index
        self.color_attribute = color_attribute
        if self.color_attribute is not None:
            self.target_var = data.domain[color_attribute]
            self.y = data.get_column_view(color_attribute)[0]
            self.y = self.y[~self.x_nans]
            if not np.issubdtype(self.y.dtype, np.number):
                self.y = self.y.astype(np.float64)
        else:
            self.target_var, self.y = None, None

        # Borders
        self.border_color = border_color if border_color is not None else '#000'
        if isinstance(border, tuple):
            assert len(border) == 4, 'Border tuple must be of size 4.'
            self.border = border
        else:
            self.border = (border, border, border, border)
        t, r, b, l = self.border

        def _draw_border(point_1, point_2, border_width, parent):
            pen = QPen(QColor(self.border_color))
            pen.setCosmetic(True)
            pen.setWidth(border_width)
            line = QGraphicsLineItem(QLineF(point_1, point_2), parent)
            line.setPen(pen)
            return line

        top_left = QPointF(0, 0)
        bottom_left = QPointF(0, self.height)
        top_right = QPointF(self.width, 0)
        bottom_right = QPointF(self.width, self.height)

        self.border_top = _draw_border(top_left, top_right, t, self) if t else None
        self.border_bottom = _draw_border(bottom_left, bottom_right, b, self) if b else None
        self.border_left = _draw_border(top_left, bottom_left, l, self) if l else None
        self.border_right = _draw_border(top_right, bottom_right, r, self) if r else None

        # _plot_`dim` accounts for all the paddings and spacings
        self._plot_height = self.height
        self._plot_height -= top_padding
        self._plot_height -= t / 4 + b / 4

        self._plot_width = self.width
        self._plot_width -= 2 * side_padding
        self._plot_width -= (self.n_bins - 2) * bar_spacing
        self._plot_width -= l / 4 + r / 4

        self.__layout = QGraphicsLinearLayout(Qt.Horizontal, self)
        self.__layout.setContentsMargins(
            side_padding + r / 2,
            top_padding + t / 2,
            side_padding + l / 2,
            b / 2
        )
        self.__layout.setSpacing(bar_spacing)

        # If the data contains any non-NaN values, we can draw a histogram
        if self.x.size > 0:
            self.edges, self.distributions = self._histogram()
            self._draw_histogram()
Exemple #21
0
 def try_big_selection(self):
     self.widget.imageplot.select_square(QPointF(-100, -100),
                                         QPointF(100, 100))
     self.widget.imageplot.make_selection(None)
class SquareGraphicsItem(QGraphicsRectItem):
    """Square Graphics Item.

    Square component to draw as components for the non-interactive Pythagoras
    tree.

    Parameters
    ----------
    tree_node : TreeNode
        The tree node the square represents.
    brush : QColor, optional
        The brush to be used as the backgound brush.
    pen : QPen, optional
        The pen to be used for the border.

    """
    def __init__(self, tree_node, parent=None, **kwargs):
        self.tree_node = tree_node
        self.tree_node.graphics_item = self

        center, length, angle = tree_node.square
        self._center_point = center
        self.center = QPointF(*center)
        self.length = length
        self.angle = angle
        super().__init__(self._get_rect_attributes(), parent)
        self.setTransformOriginPoint(self.boundingRect().center())
        self.setRotation(degrees(angle))

        self.setBrush(kwargs.get('brush', QColor('#297A1F')))
        self.setPen(kwargs.get('pen', QPen(QColor('#000'))))

        self.setAcceptHoverEvents(True)
        self.setZValue(kwargs.get('zvalue', 0))
        self.z_step = Z_STEP

        # calculate the correct z values based on the parent
        if self.tree_node.parent != TreeAdapter.ROOT_PARENT:
            p = self.tree_node.parent
            # override root z step
            num_children = len(p.children)
            own_index = [
                1 if c.label == self.tree_node.label else 0 for c in p.children
            ].index(1)

            self.z_step = int(p.graphics_item.z_step / num_children)
            base_z = p.graphics_item.zValue()

            self.setZValue(base_z + own_index * self.z_step)

    def _get_rect_attributes(self):
        """Get the rectangle attributes requrired to draw item.

        Compute the QRectF that a QGraphicsRect needs to be rendered with the
        data passed down in the constructor.

        """
        height = width = self.length
        x = self.center.x() - self.length / 2
        y = self.center.y() - self.length / 2
        return QRectF(x, y, height, width)
Exemple #23
0
 def test_select_click(self):
     self.send_signal("Data", self.whitelight)
     self.widget.imageplot.select_by_click(QPointF(1, 2))
     out = self.get_output("Selection")
     np.testing.assert_equal(out.metas, [[1, 2]])
    def _dendrogram_slider_changed(self, value):
        p = QPointF(value, 0)
        cl_height = self.dendrogram.height_at(p)

        self.set_cutoff_height(cl_height)
class SquareGraphicsItem(QGraphicsRectItem):
    """Square Graphics Item.

    Square component to draw as components for the non-interactive Pythagoras
    tree.

    Parameters
    ----------
    tree_node : TreeNode
        The tree node the square represents.
    brush : QColor, optional
        The brush to be used as the backgound brush.
    pen : QPen, optional
        The pen to be used for the border.

    """

    def __init__(self, tree_node, parent=None, **kwargs):
        self.tree_node = tree_node
        self.tree_node.graphics_item = self

        center, length, angle = tree_node.square
        self._center_point = center
        self.center = QPointF(*center)
        self.length = length
        self.angle = angle
        super().__init__(self._get_rect_attributes(), parent)
        self.setTransformOriginPoint(self.boundingRect().center())
        self.setRotation(degrees(angle))

        self.setBrush(kwargs.get('brush', QColor('#297A1F')))
        self.setPen(kwargs.get('pen', QPen(QColor('#000'))))

        self.setAcceptHoverEvents(True)
        self.setZValue(kwargs.get('zvalue', 0))
        self.z_step = Z_STEP

        # calculate the correct z values based on the parent
        if self.tree_node.parent != TreeAdapter.ROOT_PARENT:
            p = self.tree_node.parent
            # override root z step
            num_children = len(p.children)
            own_index = [1 if c.label == self.tree_node.label else 0
                         for c in p.children].index(1)

            self.z_step = int(p.graphics_item.z_step / num_children)
            base_z = p.graphics_item.zValue()

            self.setZValue(base_z + own_index * self.z_step)

    def _get_rect_attributes(self):
        """Get the rectangle attributes requrired to draw item.

        Compute the QRectF that a QGraphicsRect needs to be rendered with the
        data passed down in the constructor.

        """
        height = width = self.length
        x = self.center.x() - self.length / 2
        y = self.center.y() - self.length / 2
        return QRectF(x, y, height, width)
Exemple #26
0
 def _select_data(self):
     rect = QRectF(QPointF(-20, -20), QPointF(20, 20))
     self.widget.graph.select_by_rectangle(rect)
     return self.widget.graph.get_selection()
 def _select_data(self):
     rect = QRectF(QPointF(0, 0), QPointF(1, 1))
     self.widget.graph.select_by_rectangle(rect)
     return np.arange(len(self.data))
Exemple #28
0
    def __init__(self, *args):
        QGraphicsObject.__init__(self, *args)
        self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, True)
        self.setFlag(QGraphicsItem.ItemHasNoContents, True)

        self.__direction = QPointF()
 def anchorDirection(self):
     # type: () -> QPointF
     """
     Return the preferred anchor direction.
     """
     return QPointF(self.__direction)
Exemple #30
0
 def anchorScenePos(self):
     """
     Return anchor position in scene coordinates.
     """
     return self.mapToScene(QPointF(0, 0))
Exemple #31
0
 def setCutoff(self, x, y):
     if (x, y) != self.cutoff():
         self.__setpos(Qt.Vertical | Qt.Horizontal, QPointF(x, y))