Changeset 8309:73b6bbdf0bd5 in orange


Ignore:
Timestamp:
06/11/11 20:21:31 (3 years ago)
Author:
Noughmad <Noughmad@…>
Branch:
default
Convert:
267b1ed98ade83a5c791402ff5d0144c51efc8cb
Message:

Zooming and proper labels on axes for continuous attributes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/Graph/axis.py

    r8308 r8309  
    2626        Controls where the axis title and tick marks are placed relative to the axis 
    2727""" 
     28 
     29from math import * 
    2830 
    2931from PyQt4.QtGui import QGraphicsItemGroup, QGraphicsLineItem, QGraphicsTextItem, QPainterPath, QGraphicsPathItem, QGraphicsScene, QTransform 
     
    7173        self.label_items = [] 
    7274        self.tick_items = [] 
     75        self._ticks = [] 
    7376        self.zoom_transform = QTransform() 
     77         
     78    def update_ticks(self): 
     79        self._ticks = [] 
     80        min, max, step = self.scale 
     81        major, medium, minor = self.tick_length 
     82                 
     83        if self.labels: 
     84            qDebug('Labels defined: ' + str(len(self.labels))) 
     85            for i in range(len(self.labels)): 
     86                self._ticks.append( ( i, self.labels[i], medium ) ) 
     87        else: 
     88            qDebug('Constructing labels: ') 
     89            magnitude = int(3*log10(abs(max-min)) + 1) 
     90            if magnitude % 3 == 0: 
     91                first_place = 1 
     92            elif magnitude % 3 == 1: 
     93                first_place = 2 
     94            else: 
     95                first_place = 5 
     96            magnitude = magnitude / 3 - 1 
     97            step = first_place * pow(10, magnitude) 
     98            val = ceil(min/step) * step 
     99            while val <= max: 
     100                self._ticks.append( ( val, "%.4g" % val, medium ) ) 
     101                val = val + step 
    74102 
    75103    def update(self): 
    76104        if not self.line or not self.title or not self.scene(): 
    77105            return 
    78         if not self.style: 
    79             self.style = shared_palette().axis_style 
    80106        self.line_item.setLine(self.line) 
    81107        self.line_item.setPen(self.style.pen()) 
     
    112138             
    113139        ## Labels 
     140         
     141        self.update_ticks() 
     142         
    114143        for i in self.label_items: 
    115144            self.scene().removeItem(i) 
     
    119148        del self.tick_items[:] 
    120149        min, max, step = self.scale 
    121         qDebug(str(step)) 
    122         if self.labels: 
    123             self.transform = QTransform().translate(-self.x(), -self.y()) * self.zoom_transform * QTransform().translate(self.x(), self.y()) 
    124             ratio = self.transform.map(self.line).length() / self.line.length() 
    125             qDebug('Axis zoom ratio = ' + str(ratio)) 
    126             for i in range(len(self.labels)): 
    127                 label_pos = self.map_to_graph( i * step) 
    128                 test_rect = QRectF(self.line.p1(),  self.line.p2()).normalized() 
    129                 test_rect.adjust(-1, -1, 1, 1) 
    130                 if not test_rect.contains(label_pos): 
    131                     qDebug('Skipping label ' + self.labels[i]) 
    132                     continue 
    133                 label_pos = self.map_to_graph((i-0.5) * step) 
    134                 item = QGraphicsTextItem(self) 
    135                 item.setHtml( '<center>' + self.labels[i] + '</center>') 
    136                 item.setTextWidth(self.line.length() / len(self.labels) * ratio) 
    137                 v = self.line.normalVector().unitVector() 
    138                 if self.title_above: 
    139                     label_pos = label_pos + (v.p2() - v.p1())*40 
    140                 item.setPos(label_pos) 
    141                 item.setRotation(-self.line.angle()) 
    142                 self.label_items.append(item) 
    143         elif self.scale and self.tick_length: 
    144             t = min 
    145             while t <= max: 
    146                 p1 = self.map_to_graph(t) 
    147                 label_pos = self.map_to_graph( t - step/2 ) 
    148                 (major, medium, minor) = self.tick_length 
    149                 v = self.line.normalVector().unitVector() 
    150                 d = (v.p2() - v.p1())*medium 
    151                 if self.title_above: 
    152                     p2 = p1 - d 
    153                     label_pos = label_pos + d/major * 30 
    154                 else: 
    155                     p2 = p1 + d 
    156                 self.tick_items.append(QGraphicsLineItem(QLineF(p1, p2), self)) 
    157                 text_item = QGraphicsTextItem(self) 
    158                 text_item.setHtml('<center>' + str(t) + '</center>') 
    159                 text_item.setTextWidth(self.line.length() * step / (max-min)) 
    160                 text_item.setPos(label_pos) 
    161                 text_item.setRotation(-self.line.angle()) 
    162                 self.label_items.append(text_item) 
    163                 t = t + step             
     150        self.transform = QTransform().translate(-self.x(), -self.y()) * self.zoom_transform * QTransform().translate(self.x(), self.y()) 
     151        ratio = self.transform.map(self.line).length() / self.line.length() 
     152        qDebug('Axis zoom ratio = ' + str(ratio)) 
     153        for pos, text, size in self._ticks: 
     154            label_pos = self.map_to_graph( pos ) 
     155            test_rect = QRectF(self.line.p1(),  self.line.p2()).normalized() 
     156            test_rect.adjust(-1, -1, 1, 1) 
     157            if not test_rect.contains(label_pos): 
     158                qDebug('Skipping label ' + text) 
     159                continue 
     160            hs = 0.5*step 
     161            label_pos = self.map_to_graph(pos - hs) 
     162            item = QGraphicsTextItem(self) 
     163            item.setHtml( '<center>' + text.strip() + '</center>') 
     164            item.setTextWidth( QLineF(self.map_to_graph(pos - hs), self.map_to_graph(pos + hs) ).length() ) 
     165            v = self.line.normalVector().unitVector() 
     166            if self.title_above: 
     167                label_pos = label_pos + (v.p2() - v.p1())*40 
     168            item.setPos(label_pos) 
     169            item.setRotation(-self.line.angle()) 
     170            self.label_items.append(item) 
     171             
     172            item = QGraphicsLineItem(self) 
     173            tick_line = QLineF(v) 
     174            tick_line.translate(-tick_line.p1()) 
     175            tick_line.setLength(size) 
     176            if self.title_above: 
     177                tick_line.setAngle(tick_line.angle() + 180) 
     178            item.setLine( tick_line ) 
     179            qDebug('Adding tick at ' + str(pos)) 
     180            item.setPen(self.style.pen()) 
     181            item.setPos(self.map_to_graph(pos)) 
     182            self.tick_items.append(item) 
    164183        
    165184    @staticmethod 
     
    203222        min, max, step = self.scale 
    204223        line_point = self.line.pointAt( (x-min)/(max-min) ) 
    205         end_point = line_point * self.transform 
     224        end_point = line_point * self.zoom_transform 
    206225        return self.projection(end_point, self.line) 
    207226         
     
    213232        type = line.intersect(norm, p) 
    214233        return p 
     234         
     235    def continuous_labels(self): 
     236        min, max, step = self.scale 
     237        qDebug(' Step = ' + str(step)) 
     238        magnitude = log10(abs(max-min)) 
     239         
Note: See TracChangeset for help on using the changeset viewer.