source: orange/orange/OrangeWidgets/Unsupervised/OWNxCanvas.py @ 8839:166368cc7252

Revision 8839:166368cc7252, 52.4 KB checked in by miha <miha.stajdohar@…>, 3 years ago (diff)
Line 
1CIRCLE = 0
2SQUARE = 1
3ROUND_RECT = 2
4
5NOTHING = 0
6ZOOMING = 1
7SELECT_RECTANGLE = 2
8SELECT_POLYGON = 3
9MOVE_SELECTION = 100
10
11import Orange
12
13from numpy import *
14from OWGraph import *
15from orngScaleScatterPlotData import *
16
17class NodeItem():
18    def __init__(self, index=-1):
19        self.index = index
20        self.marked = False
21        self.show = True
22        self.highlight = False
23        self.selected = False
24        self.label = []
25        self.tooltip = []
26        self.uuid = None
27       
28        self.image = None
29        self.pen = QPen(Qt.blue, 1)
30        self.pen.setJoinStyle(Qt.RoundJoin)
31        self.nocolor = Qt.white
32        self.color = Qt.blue
33        self.size = 5
34        self.style = 1
35   
36class EdgeItem():
37    def __init__(self, u=None, v=None, weight=0, arrowu=0, arrowv=0, 
38                 links_index=None, label=[]):
39        self.u = u
40        self.v = v
41        self.links_index = links_index
42        self.arrowu = arrowu
43        self.arrowv = arrowv
44        self.weight = weight
45        self.label = label
46
47        self.pen = QPen(Qt.lightGray, 1)
48        self.pen.setCapStyle(Qt.RoundCap)
49
50class NetworkCurve(QwtPlotCurve):
51  def __init__(self, parent, pen=QPen(Qt.black), xData=None, yData=None):
52      QwtPlotCurve.__init__(self, "Network Curve")
53
54      self.coors = {}
55      self.vertices = {}
56      self.edges = []
57      self.setItemAttribute(QwtPlotItem.Legend, 0)
58      self.showEdgeLabels = 0
59
60  def move_selected_nodes(self, dx, dy):
61    selected = self.get_selected_nodes()
62   
63    self.coors[0][selected] = self.coors[0][selected] + dx
64    self.coors[1][selected] = self.coors[1][selected] + dy
65     
66    self.setData(self.coors[0], self.coors[1])
67    return selected
68 
69  def set_node_color(self, v, color):
70      pen = self.vertices[v].pen
71      self.vertices[v].color = color
72      self.vertices[v].pen = QPen(color, pen.width())
73
74  def set_nodes_color(self, vertices, color):
75      for v in vertices:
76          v.color = color
77          v.pen = QPen(color, v.pen.width())
78     
79  def set_edge_color(self, index, color, nocolor=0):
80      pen = self.edges[index].pen
81      if nocolor:
82        color.setAlpha(0)
83      self.edges[index].pen = QPen(color, pen.width())
84      self.edges[index].pen.setCapStyle(Qt.RoundCap)
85 
86  def get_selected_nodes(self):
87    return [vertex.index for vertex in self.vertices.itervalues() if vertex.selected]
88
89  def get_unselected_nodes(self):
90    return [vertex.index for vertex in self.vertices.itervalues() if not vertex.selected]
91
92  def get_marked_nodes(self):
93    return [vertex.index for vertex in self.vertices.itervalues() if vertex.marked]
94 
95  def set_marked_nodes(self, vertices):
96    for vertex in self.vertices.itervalues():
97      if vertex.index in vertices:
98        vertex.marked = True
99      else:
100        vertex.marked = False
101       
102  def mark_to_sel(self):
103    for vertex in self.vertices.itervalues():
104      if vertex.marked == True:
105          vertex.selected = True
106         
107  def sel_to_mark(self):
108    for vertex in self.vertices.itervalues():
109      if vertex.selected == True:
110          vertex.selected = False
111          vertex.marked = True
112 
113  def unmark(self):
114    for vertex in self.vertices.itervalues():
115      vertex.marked = False
116     
117  def unselect(self):
118    for vertex in self.vertices.itervalues():
119        vertex.selected = False
120       
121  def set_hidden_nodes(self, nodes):
122    for vertex in self.vertices.itervalues():
123      if vertex.index in nodes:
124        vertex.show = False
125      else:
126        vertex.show = True
127     
128  def hide_selected_nodes(self):
129    for vertex in self.vertices.itervalues():
130      if vertex.selected:
131        vertex.show = False
132 
133  def hide_unselected_nodes(self):
134    for vertex in self.vertices.itervalues():
135      if not vertex.selected:
136        vertex.show = False
137   
138  def show_all_vertices(self):
139    for vertex in self.vertices.itervalues():
140      vertex.show = True
141   
142  def changed(self):
143      self.itemChanged()
144
145  def draw(self, painter, xMap, yMap, rect):
146    for edge in self.edges:
147      if edge.u.show and edge.v.show:
148        painter.setPen(edge.pen)
149
150        px1 = xMap.transform(self.coors[edge.u.index][0])   #ali pa tudi self.x1, itd
151        py1 = yMap.transform(self.coors[edge.u.index][1])
152        px2 = xMap.transform(self.coors[edge.v.index][0])
153        py2 = yMap.transform(self.coors[edge.v.index][1])
154       
155        painter.drawLine(px1, py1, px2, py2)
156       
157        d = 12
158        #painter.setPen(QPen(Qt.lightGray, 1))
159        painter.setBrush(Qt.lightGray)
160        if edge.arrowu:
161            x = px2 - px1
162            y = py2 - py1
163           
164            fi = math.atan2(y, x) * 180 * 16 / math.pi
165
166            if not fi is None:
167                # (180*16) - fi - (20*16), (40*16)
168                rect = QRectF(px2 - d, py2 - d, 2 * d, 2 * d)
169                painter.drawPie(rect, 2560 - fi, 640)
170               
171        if edge.arrowv:
172            x = px2 - px1
173            y = py2 - py1
174           
175            fi = math.atan2(y, x) * 180 * 16 / math.pi
176            if not fi is None:
177                # (180*16) - fi - (20*16), (40*16)
178                rect = QRectF(px2 - d, py2 - d, 2 * d, 2 * d)
179                painter.drawPie(rect, 2560 - fi, 640)
180               
181        if self.showEdgeLabels and len(edge.label) > 0:
182            lbl = ', '.join(edge.label)
183            x = (px1 + px2) / 2
184            y = (py1 + py2) / 2
185           
186            th = painter.fontMetrics().height()
187            tw = painter.fontMetrics().width(lbl)
188            r = QRect(x - tw / 2, y - th / 2, tw, th)
189            painter.fillRect(r, QBrush(Qt.white))
190            painter.drawText(r, Qt.AlignHCenter + Qt.AlignVCenter, lbl)
191   
192    for key, vertex in self.vertices.iteritems():
193      if vertex.show:
194        pX = xMap.transform(self.coors[vertex.index][0])   #dobimo koordinati v pikslih (tipa integer)
195        pY = yMap.transform(self.coors[vertex.index][1])   #ki se stejeta od zgornjega levega kota canvasa
196        if vertex.selected:   
197          painter.setPen(QPen(Qt.yellow, 3))
198          painter.setBrush(vertex.color)
199          rect = QRectF(pX - (vertex.size + 4) / 2, pY - (vertex.size + 4) / 2, vertex.size + 4, vertex.size + 4)
200          painter.drawEllipse(rect)
201        elif vertex.marked:
202          painter.setPen(vertex.pen)
203          painter.setBrush(vertex.color)
204          rect = QRectF(pX - vertex.size / 2, pY - vertex.size / 2, vertex.size, vertex.size)
205          painter.drawEllipse(rect)
206        else:
207          painter.setPen(vertex.pen)
208          painter.setBrush(vertex.nocolor)
209          rect = QRectF(pX - vertex.size / 2, pY - vertex.size / 2, vertex.size, vertex.size)
210          painter.drawEllipse(rect)
211       
212  def closest_node(self, px, py):
213    ndx = min(self.coors, key=lambda x: abs(self.coors[x][0]-px) + abs(self.coors[x][1]-py))
214    return ndx, math.sqrt((self.coors[ndx][0]-px)**2 + (self.coors[ndx][0]-px)**2)
215
216  def get_nodes_in_rect(self, x1, y1, x2, y2):
217      if x1 > x2:
218          x1, x2 = x2, x1
219      if y1 > y2:
220          y1, y2 = y2, y1
221      return [key for key in self.coors if x1 < self.coors[key][0] < x2 and y1 < self.coors[key][1] < y2]
222       
223class OWNxCanvas(OWGraph):
224    def __init__(self, master, parent=None, name="None"):
225        OWGraph.__init__(self, parent, name)
226        self.master = master
227        self.parent = parent
228        self.labelText = []
229        self.tooltipText = []
230        #self.vertices_old = {}         # distionary of nodes (orngIndex: vertex_objekt)
231        #self.edges_old = {}            # distionary of edges (curveKey: edge_objekt)
232        #self.vertices = []
233        #self.edges = []
234        self.indexPairs = {}       # distionary of type CurveKey: orngIndex   (for nodes)
235        #self.selection = []        # list of selected nodes (indices)
236        self.markerKeys = {}       # dictionary of type NodeNdx : markerCurveKey
237        self.tooltipKeys = {}      # dictionary of type NodeNdx : tooltipCurveKey
238        self.graph = None
239        self.layout = None
240        self.vertexDegree = []     # seznam vozlisc oblike (vozlisce, stevilo povezav), sortiran po stevilu povezav
241        self.edgesKey = -1
242        #self.vertexSize = 6
243        self.enableXaxis(0)
244        self.enableYLaxis(0)
245        self.state = NOTHING  #default je rocno premikanje
246        self.hiddenNodes = []
247        self.markedNodes = set()
248        self.markWithRed = False
249        self.circles = []
250        self.tooltipNeighbours = 2
251        self.selectionNeighbours = 2
252        self.freezeNeighbours = False
253        self.labelsOnMarkedOnly = 0
254        self.enableWheelZoom = 1
255        self.optimizing = 0
256        self.stopOptimizing = 0
257        self.insideview = 0
258        self.insideviewNeighbours = 2
259        self.enableGridXB(False)
260        self.enableGridYL(False)
261        self.renderAntialiased = 1
262        self.sendMarkedNodes = None
263        self.showEdgeLabels = 0
264        self.showDistances = 0
265        self.showMissingValues = 0
266       
267        self.showWeights = 0
268        self.showIndexes = 0
269        self.minEdgeWeight = sys.maxint
270        self.maxEdgeWeight = 0
271        self.maxEdgeSize = 1
272       
273        self.maxVertexSize = 5
274        self.minVertexSize = 5
275        self.invertEdgeSize = 0
276        self.showComponentAttribute = None
277        self.forceVectors = None
278        self.appendToSelection = 1
279        self.fontSize = 12
280             
281        self.setAxisAutoScale(self.xBottom)
282        self.setAxisAutoScale(self.yLeft)
283       
284        self.networkCurve = NetworkCurve(self)
285        self.callbackMoveVertex = None
286        self.callbackSelectVertex = None
287        self.minComponentEdgeWidth = 0
288        self.maxComponentEdgeWidth = 0
289        self.items_matrix = None
290        self.controlPressed = False
291        self.altPressed = False
292        self.items = None
293        self.links = None
294       
295        self.setFocusPolicy(Qt.StrongFocus)
296       
297    def getSelection(self):
298      return self.networkCurve.get_selected_nodes()
299   
300    def get_marked_nodes(self):
301      return self.networkCurve.get_marked_nodes()
302       
303    def getVertexSize(self, index):
304        return 6
305       
306    def set_hidden_nodes(self, nodes):
307        self.networkCurve.set_hidden_nodes(nodes)
308   
309    def hide_selected_nodes(self):
310      self.networkCurve.hide_selected_nodes()
311      self.drawPlotItems()
312     
313    def hide_unselected_nodes(self):
314      self.networkCurve.hide_unselected_nodes()
315      self.drawPlotItems()
316     
317    def show_all_vertices(self):
318      self.networkCurve.show_all_vertices()
319      self.drawPlotItems()
320     
321    def optimize(self, frSteps):
322        qApp.processEvents()
323        tolerance = 5
324        initTemp = 100
325        breakpoints = 20
326        k = int(frSteps / breakpoints)
327        o = frSteps % breakpoints
328        iteration = 0
329        coolFactor = exp(log(10.0 / 10000.0) / frSteps)
330        #print coolFactor
331        if k > 0:
332            while iteration < breakpoints:
333                initTemp = self.layout.fruchtermanReingold(k, initTemp, coolFactor, self.hiddenNodes)
334                iteration += 1
335                qApp.processEvents()
336                self.updateCanvas()
337   
338            initTemp = self.layout.fruchtermanReingold(o, initTemp, coolFactor, self.hiddenNodes)
339            qApp.processEvents()
340            self.updateCanvas()
341        else:
342            while iteration < o:
343                initTemp = self.layout.fruchtermanReingold(1, initTemp, coolFactor, self.hiddenNodes)
344                iteration += 1
345                qApp.processEvents()
346                self.updateCanvas()
347               
348    def markedToSelection(self):
349        self.networkCurve.mark_to_sel()
350        self.drawPlotItems()
351       
352    def selectionToMarked(self):
353        self.networkCurve.sel_to_mark()
354        self.drawPlotItems()
355       
356        if self.sendMarkedNodes != None:
357            self.sendMarkedNodes(self.networkCurve.get_marked_nodes())
358       
359    def removeSelection(self, replot=True):
360        self.networkCurve.unselect()
361       
362        if replot:
363          self.replot()
364   
365    def selectNeighbours(self, sel, nodes, depth, maxdepth):
366        #print "list: " + str(sel)
367        #print "nodes: " + str(nodes)
368        sel.update(nodes)
369        if depth < maxdepth:
370            for i in nodes:
371                neighbours = set(self.graph.neighbors(i))
372                #print "neighbours: " + str(neighbours)
373                self.selectNeighbours(sel, neighbours - sel, depth + 1, maxdepth)
374       
375    def getSelectedExamples(self):
376        return self.networkCurve.get_selected_nodes()
377       
378    def getUnselectedExamples(self):
379        return self.networkCurve.get_unselected_nodes()
380   
381    def getSelectedGraph(self):
382      selection = self.networkCurve.get_selected_nodes()
383     
384      if len(selection) == 0:
385          return None
386     
387      subgraph = self.graph.subgraph(selection)
388      subnet = Network(subgraph)
389      return subnet
390   
391    def get_selected_nodes(self):
392      return self.networkCurve.get_selected_nodes()
393   
394    def getNeighboursUpTo(self, ndx, dist):
395        newNeighbours = neighbours = set([ndx])
396        for d in range(dist):
397            tNewNeighbours = set()
398            for v in newNeighbours:
399                tNewNeighbours |= set(self.graph.neighbors(v))
400            newNeighbours = tNewNeighbours - neighbours
401            neighbours |= newNeighbours
402        return neighbours
403     
404    def markSelectionNeighbours(self):
405        if not self.freezeNeighbours and self.selectionNeighbours:
406            toMark = set()
407            for ndx in self.networkCurve.get_selected_nodes():
408                toMark |= self.getNeighboursUpTo(ndx, self.selectionNeighbours)
409           
410            self.networkCurve.set_marked_nodes(toMark)
411            self.drawPlotItems()
412               
413        elif not self.freezeNeighbours and self.selectionNeighbours == 0:
414            self.networkCurve.set_marked_nodes(self.networkCurve.get_selected_nodes())
415            self.drawPlotItems()
416           
417        if self.sendMarkedNodes != None:
418            self.sendMarkedNodes(self.networkCurve.get_marked_nodes())
419               
420    def unmark(self):
421      self.networkCurve.unmark()
422      self.drawPlotItems(replot=0)
423     
424      if self.sendMarkedNodes != None:
425            self.sendMarkedNodes([])
426           
427    def set_marked_nodes(self, vertices):
428      self.networkCurve.set_marked_nodes(vertices)
429      self.drawPlotItems(replot=0)
430     
431      if self.sendMarkedNodes != None:
432            self.sendMarkedNodes(self.networkCurve.get_marked_nodes())
433       
434    def activateMoveSelection(self):
435        self.state = MOVE_SELECTION
436   
437    def mouseMoveEvent(self, event):
438        if not self.graph:
439          return
440         
441        if self.mouseCurrentlyPressed and self.state == MOVE_SELECTION and self.GMmouseMoveEvent != None:
442            newX = self.invTransform(2, event.pos().x())
443            newY = self.invTransform(0, event.pos().y())
444           
445            dx = newX - self.invTransform(2, self.GMmouseMoveEvent.x())
446            dy = newY - self.invTransform(0, self.GMmouseMoveEvent.y())
447            movedVertices = self.networkCurve.move_selected_nodes(dx, dy)
448           
449            self.GMmouseMoveEvent.setX(event.pos().x())  #zacetni dogodek postane trenutni
450            self.GMmouseMoveEvent.setY(event.pos().y())
451           
452            self.drawPlotItems(replot=1, vertices=movedVertices)
453            if self.callbackMoveVertex:
454                self.callbackMoveVertex()
455        else:
456            OWGraph.mouseMoveEvent(self, event)
457               
458        if not self.freezeNeighbours and self.tooltipNeighbours:
459            px = self.invTransform(2, event.x())
460            py = self.invTransform(0, event.y())   
461            ndx, mind = self.networkCurve.closest_node(px, py)
462            dX = self.transform(QwtPlot.xBottom, self.networkCurve.coors[ndx][0]) - event.x()
463            dY = self.transform(QwtPlot.yLeft,   self.networkCurve.coors[ndx][1]) - event.y()
464            # transform to pixel distance
465            distance = math.sqrt(dX**2 + dY**2) 
466             
467            if ndx != -1 and distance <= self.networkCurve.vertices[ndx].size:
468                toMark = set(self.getNeighboursUpTo(ndx, self.tooltipNeighbours))
469                self.networkCurve.set_marked_nodes(toMark)
470                self.drawPlotItems()
471               
472                if self.sendMarkedNodes != None:
473                    self.sendMarkedNodes(self.networkCurve.get_marked_nodes())
474            else:
475                self.networkCurve.unmark()
476                self.drawPlotItems()
477               
478                if self.sendMarkedNodes != None:
479                    self.sendMarkedNodes([])
480       
481        if self.showDistances:
482            selection = self.networkCurve.get_selected_nodes()
483            if len(selection) > 0:
484                px = self.invTransform(2, event.x())
485                py = self.invTransform(0, event.y()) 
486                 
487                v, mind = self.networkCurve.closest_node(px, py)
488                dX = self.transform(QwtPlot.xBottom, self.networkCurve.coors[v][0]) - event.x()
489                dY = self.transform(QwtPlot.yLeft,   self.networkCurve.coors[v][1]) - event.y()
490                # transform to pixel distance
491                distance = math.sqrt(dX**2 + dY**2)               
492                if v != -1 and distance <= self.networkCurve.vertices[v].size:
493                    if self.items_matrix == None:
494                        dst = 'vertex distance signal not set'
495                    else:
496                        dst = 0
497                        for u in selection:
498                            dst += self.items_matrix[u, v]
499                        dst = dst / len(selection)
500                       
501                    self.showTip(event.pos().x(), event.pos().y(), str(dst))
502                    self.replot()
503   
504    def mousePressEvent(self, event):
505      if self.graph is None:
506          return
507         
508      #self.grabKeyboard()
509      self.mouseSelectedVertex = 0
510      self.GMmouseMoveEvent = None
511     
512      if self.state == MOVE_SELECTION:
513        self.mouseCurrentlyPressed = 1
514        #if self.isPointSelected(self.invTransform(self.xBottom, event.pos().x()), self.invTransform(self.yLeft, event.pos().y())) and self.selection != []:
515        #  self.GMmouseStartEvent = QPoint(event.pos().x(), event.pos().y())
516        #else:
517          # button pressed outside selected area or there is no area
518        self.selectVertex(event.pos())
519        self.GMmouseStartEvent = QPoint(event.pos().x(), event.pos().y())
520        self.replot()
521      elif self.state == SELECT_RECTANGLE:
522          self.GMmouseStartEvent = QPoint(event.pos().x(), event.pos().y())
523         
524          if self.clickedSelectedOnVertex(event.pos()):
525              self.mouseSelectedVertex = 1
526              self.mouseCurrentlyPressed = 1
527              self.state = MOVE_SELECTION
528              self.GMmouseMoveEvent = QPoint(event.pos().x(), event.pos().y())
529          elif self.clickedOnVertex(event.pos()):
530              self.mouseSelectedVertex = 1
531              self.mouseCurrentlyPressed = 1
532          else:
533              OWGraph.mousePressEvent(self, event) 
534      else:
535          OWGraph.mousePressEvent(self, event)     
536   
537    def mouseReleaseEvent(self, event): 
538        if self.graph is None:
539          return
540         
541        #self.releaseKeyboard()
542        if self.state == MOVE_SELECTION:
543            self.state = SELECT_RECTANGLE
544            self.mouseCurrentlyPressed = 0
545           
546            self.moveGroup = False
547            #self.GMmouseStartEvent=None
548           
549        if self.state == SELECT_RECTANGLE:
550            x1 = self.invTransform(2, self.GMmouseStartEvent.x())
551            y1 = self.invTransform(0, self.GMmouseStartEvent.y())
552           
553            x2 = self.invTransform(2, event.pos().x())
554            y2 = self.invTransform(0, event.pos().y())
555           
556           
557            if self.mouseSelectedVertex == 1 and x1 == x2 and y1 == y2 and self.selectVertex(self.GMmouseStartEvent):
558                QwtPlot.mouseReleaseEvent(self, event)
559            elif self.mouseSelectedVertex == 0:
560                 
561                selection = self.networkCurve.get_nodes_in_rect(x1, y1, x2, y2)
562   
563                def selectVertex(ndx):
564                    if self.networkCurve.vertices[ndx].show:
565                        self.networkCurve.vertices[ndx].selected = True
566                       
567                map(selectVertex, selection)
568               
569                if len(selection) == 0 and x1 == x2 and y1 == y2:
570                    self.removeSelection()
571                    self.unmark()
572           
573                self.markSelectionNeighbours()
574                OWGraph.mouseReleaseEvent(self, event)
575                self.removeAllSelections()
576   
577        elif self.state == SELECT_POLYGON:
578                OWGraph.mouseReleaseEvent(self, event)
579                if self.tempSelectionCurve == None:   #if OWVisGraph closed polygon
580                    self.selectVertices()
581        else:
582            OWGraph.mouseReleaseEvent(self, event)
583           
584        self.mouseCurrentlyPressed = 0
585        self.moveGroup = False
586           
587        if self.callbackSelectVertex != None:
588            self.callbackSelectVertex()
589   
590    def keyPressEvent(self, e):
591        if self.graph is None:
592          return
593         
594        if e.key() == 87 or e.key() == 81:
595            selection = [v.index for v in self.networkCurve.vertices.itervalues() if v.selected]
596            if len(selection) > 0:
597                phi = [math.pi / -180 if e.key() == 87 else math.pi / 180]
598                self.layout.rotate_vertices([selection], phi)
599                self.drawPlotItems(replot=1)
600           
601        if e.key() == Qt.Key_Control:
602            self.controlPressed = True
603       
604        elif e.key() == Qt.Key_Alt:
605            self.altPressed = True
606           
607        if e.text() == "f":
608            self.graph.freezeNeighbours = not self.graph.freezeNeighbours
609       
610        OWGraph.keyPressEvent(self, e)
611           
612    def keyReleaseEvent(self, e):
613        if e.key() == Qt.Key_Control:
614            self.controlPressed = False
615       
616        elif e.key() == Qt.Key_Alt:
617            self.altPressed = False
618       
619        OWGraph.keyReleaseEvent(self, e)
620       
621    def clickedSelectedOnVertex(self, pos):
622        min = 1000000
623        ndx = -1
624   
625        px = self.invTransform(2, pos.x())
626        py = self.invTransform(0, pos.y())   
627   
628        ndx, min = self.networkCurve.closest_node(px, py)
629        dX = self.transform(QwtPlot.xBottom, self.networkCurve.coors[ndx][0]) - pos.x()
630        dY = self.transform(QwtPlot.yLeft,   self.networkCurve.coors[ndx][1]) - pos.y()
631        # transform to pixel distance
632        distance = math.sqrt(dX**2 + dY**2)
633       
634        #self.networkCurve
635       
636        if ndx != -1 and distance <= self.networkCurve.vertices[ndx].size:
637            return self.networkCurve.vertices[ndx].selected
638        else:
639            return False
640       
641    def clickedOnVertex(self, pos):
642        min = 1000000
643        ndx = -1
644   
645        px = self.invTransform(2, pos.x())
646        py = self.invTransform(0, pos.y())   
647   
648        ndx, min = self.networkCurve.closest_node(px, py)
649        dX = self.transform(QwtPlot.xBottom, self.networkCurve.coors[ndx][0]) - pos.x()
650        dY = self.transform(QwtPlot.yLeft,   self.networkCurve.coors[ndx][1]) - pos.y()
651        # transform to pixel distance
652        distance = math.sqrt(dX**2 + dY**2)
653        if ndx != -1 and distance <= self.networkCurve.vertices[ndx].size:
654            return True
655        else:
656            return False
657               
658    def selectVertex(self, pos):
659        min = 1000000
660        ndx = -1
661   
662        px = self.invTransform(2, pos.x())
663        py = self.invTransform(0, pos.y())   
664   
665        ndx, min = self.networkCurve.closest_node(px, py)
666       
667        dX = self.transform(QwtPlot.xBottom, self.networkCurve.coors[ndx][0]) - pos.x()
668        dY = self.transform(QwtPlot.yLeft,   self.networkCurve.coors[ndx][1]) - pos.y()
669        # transform to pixel distance
670        distance = math.sqrt(dX**2 + dY**2)
671        if ndx != -1 and distance <= self.networkCurve.vertices[ndx].size:
672            if not self.appendToSelection and not self.controlPressed:
673                self.removeSelection()
674                     
675            if self.insideview:
676                self.networkCurve.unselect()
677                self.networkCurve.vertices[ndx].selected = not self.networkCurve.vertices[ndx].selected
678                self.optimize(100)
679               
680                self.markSelectionNeighbours()
681            else:
682                self.networkCurve.vertices[ndx].selected = not self.networkCurve.vertices[ndx].selected
683                self.markSelectionNeighbours()
684           
685            return True 
686        else:
687            return False
688            self.removeSelection()
689            self.unmark()
690   
691    def updateData(self):
692        if self.graph is None:
693            return
694       
695        self.removeDrawingCurves(removeLegendItems=0)
696        self.tips.removeAll()
697       
698        if self.items_matrix and self.minComponentEdgeWidth > 0 and self.maxComponentEdgeWidth > 0:         
699            components = Orange.network.nx.algorithms.components.connected_components(self.graph)
700            matrix = self.items_matrix.avgLinkage(components)
701           
702            edges = set()
703            for u in range(matrix.dim):
704                neighbours = matrix.getKNN(u, 2)
705                for v in neighbours:
706                    if v < u:
707                        edges.add((v, u))
708                    else:
709                        edges.add((u, v))
710            edges = list(edges)
711    # show 2n strongest edges
712    #          vals = matrix.getValues()
713    #          vals = zip(vals, range(len(vals)))
714    #          count = 0
715    #          add = 0
716    #          for i in range(matrix.dim):
717    #              add += i + 1
718    #              for j in range(i+1, matrix.dim):
719    #                  v, ind = vals[count]
720    #                  ind += add
721    #                  vals[count] = (v, ind)
722    #                  count += 1
723    #          vals.sort(reverse=0)
724    #          vals = vals[:2 * matrix.dim]
725    #          edges = [(ind / matrix.dim, ind % matrix.dim) for v, ind in vals]
726    #          print "number of component edges:", len(edges), "number of components:", len(components)
727#            components_c = [(sum(self.networkCurve.coors[c][0]) / len(c), sum(self.networkCurve.coors[c][1]) / len(c)) for c in components]
728#            weights = [1 - matrix[u,v] for u,v in edges]
729#           
730#            max_weight = max(weights)
731#            min_weight = min(weights)
732#            span_weights = max_weight - min_weight
733#         
734#            for u,v in edges:
735#                x = [components_c[u][0], components_c[v][0]]
736#                y = [components_c[u][1], components_c[v][1]]
737#                w = ((1 - matrix[u,v]) - min_weight) / span_weights * (self.maxComponentEdgeWidth - self.minComponentEdgeWidth) + self.minComponentEdgeWidth
738#               
739#                pen = QPen()
740#                pen.setWidth(int(w))
741#                pen.setBrush(QColor(50,200,255,15))
742#                pen.setCapStyle(Qt.FlatCap)
743#                pen.setJoinStyle(Qt.RoundJoin)
744#                self.addCurve("component_edges", Qt.green, Qt.green, 0, style=QwtPlotCurve.Lines, symbol = QwtSymbol.NoSymbol, xData=x, yData=y, pen=pen, showFilledSymbols=False)
745       
746       
747        self.networkCurve.setData(self.layout.coors[0], self.layout.coors[1])
748       
749        if self.insideview == 1:
750            selection = self.networkCurve.get_selected_nodes()
751            if len(selection) >= 1:
752                visible = set()
753                visible |= set(selection)
754                visible |= self.getNeighboursUpTo(selection[0], self.insideviewNeighbours)
755                self.networkCurve.set_hidden_nodes(set(range(self.graph.number_of_nodes())) - visible)
756   
757        edgesCount = 0
758       
759        if self.forceVectors != None:
760            for v in self.forceVectors:
761                self.addCurve("force", Qt.white, Qt.green, 1, style=QwtPlotCurve.Lines, xData=v[0], yData=v[1], showFilledSymbols=False)
762       
763        for r in self.circles:
764            step = 2 * pi / 64;
765            fi = 0
766            x = []
767            y = []
768            for i in range(65):
769                x.append(r * cos(fi) + 5000)
770                y.append(r * sin(fi) + 5000)
771                fi += step
772               
773            self.addCurve("radius", Qt.white, Qt.green, 1, style=QwtPlotCurve.Lines, xData=x, yData=y, showFilledSymbols=False)
774       
775        if self.renderAntialiased:
776            self.networkCurve.setRenderHint(QwtPlotItem.RenderAntialiased)
777        else:
778            self.networkCurve.setRenderHint(QwtPlotItem.RenderAntialiased, False)
779     
780        self.networkCurve.showEdgeLabels = self.showEdgeLabels
781        self.networkCurve.attach(self)
782        self.drawPlotItems(replot=0)
783       
784        #self.zoomExtent()
785       
786    def drawPlotItems(self, replot=1, vertices=[]):
787        if len(vertices) > 0:
788            for vertex in vertices:
789                x1 = float(self.networkCurve.coors[vertex][0])
790                y1 = float(self.networkCurve.coors[vertex][1])
791               
792                if vertex in self.markerKeys:
793                    mkey = self.markerKeys[vertex]
794                    mkey.setValue(x1, y1)
795             
796                if 'index ' + str(vertex) in self.markerKeys:
797                    mkey = self.markerKeys['index ' + str(vertex)]
798                    mkey.setValue(x1, y1)
799               
800                if vertex in self.tooltipKeys:
801                    tkey = self.tooltipKeys[vertex]
802                    self.tips.positions[tkey] = (x1, y1, 0, 0)
803        else:
804            self.markerKeys = {}
805            self.removeMarkers()
806            self.drawLabels()
807            self.drawToolTips()
808            self.drawWeights()
809            self.drawIndexes()
810            self.drawComponentKeywords()
811       
812        if replot:
813            self.replot()
814           
815    def drawComponentKeywords(self):
816        if self.showComponentAttribute == None:
817            return
818       
819        if self.layout is None or self.graph is None or self.items is None:
820            return
821       
822        if str(self.showComponentAttribute) not in self.items.domain:
823            self.showComponentAttribute = None
824            return
825       
826        components = Orange.network.nx.algorithms.components.connected_components(self.graph)
827       
828        for component in components:
829            if len(component) == 0:
830                continue
831           
832            vertices = [vertex for vertex in component if self.networkCurve.vertices[vertex].show]
833   
834            if len(vertices) == 0:
835                continue
836           
837            xes = [self.networkCurve.coors[vertex][0] for vertex in vertices] 
838            yes = [self.networkCurve.coors[vertex][1] for vertex in vertices] 
839                                 
840            x1 = sum(xes) / len(xes)
841            y1 = sum(yes) / len(yes)
842           
843            lbl = str(self.items[component[0]][str(self.showComponentAttribute)])
844           
845            mkey = self.addMarker(lbl, float(x1), float(y1), alignment=Qt.AlignCenter, size=self.fontSize)
846   
847    def drawToolTips(self):
848      # add ToolTips
849      self.tooltipData = []
850      self.tooltipKeys = {}
851      self.tips.removeAll()
852      if len(self.tooltipText) > 0:
853        for vertex in self.networkCurve.vertices.itervalues():
854          if not vertex.show:
855            continue
856         
857          x1 = self.networkCurve.coors[vertex.index][0]
858          y1 = self.networkCurve.coors[vertex.index][1]
859          lbl = ""
860          values = self.items[vertex.index]
861          for ndx in self.tooltipText:
862              if not ndx in self.items.domain:
863                  continue
864             
865              value = str(values[ndx])
866              # wrap text
867              i = 0
868              while i < len(value) / 100:
869                  value = value[:((i + 1) * 100) + i] + "\n" + value[((i + 1) * 100) + i:]
870                  i += 1
871                 
872              lbl = lbl + str(value) + "\n"
873   
874          if lbl != '':
875            lbl = lbl[:-1]
876            self.tips.addToolTip(x1, y1, lbl)
877            self.tooltipKeys[vertex.index] = len(self.tips.texts) - 1
878                   
879    def drawLabels(self):
880        if len(self.labelText) > 0:
881            for vertex in self.networkCurve.vertices.itervalues():
882                if not vertex.show:
883                    continue
884               
885                if self.labelsOnMarkedOnly and not (vertex.marked):
886                    continue
887                                 
888                x1 = self.networkCurve.coors[vertex.index][0]
889                y1 = self.networkCurve.coors[vertex.index][1]
890                lbl = ""
891                values = self.items[vertex.index]
892                if self.showMissingValues:
893                    lbl = ", ".join([str(values[ndx]) for ndx in self.labelText])
894                else:
895                    lbl = ", ".join([str(values[ndx]) for ndx in self.labelText if str(values[ndx]) != '?'])
896                #if not self.showMissingValues and lbl == '':
897                #    continue
898               
899                if lbl:
900                    vertex.label = lbl
901                    mkey = self.addMarker(lbl, float(x1), float(y1), alignment=Qt.AlignBottom, size=self.fontSize)
902                    self.markerKeys[vertex.index] = mkey   
903                     
904    def drawIndexes(self):
905        if self.showIndexes:
906            for vertex in self.networkCurve.vertices.itervalues():
907                if not vertex.show:
908                    continue
909               
910                if self.labelsOnMarkedOnly and not (vertex.marked):
911                    continue
912                                 
913                x1 = self.networkCurve.coors[vertex.index][0]
914                y1 = self.networkCurve.coors[vertex.index][1]
915   
916                lbl = str(vertex.index)
917                mkey = self.addMarker(lbl, float(x1), float(y1), alignment=Qt.AlignTop, size=self.fontSize)
918                self.markerKeys['index ' + str(vertex.index)] = mkey         
919   
920    def drawWeights(self):
921        if self.showWeights:
922            for edge in self.edges:
923                if not (edge.u.show and edge.v.show):
924                    continue
925               
926                if self.labelsOnMarkedOnly and not (edge.u.marked and edge.v.marked):
927                    continue
928                                 
929                x1 = (self.networkCurve.coors[edge.u.index][0] + self.networkCurve.coors[edge.v.index][0]) / 2
930                y1 = (self.networkCurve.coors[edge.u.index][1] + self.networkCurve.coors[edge.v.index][1]) / 2
931               
932                if edge.weight == None:
933                    lbl = "None"
934                else:
935                    lbl = "%.2f" % float(edge.weight)
936               
937                mkey = self.addMarker(lbl, float(x1), float(y1), alignment=Qt.AlignCenter, size=self.fontSize)
938                self.markerKeys[(edge.u, edge.v)] = mkey
939                           
940    def getColorIndeces(self, table, attribute, palette):
941        colorIndices = {}
942        colorIndex = None
943        minValue = None
944        maxValue = None
945       
946        if attribute[0] != "(" or attribute[ -1] != ")":
947            i = 0
948            for var in table.domain.variables:
949                if var.name == attribute:
950                    colorIndex = i
951                    if var.varType == orange.VarTypes.Discrete: 
952                        colorIndices = getVariableValueIndices(var, colorIndex)
953                       
954                i += 1
955            metas = table.domain.getmetas()
956            for i, var in metas.iteritems():
957                if var.name == attribute:
958                    colorIndex = i
959                    if var.varType == orange.VarTypes.Discrete: 
960                        colorIndices = getVariableValueIndices(var, colorIndex)
961   
962        colorIndices['?'] = len(colorIndices)
963        palette.setNumberOfColors(len(colorIndices))
964       
965        if colorIndex != None and table.domain[colorIndex].varType == orange.VarTypes.Continuous:
966            minValue = float(min([x[colorIndex].value for x in table if x[colorIndex].value != "?"] or [0.0]))
967            maxValue = float(max([x[colorIndex].value for x in table if x[colorIndex].value != "?"] or [0.0]))
968           
969        return colorIndices, colorIndex, minValue, maxValue
970   
971    def set_edge_color(self, attribute):
972        if self.graph is None:
973            return
974       
975        colorIndices, colorIndex, minValue, maxValue = self.getColorIndeces(self.links, attribute, self.discEdgePalette)
976   
977        for index in range(len(self.networkCurve.edges)):
978            if colorIndex != None:
979                links_index = self.networkCurve.edges[index].links_index
980                if links_index == None:
981                    continue
982               
983                if self.links.domain[colorIndex].varType == orange.VarTypes.Continuous:
984                    newColor = self.discEdgePalette[0]
985                    if str(self.links[links_index][colorIndex]) != "?":
986                        if maxValue == minValue:
987                            newColor = self.discEdgePalette[0]
988                        else:
989                            value = (float(self.links[links_index][colorIndex].value) - minValue) / (maxValue - minValue)
990                            newColor = self.contEdgePalette[value]
991                       
992                    self.networkCurve.set_edge_color(index, newColor)
993                   
994                elif self.links.domain[colorIndex].varType == orange.VarTypes.Discrete:
995                    newColor = self.discEdgePalette[colorIndices[self.links[links_index][colorIndex].value]]
996                    if self.links[links_index][colorIndex].value == "0":
997                      self.networkCurve.set_edge_color(index, newColor, nocolor=1)
998                    else:
999                      self.networkCurve.set_edge_color(index, newColor)
1000                   
1001            else:
1002                newColor = self.discEdgePalette[0]
1003                self.networkCurve.set_edge_color(index, newColor)
1004       
1005        self.replot()
1006   
1007    def set_node_color(self, attribute, nodes=None):
1008        if self.graph is None:
1009            return
1010       
1011        if nodes is None:
1012            nodes = self.networkCurve.vertices.itervalues()
1013        else:
1014            nodes = (self.networkCurve.vertices[nodes] for node in nodes) 
1015           
1016        colorIndices, colorIndex, minValue, maxValue = self.getColorIndeces(self.items, attribute, self.discPalette)
1017   
1018        if colorIndex is not None and self.items.domain[colorIndex].varType == orange.VarTypes.Continuous:
1019            for vertex in nodes:
1020                v = vertex.index
1021                newColor = self.discPalette[0]
1022               
1023                if str(self.items[v][colorIndex]) != "?":
1024                    if maxValue == minValue:
1025                        newColor = self.discPalette[0]
1026                    else:
1027                        value = (float(self.items[v][colorIndex].value) - minValue) / (maxValue - minValue)
1028                        newColor = self.contPalette[value]
1029                   
1030                self.networkCurve.set_node_color(v, newColor)
1031               
1032        elif colorIndex is not None and self.items.domain[colorIndex].varType == orange.VarTypes.Discrete:
1033            for vertex in nodes:
1034                v = vertex.index
1035                newColor = self.discPalette[colorIndices[self.items[v][colorIndex].value]]
1036                self.networkCurve.set_node_color(v, newColor)
1037        else:
1038            self.networkCurve.set_nodes_color(nodes, self.discPalette[0])
1039           
1040        self.replot()
1041       
1042    def setLabelText(self, attributes):
1043        self.labelText = []
1044        if self.layout is None or self.graph is None or self.items is None:
1045            return
1046       
1047        if isinstance(self.items, orange.ExampleTable):
1048            data = self.items
1049            for att in attributes:
1050                for i in range(len(data.domain)):
1051                    if data.domain[i].name == att:
1052                        self.labelText.append(i)
1053                       
1054                if self.items.domain.hasmeta(att):
1055                        self.labelText.append(self.items.domain.metaid(att))
1056   
1057    def setTooltipText(self, attributes):
1058        self.tooltipText = []
1059        if self.layout is None or self.graph is None or self.items is None:
1060            return
1061       
1062        if isinstance(self.items, orange.ExampleTable):
1063            data = self.items
1064            for att in attributes:
1065                for i in range(len(data.domain)):
1066                    if data.domain[i].name == att:
1067                        self.tooltipText.append(i)
1068                       
1069                if self.items.domain.hasmeta(att):
1070                        self.tooltipText.append(self.items.domain.metaid(att))
1071                       
1072    def setEdgeLabelText(self, attributes):
1073        self.edgeLabelText = []
1074        if self.layout is None or self.graph is None or self.items is None:
1075            return
1076       
1077    def change_graph(self, newgraph, inter_nodes, add_nodes, remove_nodes):
1078        self.graph = newgraph
1079       
1080        [self.networkCurve.vertices.pop(key) for key in remove_nodes]
1081        self.networkCurve.vertices.update(dict((v, NodeItem(v)) for v in add_nodes))
1082        vertices = self.networkCurve.vertices
1083       
1084        #build edge index
1085        row_ind = {}
1086        if self.links is not None and len(self.links) > 0:
1087          for i, r in enumerate(self.links):
1088              u = int(r['u'].value)
1089              v = int(r['v'].value)
1090              if u in self.graph and v in self.graph:
1091                  u_dict = row_ind.get(u, {})
1092                  v_dict = row_ind.get(v, {})
1093                  u_dict[v] = i
1094                  v_dict[u] = i
1095                  row_ind[u] = u_dict
1096                  row_ind[v] = v_dict
1097                 
1098        #add edges
1099        if self.links is not None and len(self.links) > 0:
1100            links = self.links
1101            links_indices = (row_ind[i + 1][j + 1] for (i, j) in self.graph.edges())
1102            labels = ([str(row[r].value) for r in range(2, len(row))] for row in (links[links_index] for links_index in links_indices))
1103           
1104            if self.graph.is_directed():
1105                edges = [EdgeItem(vertices[i], vertices[j],
1106                    self.graph[i][j].get('weight', 1), 0, 1, links_index, label) for \
1107                    ((i, j), links_index, label) in zip(self.graph.edges(), \
1108                                                        links_indices, labels)]
1109            else:
1110                edges = [EdgeItem(vertices[i], vertices[j],
1111                    self.graph[i][j].get('weight', 1), links_index, label) for \
1112                    ((i, j), links_index, label) in zip(self.graph.edges(), \
1113                                                        links_indices, labels)]
1114        elif self.graph.is_directed():
1115            edges = [EdgeItem(vertices[i], vertices[j],
1116                                      self.graph[i][j].get('weight', 1), 0, 1) for (i, j) in self.graph.edges()]
1117        else:
1118            edges = [EdgeItem(vertices[i], vertices[j],
1119                                      self.graph[i][j].get('weight', 1)) for (i, j) in self.graph.edges()]
1120                 
1121        #self.minEdgeWeight = min(edge.weight for edge in edges) if len(edges) > 0 else 0
1122        #self.maxEdgeWeight = max(edge.weight for edge in edges) if len(edges) > 0 else 0
1123       
1124        #if self.minEdgeWeight is None:
1125        #    self.minEdgeWeight = 0
1126       
1127        #if self.maxEdgeWeight is None:
1128        #    self.maxEdgeWeight = 0
1129                         
1130        #self.maxEdgeSize = 10
1131           
1132        #self.setEdgesSize()
1133        #self.setVerticesSize()
1134       
1135        self.networkCurve.coors = self.layout.map_to_graph(self.graph)
1136        self.networkCurve.edges = edges
1137        self.networkCurve.changed()
1138       
1139    def set_graph_layout(self, graph, layout, curve=None, items=None, links=None):
1140        self.clear()
1141        self.vertexDegree = []
1142        #self.vertices_old = {}
1143        #self.vertices = []
1144        #self.edges_old = {}
1145        #self.edges = []
1146        self.minEdgeWeight = sys.maxint
1147        self.maxEdgeWeight = 0
1148       
1149        if graph is None or layout is None:
1150            self.graph = None
1151            self.layout = None
1152            self.networkCurve = None
1153            self.items = None
1154            self.links = None
1155            xMin = self.axisScaleDiv(QwtPlot.xBottom).interval().minValue()
1156            xMax = self.axisScaleDiv(QwtPlot.xBottom).interval().maxValue()
1157            yMin = self.axisScaleDiv(QwtPlot.yLeft).interval().minValue()
1158            yMax = self.axisScaleDiv(QwtPlot.yLeft).interval().maxValue()
1159            self.addMarker("no network", (xMax - xMin) / 2, (yMax - yMin) / 2, alignment=Qt.AlignCenter, size=self.fontSize)
1160            self.tooltipNeighbours = 0
1161            self.replot()
1162            return
1163       
1164        self.graph = graph
1165        self.layout = layout
1166        self.networkCurve = NetworkCurve(self) if curve is None else curve
1167        self.items = items if items is not None else self.graph.items()
1168        self.links = links if links is not None else self.graph.links()
1169       
1170        #add nodes
1171        #self.vertices_old = [(None, []) for v in self.graph]
1172        vertices = dict((v, NodeItem(v)) for v in self.graph)
1173       
1174        #build edge index
1175        row_ind = {}
1176        if self.links is not None and len(self.links) > 0:
1177          for i, r in enumerate(self.links):
1178              u = int(r['u'].value)
1179              v = int(r['v'].value)
1180              if u in self.graph and v in self.graph:
1181                  u_dict = row_ind.get(u, {})
1182                  v_dict = row_ind.get(v, {})
1183                  u_dict[v] = i
1184                  v_dict[u] = i
1185                  row_ind[u] = u_dict
1186                  row_ind[v] = v_dict
1187             
1188        #add edges
1189        if self.links is not None and len(self.links) > 0:
1190            links = self.links
1191            links_indices = (row_ind[i + 1][j + 1] for (i, j) in self.graph.edges())
1192            labels = ([str(row[r].value) for r in range(2, len(row))] for row in (links[links_index] for links_index in links_indices))
1193           
1194            if self.graph.is_directed():
1195                edges = [EdgeItem(vertices[i], vertices[j],
1196                    graph[i][j].get('weight', 1), 0, 1, links_index, label) for \
1197                    ((i, j), links_index, label) in zip(self.graph.edges(), \
1198                                                        links_indices, labels)]
1199            else:
1200                edges = [EdgeItem(vertices[i], vertices[j],
1201                    graph[i][j].get('weight', 1), links_index, label) for \
1202                    ((i, j), links_index, label) in zip(self.graph.edges(), \
1203                                                        links_indices, labels)]
1204        elif self.graph.is_directed():
1205            edges = [EdgeItem(vertices[i], vertices[j],
1206                                      graph[i][j].get('weight', 1), 0, 1) for (i, j) in self.graph.edges()]
1207        else:
1208            edges = [EdgeItem(vertices[i], vertices[j],
1209                                      graph[i][j].get('weight', 1)) for (i, j) in self.graph.edges()]
1210       
1211        self.minEdgeWeight = min(edge.weight for edge in edges) if len(edges) > 0 else 0
1212        self.maxEdgeWeight = max(edge.weight for edge in edges) if len(edges) > 0 else 0
1213       
1214        if self.minEdgeWeight is None: 
1215            self.minEdgeWeight = 0 
1216       
1217        if self.maxEdgeWeight is None: 
1218            self.maxEdgeWeight = 0 
1219                         
1220        self.maxEdgeSize = 10
1221           
1222        self.setEdgesSize()
1223        self.setVerticesSize()
1224       
1225        self.networkCurve.coors = self.layout.map_to_graph(self.graph)
1226        self.networkCurve.vertices = vertices
1227        self.networkCurve.edges = edges
1228        self.networkCurve.changed()
1229       
1230    def setEdgesSize(self):
1231        if self.maxEdgeWeight > self.minEdgeWeight:
1232            #print 'maxEdgeSize',self.maxEdgeSize
1233            #print 'maxEdgeWeight',self.maxEdgeWeight
1234            #print 'minEdgeWeight',self.minEdgeWeight
1235            k = (self.maxEdgeSize - 1) / (self.maxEdgeWeight - self.minEdgeWeight)
1236            for edge in self.networkCurve.edges:
1237                if edge.weight == None:
1238                    size = 1
1239                    edge.pen = QPen(edge.pen.color(), size)
1240                    edge.pen.setCapStyle(Qt.RoundCap)
1241                else:
1242                    if self.invertEdgeSize:
1243                        size = (self.maxEdgeWeight - edge.weight - self.minEdgeWeight) * k + 1
1244                    else:
1245                        size = (edge.weight - self.minEdgeWeight) * k + 1
1246                    edge.pen = QPen(edge.pen.color(), size)
1247                    edge.pen.setCapStyle(Qt.RoundCap)
1248        else:
1249            for edge in self.networkCurve.edges:
1250                edge.pen = QPen(edge.pen.color(), 1)
1251                edge.pen.setCapStyle(Qt.RoundCap)
1252               
1253    def setVerticesSize(self, column=None, inverted=0):
1254        if self.layout is None or self.graph is None or self.items is None:
1255            return
1256       
1257        column = str(column)
1258       
1259        if column in self.items.domain or (column.startswith("num of ") and column.replace("num of ", "") in self.items.domain):
1260            values = []
1261           
1262            if column in self.items.domain:
1263                values = [self.items[x][column].value for x in self.graph if not self.items[x][column].isSpecial()]
1264            else:
1265                values = [len(self.items[x][column.replace("num of ", "")].value.split(',')) for x in self.graph]
1266         
1267            minVertexWeight = float(min(values or [0]))
1268            maxVertexWeight = float(max(values or [0]))
1269           
1270            if maxVertexWeight - minVertexWeight == 0:
1271                k = 1 #doesn't matter
1272            else:
1273                k = (self.maxVertexSize - self.minVertexSize) / (maxVertexWeight - minVertexWeight)
1274           
1275            def getValue(v):
1276                if v.isSpecial():
1277                    return minVertexWeight
1278                else:
1279                    return float(v)
1280                 
1281            if inverted:
1282                for key, vertex in self.networkCurve.vertices.iteritems():
1283                    if column in self.items.domain:
1284                        vertex.size = self.maxVertexSize - ((getValue(self.items[vertex.index][column]) - minVertexWeight) * k)
1285                    else:
1286                        vertex.size = self.maxVertexSize - ((len(self.items[vertex.index][column.replace("num of ", "")].value.split(',')) - minVertexWeight) * k)
1287                   
1288                   
1289                    vertex.pen.setWidthF(1 + float(vertex.size) / 20)
1290            else:
1291                for key, vertex in self.networkCurve.vertices.iteritems():
1292                    if column in self.items.domain:
1293                        vertex.size = (getValue(self.items[vertex.index][column]) - minVertexWeight) * k + self.minVertexSize
1294                    else:
1295                        vertex.size = (float(len(self.items[vertex.index][column.replace("num of ", "")].value.split(','))) - minVertexWeight) * k + self.minVertexSize
1296                       
1297                    #print vertex.size
1298                    vertex.pen.setWidthF(1 + float(vertex.size) / 20)
1299        else:
1300            for key, vertex in self.networkCurve.vertices.iteritems():
1301                vertex.size = self.maxVertexSize
1302                vertex.pen.setWidthF(1 + float(vertex.size) / 20)
1303     
1304    def updateCanvas(self):
1305        self.setAxisAutoScale(self.xBottom)
1306        self.setAxisAutoScale(self.yLeft)
1307        self.updateData()
1308        self.replot() 
1309   
1310    def zoomExtent(self):
1311        self.setAxisAutoScale(self.xBottom)
1312        self.setAxisAutoScale(self.yLeft)
1313        self.replot()
1314       
1315    def zoomSelection(self):
1316        selection = self.networkCurve.get_selected_nodes()
1317        if len(selection) > 0: 
1318            x = [self.networkCurve.coors[v][0] for v in selection]
1319            y = [self.networkCurve.coors[v][1] for v in selection]
1320   
1321            oldXMin = self.axisScaleDiv(QwtPlot.xBottom).interval().minValue()
1322            oldXMax = self.axisScaleDiv(QwtPlot.xBottom).interval().maxValue()
1323            oldYMin = self.axisScaleDiv(QwtPlot.yLeft).interval().minValue()
1324            oldYMax = self.axisScaleDiv(QwtPlot.yLeft).interval().maxValue()
1325            newXMin = min(x)
1326            newXMax = max(x)
1327            newYMin = min(y)
1328            newYMax = max(y)
1329            self.zoomStack.append((oldXMin, oldXMax, oldYMin, oldYMax))
1330            self.setAxisScale(QwtPlot.xBottom, newXMin - 100, newXMax + 100)
1331            self.setAxisScale(QwtPlot.yLeft, newYMin - 100, newYMax + 100)
1332            self.replot()
1333                   
Note: See TracBrowser for help on using the repository browser.