Ejemplo n.º 1
0
 def draw_y_axis(self):
     lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0]),
                                  0, self.coordY(self.ylim[1]),
                                  parent=self.item)
     lineItem.setPen(QPen(QColor('black')))
     lineItem.setZValue(10)
     max_w = 0
     for y in set(self.hlines + list(self.ylim)):
         lineItem = QGraphicsLineItem(0, self.coordY(y),
                                            -5, self.coordY(y),
                                            parent=self.item)
         lineItem.setPen(QPen(QColor('black')))
         lineItem.setZValue(10)
         text = QGraphicsSimpleTextItem(str(y))
         text.setFont(QFont("Arial", self.fsize-2))
         text.setParentItem(self.item)
         tw = text.boundingRect().width()
         max_w = tw if tw > max_w else max_w
         th = text.boundingRect().height()
         # Center text according to masterItem size
         text.setPos(-tw - 5, self.coordY(y)-th/2)
     if self.ylabel:
         text = QGraphicsSimpleTextItem(self.ylabel)
         text.setFont(QFont("Arial", self.fsize-1))
         text.setParentItem(self.item)
         text.rotate(-90)
         tw = text.boundingRect().width()
         th = text.boundingRect().height()
         # Center text according to masterItem size
         text.setPos(-th -5-max_w, tw/2+self.coordY(sum(self.ylim)/2))
Ejemplo n.º 2
0
    def moveTo(self, pos):
        #data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x, y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(
            QPen(QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        #update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX, oldY), QSize(1, 1))
        #grow bounding box
        self.bb.setLeft(
            min(self.bb.left(), max(0, x - self.brushSize // 2 - 1)))
        self.bb.setRight(
            max(self.bb.right(),
                min(self.sliceRect[0] - 1, x + self.brushSize // 2 + 1)))
        self.bb.setTop(min(self.bb.top(), max(0, y - self.brushSize // 2 - 1)))
        self.bb.setBottom(
            max(self.bb.bottom(),
                min(self.sliceRect[1] - 1, y + self.brushSize // 2 + 1)))

        #update/move position
        self.pos = pos
Ejemplo n.º 3
0
class GPendulum(Graphics.Items.ItemGroupBase):
    def _setup(self):
        self.rod = QGraphicsLineItem(QLineF(0, 0, 0, 100))
        p = QPen(QColor(100, 100, 100))
        p.setWidth(5)
        self.rod.setPen(p)
        self.rod.setToolTip('This is the rod of the pendulum')
        self.ball = QGraphicsEllipseItem(QRectF(-20, 80, 40, 40))
        b = QBrush(Qt.SolidPattern)
        b.setColor(QColor(0, 255, 0))
        self.ball.setBrush(b)
        self.ball.setToolTip('This is the ball of the pendulum where the mass is concentrated')
        self.addToGroup(self.rod)
        self.addToGroup(self.ball)
        self.setFlags(QGraphicsItem.ItemIsSelectable)

    def setProperties(self, q):
        self.properties = q

    def contextMenuEvent(self, e):
        e.accept()
        m = QMenu()
        p = m.addAction("Properties")
        a = m.exec_(e.screenPos())
        if a == p:
            dlg = SimTools.RichTypes.Qt4Widgets.SimpleRichTypesDialog(mainWin, 'Pendulum properties',
                text='Change physical properties', scrolling=False)
            dlg.addRichTypes(self.properties)
            dlg.exec_()
Ejemplo n.º 4
0
    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:

            downPos = event.buttonDownPos(Qt.LeftButton)
            if not self.__tmpLine and self.__dragStartItem and \
                    (downPos - event.pos()).manhattanLength() > \
                        QApplication.instance().startDragDistance():
                # Start a line drag
                line = QGraphicsLineItem(self)
                start = self.__dragStartItem.boundingRect().center()
                start = self.mapFromItem(self.__dragStartItem, start)
                line.setLine(start.x(), start.y(),
                             event.pos().x(),
                             event.pos().y())

                pen = QPen(Qt.black, 4)
                pen.setCapStyle(Qt.RoundCap)
                line.setPen(pen)
                line.show()

                self.__tmpLine = line

            if self.__tmpLine:
                # Update the temp line
                line = self.__tmpLine.line()
                line.setP2(event.pos())
                self.__tmpLine.setLine(line)

        QGraphicsWidget.mouseMoveEvent(self, event)
Ejemplo n.º 5
0
    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:

            downPos = event.buttonDownPos(Qt.LeftButton)
            if not self.__tmpLine and self.__dragStartItem and \
                    (downPos - event.pos()).manhattanLength() > \
                        QApplication.instance().startDragDistance():
                # Start a line drag
                line = QGraphicsLineItem(self)
                start = self.__dragStartItem.boundingRect().center()
                start = self.mapFromItem(self.__dragStartItem, start)
                line.setLine(start.x(), start.y(),
                             event.pos().x(), event.pos().y())

                pen = QPen(Qt.black, 4)
                pen.setCapStyle(Qt.RoundCap)
                line.setPen(pen)
                line.show()

                self.__tmpLine = line

            if self.__tmpLine:
                # Update the temp line
                line = self.__tmpLine.line()
                line.setP2(event.pos())
                self.__tmpLine.setLine(line)

        QGraphicsWidget.mouseMoveEvent(self, event)
Ejemplo n.º 6
0
 def draw_y_axis(self):
     lineItem = QGraphicsLineItem(0,
                                  self.coordY(self.ylim[0]),
                                  0,
                                  self.coordY(self.ylim[1]),
                                  parent=self.item)
     lineItem.setPen(QPen(QColor('black')))
     lineItem.setZValue(10)
     max_w = 0
     for y in set(self.hlines + list(self.ylim)):
         lineItem = QGraphicsLineItem(0,
                                      self.coordY(y),
                                      -5,
                                      self.coordY(y),
                                      parent=self.item)
         lineItem.setPen(QPen(QColor('black')))
         lineItem.setZValue(10)
         text = QGraphicsSimpleTextItem(str(y))
         text.setFont(QFont("Arial", self.fsize - 2))
         text.setParentItem(self.item)
         tw = text.boundingRect().width()
         max_w = tw if tw > max_w else max_w
         th = text.boundingRect().height()
         # Center text according to masterItem size
         text.setPos(-tw - 5, self.coordY(y) - th / 2)
     if self.ylabel:
         text = QGraphicsSimpleTextItem(self.ylabel)
         text.setFont(QFont("Arial", self.fsize - 1))
         text.setParentItem(self.item)
         text.rotate(-90)
         tw = text.boundingRect().width()
         th = text.boundingRect().height()
         # Center text according to masterItem size
         text.setPos(-th - 5 - max_w,
                     tw / 2 + self.coordY(sum(self.ylim) / 2))
Ejemplo n.º 7
0
 def draw_errors(self, x, i):
     lower = self.values[i]+self._dw_err[i]
     upper = self.values[i]+self._up_err[i]
     lineItem = QGraphicsLineItem(0, self.coordY(lower), 0,
                                        self.coordY(upper), parent=self.item)
     lineItem.setX(x)
     lineItem.setPen(QPen(QColor('black'),1))
Ejemplo n.º 8
0
 def draw_hlines(self, line, col):
     lineItem = QGraphicsLineItem(0,
                                  self.coordY(line),
                                  self.width,
                                  self.coordY(line),
                                  parent=self.item)
     lineItem.setPen(QPen(QColor(col), 1, Qt.DashLine))
     lineItem.setZValue(10)
Ejemplo n.º 9
0
 def draw_stick(self, x, y, i):
     lineItem = QGraphicsLineItem(0,
                                  self.coordY(self.ylim[0]),
                                  0,
                                  self.coordY(y),
                                  parent=self.item)
     lineItem.setX(x)
     lineItem.setPen(QPen(QColor(self.colors[i]), 2))
Ejemplo n.º 10
0
 def draw_errors(self, x, i):
     lower = self.values[i] + self._dw_err[i]
     upper = self.values[i] + self._up_err[i]
     lineItem = QGraphicsLineItem(0,
                                  self.coordY(lower),
                                  0,
                                  self.coordY(upper),
                                  parent=self.item)
     lineItem.setX(x)
     lineItem.setPen(QPen(QColor('black'), 1))
Ejemplo n.º 11
0
class CrossX(ItemGroupBase):
    """a cross (x) made of two lines"""
    def _setup(self, x=0, y=0, size=10, pen=QPen(QColor(0,0, 255))):
        a = 0.5*size
        self.p1 = QGraphicsLineItem(QLineF(x-a, y-a, x+a, y+a))
        self.p2 = QGraphicsLineItem(QLineF(x-a, y+a, x+a, y-a))
        self.p1.setPen(pen)
        self.p2.setPen(pen)
        self.addToGroup(self.p1)
        self.addToGroup(self.p2)
Ejemplo n.º 12
0
class Axes(ItemGroupBase):
    """two rectangular lines as axes"""
    def _setup(self, x=[0, -100, 100], y=[0, -100, 100], pen=QPen(QColor(255,0,0))):
        if x:
            self.xAxis = QGraphicsLineItem(QLineF(x[1], x[0], x[2], x[0]))
            self.xAxis.setPen(pen)
            self.addToGroup(self.xAxis)
        if y:
            self.yAxis = QGraphicsLineItem(QLineF(y[0], y[1], y[0], y[2]))
            self.yAxis.setPen(pen)
            self.addToGroup(self.yAxis)
Ejemplo n.º 13
0
 def onEdgeAdd(start,end):
   '''
   Whenever a new edge is added to model, this method is to be notified.
   '''
   p1 = nodeToScene[start].rect().center()
   p2 = nodeToScene[end]  .rect().center()
   line = QGraphicsLineItem( QLineF(p1,p2) )
   line.setPen( QPen( QColor(32,32,32), 1 ) )
   groupEdges.addToGroup(line)
   nodeToLineP1[start].add(line)
   nodeToLineP2  [end].add(line)
Ejemplo n.º 14
0
 def draw_curve(self, x, y, i):
     # top line
     lineItem = QGraphicsLineItem(0, self.coordY(y), 4,
                                        self.coordY(y), parent=self.item)
     lineItem.setX(x-2)
     lineItem.setPen(QPen(QColor(self.colors[i]),2))
     if i > 0:
         prev = self.values[i-1] if i>0 else self.values[i]
         lineItem = QGraphicsLineItem(0, self.coordY(prev), self.col_w-4,
                                            self.coordY(y), parent=self.item)
         lineItem.setX(x - self.col_w+2)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
Ejemplo n.º 15
0
    def onMouseMove_draw( self, imageview, event ):
        self._navIntr.onMouseMove_default( imageview, event )

        o = imageview.scene().data2scene.map(QPointF(imageview.oldX,imageview.oldY))
        n = imageview.scene().data2scene.map(QPointF(imageview.x,imageview.y))

        # Draw temporary line for the brush stroke so the user gets feedback before the data is really updated.
        pen = QPen( QBrush(self._brushingCtrl._brushingModel.drawColor), self._brushingCtrl._brushingModel.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        line = QGraphicsLineItem(o.x(), o.y(), n.x(), n.y())
        line.setPen(pen)
        
        imageview.scene().addItem(line)
        line.setParentItem(imageview.scene().dataRectItem)

        self._lineItems.append(line)
        self._brushingCtrl._brushingModel.moveTo(imageview.mousePos)
Ejemplo n.º 16
0
    def onMouseMove_draw( self, imageview, event ):
        self._navIntr.onMouseMove_default( imageview, event )

        o = imageview.scene().data2scene.map(QPointF(imageview.oldX,imageview.oldY))
        n = imageview.scene().data2scene.map(QPointF(imageview.x,imageview.y))

        # Draw temporary line for the brush stroke so the user gets feedback before the data is really updated.
        pen = QPen( QBrush(self._brushingCtrl._brushingModel.drawColor), self._brushingCtrl._brushingModel.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        line = QGraphicsLineItem(o.x(), o.y(), n.x(), n.y())
        line.setPen(pen)
        
        imageview.scene().addItem(line)
        line.setParentItem(imageview.scene().dataRect)

        self._lineItems.append(line)
        self._brushingCtrl._brushingModel.moveTo(imageview.mousePos)
Ejemplo n.º 17
0
    def draw_x_axis(self):
        lineItem = QGraphicsLineItem(self.col_w / 2,
                                     self.coordY(self.ylim[0]) + 2,
                                     self.width - self.col_w / 2,
                                     self.coordY(self.ylim[0]) + 2,
                                     parent=self.item)
        lineItem.setPen(QPen(QColor('black')))
        lineItem.setZValue(10)
        all_vals = list(range(0, len(self.values), self.x_inter_values))
        if (len(self.values) - 1) % self.x_inter_values:
            all_vals += [len(self.values) - 1]

        hp_x = []
        if self.hp:
            for x in list(range(0, len(self.values))):
                if self.x_values[x] in self.hp:
                    hp_x.append(x)
                    if not x in all_vals:
                        all_vals += [x]
        all_vals.sort()

        for x in all_vals:
            lineItem = QGraphicsLineItem(0,
                                         self.coordY(self.ylim[0]) + 2,
                                         0,
                                         self.coordY(self.ylim[0]) + 6,
                                         parent=self.item)
            lineItem.setX(x * self.col_w + self.col_w / 2)
            lineItem.setPen(QPen(QColor('black')))
            lineItem.setZValue(10)
            if x in hp_x:
                text = QGraphicsSimpleTextItem("*" + str(self.x_values[x]))
                qfont = QFont("Arial", self.fsize - 1)
                #qfont.setBold(True)
                text.setFont(qfont)
            else:
                text = QGraphicsSimpleTextItem(" " + str(self.x_values[x]))
                text.setFont(QFont("Arial", self.fsize - 1))
            text.rotate(-90)
            text.setParentItem(self.item)
            text.setZValue(10)
            tw = text.boundingRect().width()
            th = text.boundingRect().height()
            # Center text according to masterItem size
            text.setPos(x * self.col_w - th / 2 + self.col_w / 2,
                        tw + self.coordY(self.ylim[0]) + 7)
Ejemplo n.º 18
0
    def update_items(self):
        rect_h = self.height
        if self.x_axis:
            rect_h += 30
        self.item = QGraphicsRectItem(0, 0, self.width + 40, rect_h)
        self.item.setPen(QPen(QColor('white')))

        #X axis

        if self.x_axis:
            self.draw_x_axis()

        # Legend

        self.draw_legend()

        # Y axes and colo rect
        yi = -1
        for model in ["PCOC", "PC", "OC", "Topological", "Identical"]:
            if self.dict_values_pcoc.has_key(model):
                yi += 1
                y = yi * self.col_w

                # Y axes
                ## Stick
                yaxis = (yi + 0.5) * self.col_w
                lineItem = QGraphicsLineItem(self.width,
                                             yaxis,
                                             self.width + 5,
                                             yaxis,
                                             parent=self.item)
                lineItem.setPen(QPen(QColor('black')))
                ## Text
                text = QGraphicsSimpleTextItem(model)
                text.setFont(QFont("Arial", self.fsize - 2))
                text.setParentItem(self.item)
                tw = text.boundingRect().width()
                th = text.boundingRect().height()
                ## Center text according to masterItem size
                text.setPos(self.width + 5, yaxis - th / 2)

                # Color rect for each model
                values = self.dict_values_pcoc[model]
                for i, val in enumerate(values):
                    self.draw_fun(i * self.col_w, y, val, col_width=self.col_w)
Ejemplo n.º 19
0
 def draw_curve(self, x, y, i):
     # top line
     lineItem = QGraphicsLineItem(0,
                                  self.coordY(y),
                                  4,
                                  self.coordY(y),
                                  parent=self.item)
     lineItem.setX(x - 2)
     lineItem.setPen(QPen(QColor(self.colors[i]), 2))
     if i > 0:
         prev = self.values[i - 1] if i > 0 else self.values[i]
         lineItem = QGraphicsLineItem(0,
                                      self.coordY(prev),
                                      self.col_w - 4,
                                      self.coordY(y),
                                      parent=self.item)
         lineItem.setX(x - self.col_w + 2)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
Ejemplo n.º 20
0
    def addLines(self, x, y, w, h, diff, pen):
        if w == 0 or h == 0:
            return

        dist = 20 * diff  # original distance between two lines in pixels
        temp = dist
        canvas = self.canvas
        while temp < w:
            r = QGraphicsLineItem(temp + x, y, temp + x, y + h, None)
            canvas.addItem(r)
            r.setPen(pen)
            temp += dist

        temp = dist
        while temp < h:
            r = QGraphicsLineItem(x, y + temp, x + w, y + temp, None)
            canvas.addItem(r)
            r.setPen(pen)
            temp += dist
Ejemplo n.º 21
0
    def addLines(self, x, y, w, h, diff, pen):
        if w == 0 or h == 0:
            return

        dist = 20 * diff  # original distance between two lines in pixels
        temp = dist
        canvas = self.canvas
        while temp < w:
            r = QGraphicsLineItem(temp + x, y, temp + x, y + h, None)
            canvas.addItem(r)
            r.setPen(pen)
            temp += dist

        temp = dist
        while temp < h:
            r = QGraphicsLineItem(x, y + temp, x + w, y + temp, None)
            canvas.addItem(r)
            r.setPen(pen)
            temp += dist
Ejemplo n.º 22
0
    def moveTo(self, pos):
        oldX, oldY = self.pos.x(), self.pos.y()
        x,y = pos.x(), pos.y()
        
        #print "BrushingModel.moveTo(pos=%r)" % (pos) 
        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(QPen( QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.scene.addItem(line)

        #update bounding Box 
        if not self.bb.isValid():
            self.bb = QRect(QPoint(x,y), QSize(1,1))
        #grow bounding box
        self.bb.setLeft(  min(self.bb.left(),   max(0,                   x-self.brushSize/2-1) ) )
        self.bb.setRight( max(self.bb.right(),  min(self.sliceRect[0]-1, x+self.brushSize/2+1) ) )
        self.bb.setTop(   min(self.bb.top(),    max(0,                   y-self.brushSize/2-1) ) )
        self.bb.setBottom(max(self.bb.bottom(), min(self.sliceRect[1]-1, y+self.brushSize/2+1) ) )
        
        #update/move position
        self.pos = pos
Ejemplo n.º 23
0
    def moveTo(self, pos):    
        lineVis = QGraphicsLineItem(self.pos.x(), self.pos.y(), pos.x(), pos.y())
        lineVis.setPen(self.penVis)
        
        line = QGraphicsLineItem(self.pos.x(), self.pos.y(), pos.x(), pos.y())
        line.setPen(self.penDraw)
        self.scene.addItem(line)

        self.pos = pos
        x = pos.x()
        y = pos.y()
        #update bounding Box :
        if x > self.bb.right():
            self.bb.setRight(x)
        if x < self.bb.left():
            self.bb.setLeft(x)
        if y > self.bb.bottom():
            self.bb.setBottom(y)
        if y < self.bb.top():
            self.bb.setTop(y)
        return lineVis
Ejemplo n.º 24
0
    def addLink(self, output, input):
        """
        Add a link between `output` (:class:`OutputSignal`) and `input`
        (:class:`InputSignal`).

        """
        if not compatible_channels(output, input):
            return

        if output not in self.source.output_channels():
            raise ValueError("%r is not an output channel of %r" % \
                             (output, self.source))

        if input not in self.sink.input_channels():
            raise ValueError("%r is not an input channel of %r" % \
                             (input, self.sink))

        if input.single:
            # Remove existing link if it exists.
            for s1, s2, _ in self.__links:
                if s2 == input:
                    self.removeLink(s1, s2)

        line = QGraphicsLineItem(self)

        source_anchor = self.sourceNodeWidget.anchor(output)
        sink_anchor = self.sinkNodeWidget.anchor(input)

        source_pos = source_anchor.boundingRect().center()
        source_pos = self.mapFromItem(source_anchor, source_pos)

        sink_pos = sink_anchor.boundingRect().center()
        sink_pos = self.mapFromItem(sink_anchor, sink_pos)
        line.setLine(source_pos.x(), source_pos.y(),
                     sink_pos.x(), sink_pos.y())
        pen = QPen(Qt.black, 4)
        pen.setCapStyle(Qt.RoundCap)
        line.setPen(pen)

        self.__links.append(_Link(output, input, line))
Ejemplo n.º 25
0
    def addLink(self, output, input):
        """
        Add a link between `output` (:class:`OutputSignal`) and `input`
        (:class:`InputSignal`).

        """
        if not compatible_channels(output, input):
            return

        if output not in self.source.output_channels():
            raise ValueError("%r is not an output channel of %r" % \
                             (output, self.source))

        if input not in self.sink.input_channels():
            raise ValueError("%r is not an input channel of %r" % \
                             (input, self.sink))

        if input.single:
            # Remove existing link if it exists.
            for s1, s2, _ in self.__links:
                if s2 == input:
                    self.removeLink(s1, s2)

        line = QGraphicsLineItem(self)

        source_anchor = self.sourceNodeWidget.anchor(output)
        sink_anchor = self.sinkNodeWidget.anchor(input)

        source_pos = source_anchor.boundingRect().center()
        source_pos = self.mapFromItem(source_anchor, source_pos)

        sink_pos = sink_anchor.boundingRect().center()
        sink_pos = self.mapFromItem(sink_anchor, sink_pos)
        line.setLine(source_pos.x(), source_pos.y(), sink_pos.x(),
                     sink_pos.y())
        pen = QPen(Qt.black, 4)
        pen.setCapStyle(Qt.RoundCap)
        line.setPen(pen)

        self.__links.append(_Link(output, input, line))
Ejemplo n.º 26
0
    def draw_legend(self):
        legend_h = self.height * ((self.nb_models - 1) / float(self.nb_models))
        if legend_h < 35:
            legend_h = 35
        legend_rect = QGraphicsRectItem(-20, 0, 10, legend_h, parent=self.item)
        x0 = -20
        n_cat = 6.
        for y, str_y in [(1, 1), (1 / n_cat * 5, 0.99), (1 / n_cat * 4, 0.9),
                         (1 / n_cat * 3, 0.8), (1 / n_cat * 2, 0.7),
                         (1 / n_cat * 1, 0.5), (1 / n_cat * 0, 0)]:
            y_stick = legend_h - y * legend_h
            lineItem = QGraphicsLineItem(x0 - 5,
                                         y_stick,
                                         x0,
                                         y_stick,
                                         parent=self.item)
            lineItem.setPen(QPen(QColor('black')))
            text = QGraphicsSimpleTextItem(str(str_y))
            text.setFont(QFont("Arial", self.fsize - 4))
            text.setParentItem(self.item)
            tw = text.boundingRect().width()
            th = text.boundingRect().height()
            # Center text according to masterItem size
            text.setPos(x0 - tw - 7, y_stick - th / 2)

        for (y1, y2, c) in [(1, 1 / n_cat * 5, 0.99),
                            (1 / n_cat * 5, 1 / n_cat * 4, 0.9),
                            (1 / n_cat * 4, 1 / n_cat * 3, 0.8),
                            (1 / n_cat * 3, 1 / n_cat * 2, 0.7),
                            (1 / n_cat * 2, 1 / n_cat * 1, 0.5),
                            (1 / n_cat * 1, 1 / n_cat * 0, 0)]:
            y1_stick = legend_h - y1 * legend_h
            y2_stick = legend_h - y2 * legend_h
            self.draw_fun(x0,
                          y1_stick,
                          c,
                          col_width=10,
                          col_height=y2_stick - y1_stick)
Ejemplo n.º 27
0
class Visualizer:

    def __init__(self, scene):

        self.scene = scene

        # Pool of items to grab from when needed.
        self.taskItemPool = list()

        # The items that are active and to be updated.
        self.activeItems = list()

        # Dictionary of PIDs and an associated item to represent the process.
        self.taskItemPids = dict()

        # Scales the visualization dimension for cpu%.
        self.cpuScale = 2.0

        # Setup memory axis visualization.
        self.memAxisLen = 1000
        self.memXOffset = -10
        self._memTickInterval = 0.1  # As a percentage of the memScale.
        self.memAxis = None
        self.setup_mem_axis()

        # Set the color codes for each task type.
        self.userTaskColor = Qt.red
        self.rootTaskColor = Qt.darkGray
        self.otherTaskColor = Qt.cyan

        # Spacing between each task graphical item
        self.taskItemSpacing = 20

        self.showRootTasks = False

        # Set up the timers to update the visualization.
        self.updateProcessDataTimer = QTimer()
        self.updateProcessDataTimer.timeout.connect(self.update_processes_data)
        self.updateItemsTimer = QTimer()
        self.updateItemsTimer.timeout.connect(self.update_items)

        # Fill the pool of task items.
        for i in range(0, 200):
            self.add_new_task_graphics_item(False)

        self.updateProcessDataTimer.start(1000.0)
        self.updateItemsTimer.start(50.0)

    def update_processes_data(self):

        # Reset USED flag in order to determine which task items are unused. This
        # will happen when an item's process does not exist anymore.
        for item in self.activeItems:
            item.used = False

        processes = StateManager.get_processes_data()

        # Update the graphical representations
        x = 0
        for p in processes:

            if p[USER_INDEX] == ROOT_NAME and not self.showRootTasks:
                continue

            pid = p[PID_INDEX]

            # Pid still exists.
            if pid in self.taskItemPids:

                item = self.taskItemPids[pid]

                # Check if PID returned after it ended. This means that the mapped
                # item MAY be associated with another process.
                if item.pid != pid:
                    item = self.fetch_task_item()
                    self.taskItemPids[pid] = item
                    item.pid = pid

                # Remove from pool and add to active.
                elif item in self.taskItemPool:
                    self.taskItemPool.remove(item)
                    self.activeItems.append(item)

                # ELSE: reuse item, the process returned continuously.
                item.setVisible(True)
                item.used = True

            # Pid not in dictionary, Add task item.
            else:
                item = self.fetch_task_item()
                self.taskItemPids[pid] = item
                item.pid = pid
                item.used = True

            # CPU %
            new_diameter = p[CPU_INDEX] * self.cpuScale + 2

            # MEM %
            y = p[MEM_INDEX] / 100.0 * self.memAxisLen

            # Center around on y-component.
            y -= new_diameter / 2.0

            pos = item.rect().topLeft()
            diameter = item.rect().width()

            # Set position bounds.
            item.startPos = pos
            item.endPos = QPointF(x, y)

            # Setup diameter bounds.
            item.startDiameter = diameter
            item.endDiameter = new_diameter

            x += new_diameter + self.taskItemSpacing

            # Setup the name of the task.
            item.set_name(p[NAME_INDEX])

            if p[USER_INDEX] == USER_NAME:
                item.setBrush(QBrush(self.userTaskColor))
                item.textItem.setDefaultTextColor(Qt.white)

            elif p[USER_INDEX] == ROOT_NAME:
                item.setBrush(QBrush(self.rootTaskColor))
                item.textItem.setDefaultTextColor(self.rootTaskColor)

            else:
                item.setBrush(QBrush(self.otherTaskColor))
                item.textItem.setDefaultTextColor(Qt.white)

        self.recycle_unused_items()

        # Update the scene so it can repaint properly
        self.scene.update()

    def update_items(self):

        time_step = self.updateItemsTimer.interval() / float(self.updateProcessDataTimer.interval())

        for item in self.activeItems:
            item.update(time_step)

    def fetch_task_item(self):

        # Add more graphic items if there isn't enough in the pool.
        if len(self.taskItemPool) == 0:
            self.add_new_task_graphics_item()

        item = self.taskItemPool.pop()
        item.setVisible(True)
        self.activeItems.append(item)

        return item

    def recycle_task_item(self, item):
        item.setVisible(False)
        self.taskItemPool.append(item)

    # Items without an active process are recycled
    def recycle_unused_items(self):

        # Recycle unused.
        for item in self.activeItems:
            if not item.used:
                self.recycle_task_item(item)

        # Only keep the used items.
        self.activeItems = [item for item in self.activeItems if item.used]

    def add_new_task_graphics_item(self, visible=True):
        item = TaskGraphicsItem(QRectF(0, 0, 1, 1))
        item.setVisible(visible)
        self.taskItemPool.append(item)
        self.scene.addItem(item)

    def setup_mem_axis(self):
        self.memAxis = QGraphicsLineItem(self.memXOffset, 0, self.memXOffset, self.memAxisLen, None, self.scene)
        self.memAxis.setPen(QPen(Qt.white))

        step = int(self._memTickInterval * self.memAxisLen)

        pen = QPen(Qt.CustomDashLine)
        pen.setDashPattern([2, 20])
        pen.setColor(Qt.lightGray)

        for y in range(step, self.memAxisLen + step, step):
            self.scene.addLine(self.memXOffset, y, 2500.0, y, pen)

    def update_mem_axis(self):

        # Set Length of line to the x value of the last active task item.
        pass
Ejemplo n.º 28
0
    def setAxisIntersect(self, intersect):
        self._axisIntersect = intersect
        #print "SkeletonsLayer(axis=%d) is updating intersect=%d" % (self._axis, self._axisIntersect)

        nodes, eIntersected, ePlane = self._3d._skeletons.intersect(
            self._axis, self._axisIntersect)

        #update existing items
        toRemove = []
        for node, item in self._node2view.iteritems():
            if node.pos[self._axis] != self._axisIntersect:
                self._scene.removeItem(item)
                toRemove.append(node)
            elif node.pointF(self._axis) != item.pos():
                item.setPos(self._scene.data2scene.map(node.pointF(
                    self._axis)))
            if node.isSelected() != item.isSelected():
                item.setSelected(node.isSelected())
                assert item.isSelected() == node.isSelected()
            i = 0
            newSize = [0, 0]
            for j in range(3):
                if j == self._axis:
                    continue
                newSize[i] = node.shape[j]
                i += 1
            newRectF = QRectF(0, 0, *newSize)
            newRectF = self._scene.data2scene.mapRect(newRectF)

            item.setRect(
                QRectF(-newRectF.width() / 2.0, -newRectF.height() / 2.0,
                       newRectF.width(), newRectF.height()))

        for r in toRemove:
            del self._node2view[r]

        #add new views for nodes
        for n in nodes:
            if n in self._node2view:
                continue

            pos2D = list(n.pos)
            del pos2D[self._axis]

            shape2D = n.shape2D(self._axis)
            itm = QGraphicsSkeletonNode(shape2D,
                                        skeletons=self._3d._skeletons,
                                        node=n)
            itm.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            itm.setSelected(n.isSelected())

            self._scene.addItem(itm)
            self._node2view[n] = itm

        for itm in self._edge2view.values():
            self._scene.removeItem(itm)
        self._edge2view = dict()

        for e in ePlane:
            l = QLineF(e[0].pointF(), e[1].pointF())

            c1 = e[0].color()
            c2 = e[1].color()
            mixColor = QColor((c1.red() + c2.red()) / 2,
                              (c1.green() + c2.green()) / 2,
                              (c1.blue() + c2.blue()) / 2)

            line = QGraphicsLineItem(self._scene.data2scene.map(l))
            line.setPen(QPen(mixColor))
            self._scene.addItem(line)
            self._edge2view[e] = line

        for theEdge, e in eIntersected:
            c1 = theEdge[0].color()
            c2 = theEdge[1].color()
            mixColor = QColor((c1.red() + c2.red()) / 2,
                              (c1.green() + c2.green()) / 2,
                              (c1.blue() + c2.blue()) / 2)

            nodeSize = 6
            p = QGraphicsRectItem(-nodeSize / 2, -nodeSize / 2, nodeSize,
                                  nodeSize)
            pos2D = list(e)
            del pos2D[self._axis]
            p.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            p.setPen(QPen(mixColor))
            self._scene.addItem(p)
            self._edge2view[e] = p
Ejemplo n.º 29
0
 def setColor(self, color):
     pen = QPen(color)
     QGraphicsLineItem.setPen(self, pen)
Ejemplo n.º 30
0
 def resetColor(self):
     pen = QPen(QColor.fromRgb(0,0,0))
     QGraphicsLineItem.setPen(self, pen)
Ejemplo n.º 31
0
 def _offseted_line(ax, ay):
     r = QGraphicsLineItem(x + ax, y + ay, x + (ax or w),
                           y + (ay or h))
     self.canvas.addItem(r)
     r.setPen(pen)
Ejemplo n.º 32
0
 def _offseted_line(ax, ay):
     r = QGraphicsLineItem(x + ax, y + ay, x + (ax or w),
                           y + (ay or h))
     self.canvas.addItem(r)
     r.setPen(pen)
Ejemplo n.º 33
0
 def line(x1, y1, x2, y2):
     r = QGraphicsLineItem(x1, y1, x2, y2, None)
     self.canvas.addItem(r)
     r.setPen(QPen(Qt.white, 2))
     r.setZValue(30)
Ejemplo n.º 34
0
    def setAxisIntersect(self, intersect):
        self._axisIntersect = intersect
        #print "SkeletonsLayer(axis=%d) is updating intersect=%d" % (self._axis, self._axisIntersect)
        
        nodes, eIntersected, ePlane = self._3d._skeletons.intersect(self._axis, self._axisIntersect)
       
        #update existing items 
        toRemove = []
        for node, item in self._node2view.iteritems():
            if node.pos[self._axis] != self._axisIntersect:
                self._scene.removeItem(item)
                toRemove.append(node)
            elif node.pointF(self._axis) != item.pos():
                item.setPos( self._scene.data2scene.map( node.pointF(self._axis) ) )
            if node.isSelected() != item.isSelected():
                item.setSelected(node.isSelected())
                assert item.isSelected() == node.isSelected()
            i = 0 
            newSize = [0,0]
            for j in range(3):
                if j == self._axis:
                    continue
                newSize[i] = node.shape[j] 
                i += 1
            newRectF = QRectF(0,0,*newSize)
            newRectF = self._scene.data2scene.mapRect(newRectF)
            
            item.setRect(QRectF(-newRectF.width()/2.0, -newRectF.height()/2.0, newRectF.width(), newRectF.height()))
            
        for r in toRemove:
            del self._node2view[r]
               
        #add new views for nodes 
        for n in nodes:
            if n in self._node2view:
                continue
            
            pos2D = list(n.pos)
            del pos2D[self._axis]

            shape2D = n.shape2D(self._axis)
            itm = QGraphicsSkeletonNode(shape2D, skeletons=self._3d._skeletons, node = n)
            itm.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            itm.setSelected(n.isSelected())
            
            self._scene.addItem(itm)
            self._node2view[n] = itm

        for itm in self._edge2view.values():
            self._scene.removeItem(itm) 
        self._edge2view = dict()
        
        for e in ePlane:
            l = QLineF(e[0].pointF(), e[1].pointF())

            c1 = e[0].color()
            c2 = e[1].color()
            mixColor = QColor( (c1.red()+c2.red())/2,
                               (c1.green()+c2.green())/2,
                               (c1.blue()+c2.blue())/2 )

            line = QGraphicsLineItem(self._scene.data2scene.map(l))
            line.setPen(QPen(mixColor))
            self._scene.addItem(line)
            self._edge2view[e] = line
            
        for theEdge, e in eIntersected:
            c1 = theEdge[0].color()
            c2 = theEdge[1].color()
            mixColor = QColor( (c1.red()+c2.red())/2,
                               (c1.green()+c2.green())/2,
                               (c1.blue()+c2.blue())/2 )

            nodeSize = 6
            p = QGraphicsRectItem(-nodeSize/2, -nodeSize/2, nodeSize, nodeSize)
            pos2D = list(e)
            del pos2D[self._axis]
            p.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            p.setPen(QPen(mixColor))
            self._scene.addItem(p)
            self._edge2view[e] = p
Ejemplo n.º 35
0
 def line(x1, y1, x2, y2):
     r = QGraphicsLineItem(x1, y1, x2, y2, None)
     self.canvas.addItem(r)
     r.setPen(QPen(Qt.white, 2))
     r.setZValue(30)
Ejemplo n.º 36
0
 def draw_stick(self, x, y, i):
     lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0]),
                                        0, self.coordY(y),
                                        parent=self.item)
     lineItem.setX(x)
     lineItem.setPen(QPen(QColor(self.colors[i]),2))
Ejemplo n.º 37
0
 def draw_hlines (self, line, col):
     lineItem = QGraphicsLineItem(0, self.coordY(line),
                                        self.width, self.coordY(line),
                                        parent=self.item)
     lineItem.setPen(QPen(QColor(col), 1, Qt.DashLine))
     lineItem.setZValue(10)
Ejemplo n.º 38
0
 def draw_bar(self, x, y, i):
     h = self.coordY(self.ylim[0])  #self.height
     coordY = self.coordY
     item = self.item
     # if value stands out of bound
     if y < self.ylim[0]: return
     if y < self.ylim[1]:
         # left line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x - 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
         # right line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x + 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
         # top line
         lineItem = QGraphicsLineItem(0,
                                      coordY(y),
                                      6,
                                      coordY(y),
                                      parent=item)
         lineItem.setX(x - 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
     else:
         # lower left line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x - 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
         # lower right line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x + 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
         # upper left line
         lineItem = QGraphicsLineItem(0,
                                      coordY(y) - 4,
                                      0,
                                      coordY(y) - 7,
                                      parent=item)
         lineItem.setX(x - 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
         # upper right line
         lineItem = QGraphicsLineItem(0,
                                      coordY(y) - 4,
                                      0,
                                      coordY(y) - 7,
                                      parent=item)
         lineItem.setX(x + 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
         # top line
         lineItem = QGraphicsLineItem(0,
                                      coordY(y) - 7,
                                      6,
                                      coordY(y) - 7,
                                      parent=item)
         lineItem.setX(x - 3)
         lineItem.setPen(QPen(QColor(self.colors[i]), 2))
Ejemplo n.º 39
0
class OWAxis(QGraphicsItem):

    Role = OWPalette.Axis

    def __init__(self, id, title = '', title_above = False, title_location = AxisMiddle, line = None, arrows = 0, plot = None):
        QGraphicsItem.__init__(self)
        self.setFlag(QGraphicsItem.ItemHasNoContents)
        self.setZValue(AxisZValue)
        self.id = id
        self.title = title
        self.title_location = title_location
        self.data_line = line
        self.plot = plot
        self.graph_line = None
        self.size = None
        self.scale = None
        self.tick_length = (10, 5, 0)
        self.arrows = arrows
        self.title_above = title_above
        self.line_item = QGraphicsLineItem(self)
        self.title_item = QGraphicsTextItem(self)
        self.end_arrow_item = None
        self.start_arrow_item = None
        self.show_title = False
        self.scale = None
        path = QPainterPath()
        path.setFillRule(Qt.WindingFill)
        path.moveTo(0, 3.09)
        path.lineTo(0, -3.09)
        path.lineTo(9.51, 0)
        path.closeSubpath()
        self.arrow_path = path
        self.label_items = []
        self.label_bg_items = []
        self.tick_items = []
        self._ticks = []
        self.zoom_transform = QTransform()
        self.labels = None
        self.auto_range = None
        self.auto_scale = True

        self.zoomable = False
        self.update_callback = None
        self.max_text_width = 50
        self.text_margin = 5
        self.always_horizontal_text = False

    @staticmethod
    def compute_scale(min, max):
        magnitude = int(3*log10(abs(max-min)) + 1)
        if magnitude % 3 == 0:
            first_place = 1
        elif magnitude % 3 == 1:
            first_place = 2
        else:
            first_place = 5
        magnitude = magnitude // 3 - 1
        step = first_place * pow(10, magnitude)
        first_val = ceil(min/step) * step
        return first_val, step

    def update_ticks(self):
        self._ticks = []
        major, medium, minor = self.tick_length
        if self.labels is not None and not self.auto_scale:
            for i, text in enumerate(self.labels):
                self._ticks.append( ( i, text, medium, 1 ) )
        else:
            if self.scale and not self.auto_scale:
                min, max, step = self.scale
            elif self.auto_range:
                min, max = self.auto_range
                if min is not None and max is not None:
                    step = (max - min)/10
                else:
                    return
            else:
                return

            if max == min:
                return

            val, step = self.compute_scale(min, max)
            while val <= max:
                self._ticks.append( ( val, "%.4g" % val, medium, step ) )
                val += step

    def update_graph(self):
        if self.update_callback:
            self.update_callback()


    def update(self, zoom_only = False):
        self.update_ticks()
        line_color = self.plot.color(OWPalette.Axis)
        text_color = self.plot.color(OWPalette.Text)
        if not self.graph_line or not self.scene():
            return
        self.line_item.setLine(self.graph_line)
        self.line_item.setPen(line_color)
        if self.title:
            self.title_item.setHtml('<b>' + self.title + '</b>')
            self.title_item.setDefaultTextColor(text_color)
        if self.title_location == AxisMiddle:
            title_p = 0.5
        elif self.title_location == AxisEnd:
            title_p = 0.95
        else:
            title_p = 0.05
        title_pos = self.graph_line.pointAt(title_p)
        v = self.graph_line.normalVector().unitVector()

        dense_text = False
        if hasattr(self, 'title_margin'):
            offset = self.title_margin
        elif self._ticks:
            if self.should_be_expanded():
                offset = 55
                dense_text = True
            else:
                offset = 35
        else:
            offset = 10

        if self.title_above:
            title_pos = title_pos + (v.p2() - v.p1())*(offset + QFontMetrics(self.title_item.font()).height())
        else:
            title_pos = title_pos - (v.p2() - v.p1())*offset
        ## TODO: Move it according to self.label_pos
        self.title_item.setVisible(self.show_title)
        self.title_item.setRotation(-self.graph_line.angle())
        c = self.title_item.mapToParent(self.title_item.boundingRect().center())
        tl = self.title_item.mapToParent(self.title_item.boundingRect().topLeft())
        self.title_item.setPos(title_pos - c + tl)

        ## Arrows
        if not zoom_only:
            if self.start_arrow_item:
                self.scene().removeItem(self.start_arrow_item)
                self.start_arrow_item = None
            if self.end_arrow_item:
                self.scene().removeItem(self.end_arrow_item)
                self.end_arrow_item = None

        if self.arrows & AxisStart:
            if not zoom_only or not self.start_arrow_item:
                self.start_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.start_arrow_item.setPos(self.graph_line.p1())
            self.start_arrow_item.setRotation(-self.graph_line.angle() + 180)
            self.start_arrow_item.setBrush(line_color)
            self.start_arrow_item.setPen(line_color)
        if self.arrows & AxisEnd:
            if not zoom_only or not self.end_arrow_item:
                self.end_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.end_arrow_item.setPos(self.graph_line.p2())
            self.end_arrow_item.setRotation(-self.graph_line.angle())
            self.end_arrow_item.setBrush(line_color)
            self.end_arrow_item.setPen(line_color)

        ## Labels

        n = len(self._ticks)
        resize_plot_item_list(self.label_items, n, QGraphicsTextItem, self)
        resize_plot_item_list(self.label_bg_items, n, QGraphicsRectItem, self)
        resize_plot_item_list(self.tick_items, n, QGraphicsLineItem, self)

        test_rect = QRectF(self.graph_line.p1(),  self.graph_line.p2()).normalized()
        test_rect.adjust(-1, -1, 1, 1)

        n_v = self.graph_line.normalVector().unitVector()
        if self.title_above:
            n_p = n_v.p2() - n_v.p1()
        else:
            n_p = n_v.p1() - n_v.p2()
        l_v = self.graph_line.unitVector()
        l_p = l_v.p2() - l_v.p1()
        for i in range(n):
            pos, text, size, step = self._ticks[i]
            hs = 0.5 * step
            tick_pos = self.map_to_graph( pos )
            if not test_rect.contains(tick_pos):
                self.tick_items[i].setVisible(False)
                self.label_items[i].setVisible(False)
                continue
            item = self.label_items[i]
            item.setVisible(True)
            if not zoom_only:
                if self.id in XAxes or getattr(self, 'is_horizontal', False):
                    item.setHtml( '<center>' + Qt.escape(text.strip()) + '</center>')
                else:
                    item.setHtml(Qt.escape(text.strip()))

            item.setTextWidth(-1)
            text_angle = 0
            if dense_text:
                w = min(item.boundingRect().width(), self.max_text_width)
                item.setTextWidth(w)
                if self.title_above:
                    label_pos = tick_pos + n_p * (w + self.text_margin) + l_p * item.boundingRect().height()/2
                else:
                    label_pos = tick_pos + n_p * self.text_margin + l_p * item.boundingRect().height()/2
                text_angle = -90 if self.title_above else 90
            else:
                w = min(item.boundingRect().width(), QLineF(self.map_to_graph(pos - hs), self.map_to_graph(pos + hs) ).length())
                label_pos = tick_pos + n_p * self.text_margin - l_p * w/2
                item.setTextWidth(w)

            if not self.always_horizontal_text:
                if self.title_above:
                    item.setRotation(-self.graph_line.angle() - text_angle)
                else:
                    item.setRotation(self.graph_line.angle() - text_angle)

            item.setPos(label_pos)
            item.setDefaultTextColor(text_color)

            self.label_bg_items[i].setRect(item.boundingRect())
            self.label_bg_items[i].setPen(QPen(Qt.NoPen))
            self.label_bg_items[i].setBrush(self.plot.color(OWPalette.Canvas))

            item = self.tick_items[i]
            item.setVisible(True)
            tick_line = QLineF(v)
            tick_line.translate(-tick_line.p1())
            tick_line.setLength(size)
            if self.title_above:
                tick_line.setAngle(tick_line.angle() + 180)
            item.setLine( tick_line )
            item.setPen(line_color)
            item.setPos(self.map_to_graph(pos))

    @staticmethod
    def make_title(label, unit = None):
        lab = '<i>' + label + '</i>'
        if unit:
            lab = lab + ' [' + unit + ']'
        return lab

    def set_line(self, line):
        self.graph_line = line
        self.update()

    def set_title(self, title):
        self.title = title
        self.update()

    def set_show_title(self, b):
        self.show_title = b
        self.update()

    def set_labels(self, labels):
        self.labels = labels
        self.graph_line = None
        self.auto_scale = False
        self.update_ticks()
        self.update_graph()

    def set_scale(self, min, max, step_size):
        self.scale = (min, max, step_size)
        self.graph_line = None
        self.auto_scale = False
        self.update_ticks()
        self.update_graph()

    def set_tick_length(self, minor, medium, major):
        self.tick_length = (minor, medium, major)
        self.update()

    def map_to_graph(self, x):
        min, max = self.plot.bounds_for_axis(self.id)
        if min == max:
            return QPointF()
        line_point = self.graph_line.pointAt( (x-min)/(max-min) )
        end_point = line_point * self.zoom_transform
        return self.projection(end_point, self.graph_line)

    @staticmethod
    def projection(point, line):
        norm = line.normalVector()
        norm.translate(point - norm.p1())
        p = QPointF()
        type = line.intersect(norm, p)
        return p

    def continuous_labels(self):
        min, max, step = self.scale
        magnitude = log10(abs(max-min))

    def paint(self, painter, option, widget):
        pass

    def boundingRect(self):
        return QRectF()

    def ticks(self):
        if not self._ticks:
            self.update_ticks()
        return self._ticks

    def bounds(self):
        if self.labels:
            return -0.2, len(self.labels) -0.8
        elif self.scale:
            min, max, _step = self.scale
            return min, max
        elif self.auto_range:
            return self.auto_range
        else:
            return 0, 1

    def should_be_expanded(self):
        self.update_ticks()
        return self.id in YAxes or self.always_horizontal_text or sum(len(t[1]) for t in self._ticks) * 12 > self.plot.width()
Ejemplo n.º 40
0
 def line(scene, x1, y1, x2, y2, color="blue", width=5):
    item = QGraphicsLineItem(x1, y1, x2, y2)
    pen = QPen(QColor(color))
    pen.setWidth(width)
    item.setPen(pen)
    scene.addItem(item)
Ejemplo n.º 41
0
class OWAxis(QGraphicsItem):

    Role = OWPalette.Axis

    def __init__(self,
                 id,
                 title='',
                 title_above=False,
                 title_location=AxisMiddle,
                 line=None,
                 arrows=AxisEnd,
                 plot=None):
        QGraphicsItem.__init__(self)
        self.setFlag(QGraphicsItem.ItemHasNoContents)
        self.setZValue(AxisZValue)
        self.id = id
        self.title = title
        self.title_location = title_location
        self.data_line = line
        self.plot = plot
        self.graph_line = None
        self.size = None
        self.scale = None
        self.tick_length = (10, 5, 0)
        self.arrows = arrows
        self.title_above = title_above
        self.line_item = QGraphicsLineItem(self)
        self.title_item = QGraphicsTextItem(self)
        self.end_arrow_item = None
        self.start_arrow_item = None
        self.show_title = False
        self.scale = None
        path = QPainterPath()
        path.setFillRule(Qt.WindingFill)
        path.moveTo(0, 3.09)
        path.lineTo(0, -3.09)
        path.lineTo(9.51, 0)
        path.closeSubpath()
        self.arrow_path = path
        self.label_items = []
        self.label_bg_items = []
        self.tick_items = []
        self._ticks = []
        self.zoom_transform = QTransform()
        self.labels = None
        self.auto_range = None
        self.auto_scale = True

        self.zoomable = False
        self.update_callback = None
        self.max_text_width = 50
        self.text_margin = 5
        self.always_horizontal_text = False

    def update_ticks(self):
        self._ticks = []
        major, medium, minor = self.tick_length
        if self.labels is not None and not self.auto_scale:
            for i, text in enumerate(self.labels):
                self._ticks.append((i, text, medium, 1))
        else:
            if self.scale and not self.auto_scale:
                min, max, step = self.scale
            elif self.auto_range:
                min, max = self.auto_range
                if min is not None and max is not None:
                    step = (max - min) / 10
                else:
                    return
            else:
                return

            if max == min:
                return

            magnitude = int(3 * log10(abs(max - min)) + 1)
            if magnitude % 3 == 0:
                first_place = 1
            elif magnitude % 3 == 1:
                first_place = 2
            else:
                first_place = 5
            magnitude = magnitude / 3 - 1
            step = first_place * pow(10, magnitude)
            val = ceil(min / step) * step
            while val <= max:
                self._ticks.append((val, "%.4g" % val, medium, step))
                val = val + step

    def update_graph(self):
        if self.update_callback:
            self.update_callback()

    def update(self, zoom_only=False):
        self.update_ticks()
        line_color = self.plot.color(OWPalette.Axis)
        text_color = self.plot.color(OWPalette.Text)
        if not self.graph_line or not self.scene():
            return
        self.line_item.setLine(self.graph_line)
        self.line_item.setPen(line_color)
        if self.title:
            self.title_item.setHtml('<b>' + self.title + '</b>')
            self.title_item.setDefaultTextColor(text_color)
        if self.title_location == AxisMiddle:
            title_p = 0.5
        elif self.title_location == AxisEnd:
            title_p = 0.95
        else:
            title_p = 0.05
        title_pos = self.graph_line.pointAt(title_p)
        v = self.graph_line.normalVector().unitVector()

        dense_text = False
        if hasattr(self, 'title_margin'):
            offset = self.title_margin
        elif self._ticks:
            if self.should_be_expanded():
                offset = 55
                dense_text = True
            else:
                offset = 35
        else:
            offset = 10

        if self.title_above:
            title_pos = title_pos + (v.p2() - v.p1()) * (
                offset + QFontMetrics(self.title_item.font()).height())
        else:
            title_pos = title_pos - (v.p2() - v.p1()) * offset
        ## TODO: Move it according to self.label_pos
        self.title_item.setVisible(self.show_title)
        self.title_item.setRotation(-self.graph_line.angle())
        c = self.title_item.mapToParent(
            self.title_item.boundingRect().center())
        tl = self.title_item.mapToParent(
            self.title_item.boundingRect().topLeft())
        self.title_item.setPos(title_pos - c + tl)

        ## Arrows
        if not zoom_only:
            if self.start_arrow_item:
                self.scene().removeItem(self.start_arrow_item)
                self.start_arrow_item = None
            if self.end_arrow_item:
                self.scene().removeItem(self.end_arrow_item)
                self.end_arrow_item = None

        if self.arrows & AxisStart:
            if not zoom_only or not self.start_arrow_item:
                self.start_arrow_item = QGraphicsPathItem(
                    self.arrow_path, self)
            self.start_arrow_item.setPos(self.graph_line.p1())
            self.start_arrow_item.setRotation(-self.graph_line.angle() + 180)
            self.start_arrow_item.setBrush(line_color)
            self.start_arrow_item.setPen(line_color)
        if self.arrows & AxisEnd:
            if not zoom_only or not self.end_arrow_item:
                self.end_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.end_arrow_item.setPos(self.graph_line.p2())
            self.end_arrow_item.setRotation(-self.graph_line.angle())
            self.end_arrow_item.setBrush(line_color)
            self.end_arrow_item.setPen(line_color)

        ## Labels

        n = len(self._ticks)
        resize_plot_item_list(self.label_items, n, QGraphicsTextItem, self)
        resize_plot_item_list(self.label_bg_items, n, QGraphicsRectItem, self)
        resize_plot_item_list(self.tick_items, n, QGraphicsLineItem, self)

        test_rect = QRectF(self.graph_line.p1(),
                           self.graph_line.p2()).normalized()
        test_rect.adjust(-1, -1, 1, 1)

        n_v = self.graph_line.normalVector().unitVector()
        if self.title_above:
            n_p = n_v.p2() - n_v.p1()
        else:
            n_p = n_v.p1() - n_v.p2()
        l_v = self.graph_line.unitVector()
        l_p = l_v.p2() - l_v.p1()
        for i in range(n):
            pos, text, size, step = self._ticks[i]
            hs = 0.5 * step
            tick_pos = self.map_to_graph(pos)
            if not test_rect.contains(tick_pos):
                self.tick_items[i].setVisible(False)
                self.label_items[i].setVisible(False)
                continue
            item = self.label_items[i]
            item.setVisible(True)
            if not zoom_only:
                if self.id in XAxes or getattr(self, 'is_horizontal', False):
                    item.setHtml('<center>' + Qt.escape(text.strip()) +
                                 '</center>')
                else:
                    item.setHtml(Qt.escape(text.strip()))

            item.setTextWidth(-1)
            text_angle = 0
            if dense_text:
                w = min(item.boundingRect().width(), self.max_text_width)
                item.setTextWidth(w)
                if self.title_above:
                    label_pos = tick_pos + n_p * (
                        w + self.text_margin
                    ) + l_p * item.boundingRect().height() / 2
                else:
                    label_pos = tick_pos + n_p * self.text_margin + l_p * item.boundingRect(
                    ).height() / 2
                text_angle = -90 if self.title_above else 90
            else:
                w = min(
                    item.boundingRect().width(),
                    QLineF(self.map_to_graph(pos - hs),
                           self.map_to_graph(pos + hs)).length())
                label_pos = tick_pos + n_p * self.text_margin - l_p * w / 2
                item.setTextWidth(w)

            if not self.always_horizontal_text:
                if self.title_above:
                    item.setRotation(-self.graph_line.angle() - text_angle)
                else:
                    item.setRotation(self.graph_line.angle() - text_angle)

            item.setPos(label_pos)
            item.setDefaultTextColor(text_color)

            self.label_bg_items[i].setRect(item.boundingRect())
            self.label_bg_items[i].setPen(QPen(Qt.NoPen))
            self.label_bg_items[i].setBrush(self.plot.color(OWPalette.Canvas))

            item = self.tick_items[i]
            item.setVisible(True)
            tick_line = QLineF(v)
            tick_line.translate(-tick_line.p1())
            tick_line.setLength(size)
            if self.title_above:
                tick_line.setAngle(tick_line.angle() + 180)
            item.setLine(tick_line)
            item.setPen(line_color)
            item.setPos(self.map_to_graph(pos))

    @staticmethod
    def make_title(label, unit=None):
        lab = '<i>' + label + '</i>'
        if unit:
            lab = lab + ' [' + unit + ']'
        return lab

    def set_line(self, line):
        self.graph_line = line
        self.update()

    def set_title(self, title):
        self.title = title
        self.update()

    def set_show_title(self, b):
        self.show_title = b
        self.update()

    def set_labels(self, labels):
        self.labels = labels
        self.graph_line = None
        self.auto_scale = False
        self.update_ticks()
        self.update_graph()

    def set_scale(self, min, max, step_size):
        self.scale = (min, max, step_size)
        self.graph_line = None
        self.auto_scale = False
        self.update_ticks()
        self.update_graph()

    def set_tick_length(self, minor, medium, major):
        self.tick_length = (minor, medium, major)
        self.update()

    def map_to_graph(self, x):
        min, max = self.plot.bounds_for_axis(self.id)
        if min == max:
            return QPointF()
        line_point = self.graph_line.pointAt((x - min) / (max - min))
        end_point = line_point * self.zoom_transform
        return self.projection(end_point, self.graph_line)

    @staticmethod
    def projection(point, line):
        norm = line.normalVector()
        norm.translate(point - norm.p1())
        p = QPointF()
        type = line.intersect(norm, p)
        return p

    def continuous_labels(self):
        min, max, step = self.scale
        magnitude = log10(abs(max - min))

    def paint(self, painter, option, widget):
        pass

    def boundingRect(self):
        return QRectF()

    def ticks(self):
        if not self._ticks:
            self.update_ticks()
        return self._ticks

    def bounds(self):
        if self.labels:
            return -0.2, len(self.labels) - 0.8
        elif self.scale:
            min, max, _step = self.scale
            return min, max
        elif self.auto_range:
            return self.auto_range
        else:
            return 0, 1

    def should_be_expanded(self):
        self.update_ticks()
        return self.id in YAxes or self.always_horizontal_text or sum(
            len(t[1]) for t in self._ticks) * 12 > self.plot.width()
Ejemplo n.º 42
0
    def drawHistogram(self):
        if self.result is None:
            return
        # Label the histogram
        #self.minValueLabel.setText(str(self.minValue))
        #self.maxValueLabel.setText(str(self.maxValue))
        minvaltext = QGraphicsTextItem(str(self.minValue))
        minvaltextheight = minvaltext.boundingRect().height()
        maxvaltext = QGraphicsTextItem(str(self.maxValue))
        maxvaltextwidth = maxvaltext.boundingRect().width()

        #self.showInfo(str(self.result))
        # Check which element should be used for the histogram
        element = 1
        maxvalue = 0.0
        for i in range(len(self.result)):
            if self.result[i][element] > maxvalue:
                maxvalue = self.result[i][element]
                # Find the maximum value for scaling
        cutoffvalue = maxvalue
        if (self.frequencyRangeSpinBox.value() > 0):
            cutoffvalue = self.frequencyRangeSpinBox.value()
        #self.maxNumberLabel.setText(str(maxvalue))
        #self.maxNumberLabel.setText(str(cutoffvalue))
        self.scene.clear()
        if maxvalue == 0:
            return
        viewprect = QRectF(self.histogramGraphicsView.viewport().rect())
        self.histogramGraphicsView.setSceneRect(viewprect)
        bottom = self.histogramGraphicsView.sceneRect().bottom()
        top = self.histogramGraphicsView.sceneRect().top()
        left = self.histogramGraphicsView.sceneRect().left()
        right = self.histogramGraphicsView.sceneRect().right()
        height = bottom - top - 1
        width = right - left - 1
        padding = 3
        toppadding = 3
        bottompadding = minvaltextheight
        # Determine the width of the left margin (depends on the y range)
        clog = log(cutoffvalue,10)
        clogint = int(clog)
        #clogrem = clog % clogint
        yincr = pow(10,clogint)
        dummytext = QGraphicsTextItem(str(yincr))
        # The left padding must accomodate the y labels
        leftpadding = dummytext.boundingRect().width()
        #leftpadding = 30
        # Find the width of the maximium frequency label
        maxfreqtext = QGraphicsTextItem(str(cutoffvalue))
        maxfreqtextwidth = maxvaltext.boundingRect().width()
        rightpadding = maxfreqtextwidth
        width = width - (leftpadding + rightpadding)
        height = height - (toppadding + bottompadding)
        barwidth = width / self.bins
        #center = QPoint(left + width / 2.0, top + height / 2.0)
        #start = QPointF(self.histogramGraphicsView.mapToScene(center))

        # Create the histogram
        for i in range(self.bins):
            #barheight = height * self.result[i][element] / maxvalue
            barheight = height * self.result[i][element] / cutoffvalue
            barrect = QGraphicsRectItem(QRectF(leftpadding + barwidth * i,
                        height-barheight+toppadding, barwidth, barheight))
            barbrush = QBrush(QColor(255,153,102))
            barrect.setBrush(barbrush)
            self.scene.addItem(barrect)
        
        # Determine the increments for the horizontal lines
        if (cutoffvalue // yincr <= 5 and yincr > 1 ):
            yincr = yincr / 2
            if (cutoffvalue // yincr < 5 and yincr > 10 ):
                yincr = yincr / 2
        # Draw horizontal lines with labels
        yval = 0
        while (yval <= cutoffvalue):
            scval = height + toppadding - yval * height / cutoffvalue
            hline = QGraphicsLineItem(QLineF(leftpadding-2, scval,width+(leftpadding),scval))
            hlinepen = QPen(QColor(153,153,153))
            hline.setPen(hlinepen)
            self.scene.addItem(hline)
            ylabtext = QGraphicsTextItem(str(int(yval)))
            ylabtextheight = ylabtext.boundingRect().height()
            ylabtextwidth = ylabtext.boundingRect().width()
            ylabtext.setPos(leftpadding - ylabtextwidth, scval - ylabtextheight/2)
            if (scval - ylabtextheight/2 > 0):
                self.scene.addItem(ylabtext)
            yval = yval + yincr

            
        #yincr = (cutoffvalue / 10)
        minvaltextwidth = minvaltext.boundingRect().width()
        minvaltext.setPos(leftpadding - minvaltextwidth/2, height + toppadding + bottompadding - minvaltextheight)
        self.scene.addItem(minvaltext)
        maxvaltext.setPos(leftpadding + width - maxvaltextwidth/2, height + toppadding + bottompadding - minvaltextheight)
        self.scene.addItem(maxvaltext)
        maxfreqtext.setPos(leftpadding + width, 0)
        self.scene.addItem(maxfreqtext)
Ejemplo n.º 43
0
class AxisItem(pg.GraphicsObject):
    def __init__(self, parent=None, line=None, label=None, **kwargs):
        super().__init__(parent, **kwargs)
        self.setFlag(pg.GraphicsObject.ItemHasNoContents)

        if line is None:
            line = QLineF(0, 0, 1, 0)

        self._spine = QGraphicsLineItem(line, self)
        angle = QLineF(0, 0, 1, 0).angleTo(line)
        angle = (180 - angle) % 360
        dx = line.x2() - line.x1()
        dy = line.y2() - line.y1()
        rad = numpy.arctan2(dy, dx)
        angle = (rad * 180 / numpy.pi) % 360

        self._arrow = pg.ArrowItem(parent=self, angle=180 - angle)
        self._arrow.setPos(self._spine.line().p2())

        self._label = pg.TextItem(text=label, color=(10, 10, 10))
        self._label.setParentItem(self)
        self._label.setPos(self._spine.line().p2())

    def setLabel(self, label):
        if label != self._label:
            self._label = label
            self._label.setText(label)

    def setPen(self, pen):
        self._spine.setPen(pen)

    def paint(self, painter, option, widget):
        pass

    def boundingRect(self):
        return QRectF()

    def viewTransformChanged(self):
        self.__updateLabelPos()

    def __updateLabelPos(self):
        T = self.viewTransform()
        if T is not None:
            Tinv, ok = T.inverted()
        else:
            Tinv, ok = None, False
        if not ok:
            T = Tinv = QtGui.QTransform()

        # map the axis spine to viewbox coord. system
        viewbox_line = Tinv.map(self._spine.line())
        angle = viewbox_line.angle()
        # note in Qt the y axis is inverted (90 degree angle 'points' down)
        left_quad = 270 <= angle <= 360 or -0.0 <= angle < 90

        # position the text label along the viewbox_line
        label_pos = viewbox_line.pointAt(0.90)

        if left_quad:
            anchor = (0.5, -0.1)
        else:
            anchor = (0.5, 1.1)

        pos = T.map(label_pos)
        self._label.setPos(pos)
        self._label.anchor = pg.Point(*anchor)
        self._label.updateText()
        self._label.setRotation(angle if left_quad else angle - 180)
Ejemplo n.º 44
0
class AxisItem(pg.GraphicsObject):
    def __init__(self, parent=None, line=None, label=None, **kwargs):
        super().__init__(parent, **kwargs)
        self.setFlag(pg.GraphicsObject.ItemHasNoContents)

        if line is None:
            line = QLineF(0, 0, 1, 0)

        self._spine = QGraphicsLineItem(line, self)
        angle = QLineF(0, 0, 1, 0).angleTo(line)
        angle = (180 - angle) % 360
        dx = line.x2() - line.x1()
        dy = line.y2() - line.y1()
        rad = numpy.arctan2(dy, dx)
        angle = (rad * 180 / numpy.pi) % 360

        self._arrow = pg.ArrowItem(parent=self, angle=180 - angle)
        self._arrow.setPos(self._spine.line().p2())

        self._label = pg.TextItem(text=label, color=(10, 10, 10))
        self._label.setParentItem(self)
        self._label.setPos(self._spine.line().p2())

    def setLabel(self, label):
        if label != self._label:
            self._label = label
            self._label.setText(label)

    def setPen(self, pen):
        self._spine.setPen(pen)

    def paint(self, painter, option, widget):
        pass

    def boundingRect(self):
        return QRectF()

    def viewTransformChanged(self):
        self.__updateLabelPos()

    def __updateLabelPos(self):
        T = self.viewTransform()
        if T is not None:
            Tinv, ok = T.inverted()
        else:
            Tinv, ok = None, False
        if not ok:
            T = Tinv = QtGui.QTransform()

        # map the axis spine to viewbox coord. system
        viewbox_line = Tinv.map(self._spine.line())
        angle = viewbox_line.angle()
        # note in Qt the y axis is inverted (90 degree angle 'points' down)
        left_quad = 270 <= angle <= 360 or -0.0 <= angle < 90

        # position the text label along the viewbox_line
        label_pos = viewbox_line.pointAt(0.90)

        if left_quad:
            anchor = (0.5, -0.1)
        else:
            anchor = (0.5, 1.1)

        pos = T.map(label_pos)
        self._label.setPos(pos)
        self._label.anchor = pg.Point(*anchor)
        self._label.updateText()
        self._label.setRotation(angle if left_quad else angle - 180)
Ejemplo n.º 45
0
 def draw_bar(self, x, y, i):
     h = self.coordY(self.ylim[0])#self.height
     coordY = self.coordY
     item = self.item
     # if value stands out of bound
     if y < self.ylim[0]: return
     if y < self.ylim[1]:
         # left line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x-3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
         # right line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x+3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
         # top line
         lineItem = QGraphicsLineItem(0, coordY(y), 6, coordY(y), parent=item)
         lineItem.setX(x-3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
     else:
         # lower left line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x-3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
         # lower right line
         lineItem = QGraphicsLineItem(0, h, 0, coordY(y), parent=item)
         lineItem.setX(x+3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
         # upper left line
         lineItem = QGraphicsLineItem(0, coordY(y)-4, 0, coordY(y)-7, parent=item)
         lineItem.setX(x-3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
         # upper right line
         lineItem = QGraphicsLineItem(0, coordY(y)-4, 0, coordY(y)-7, parent=item)
         lineItem.setX(x+3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))
         # top line
         lineItem = QGraphicsLineItem(0, coordY(y)-7, 6, coordY(y)-7, parent=item)
         lineItem.setX(x-3)
         lineItem.setPen(QPen(QColor(self.colors[i]),2))