Style changes and a minor bug fix

This commit is contained in:
Luke Campagnola 2014-03-29 11:31:23 -04:00
parent 8c0940555a
commit 26c57a0f14
2 changed files with 102 additions and 98 deletions

View File

@ -33,7 +33,6 @@ class AxisItem(GraphicsWidget):
GraphicsWidget.__init__(self, parent) GraphicsWidget.__init__(self, parent)
self.label = QtGui.QGraphicsTextItem(self) self.label = QtGui.QGraphicsTextItem(self)
self.showValues = showValues
self.picture = None self.picture = None
self.orientation = orientation self.orientation = orientation
if orientation not in ['left', 'right', 'top', 'bottom']: if orientation not in ['left', 'right', 'top', 'bottom']:
@ -53,7 +52,8 @@ class AxisItem(GraphicsWidget):
(2, 0.6), ## If we already have 2 ticks with text, fill no more than 60% of the axis (2, 0.6), ## If we already have 2 ticks with text, fill no more than 60% of the axis
(4, 0.4), ## If we already have 4 ticks with text, fill no more than 40% of the axis (4, 0.4), ## If we already have 4 ticks with text, fill no more than 40% of the axis
(6, 0.2), ## If we already have 6 ticks with text, fill no more than 20% of the axis (6, 0.2), ## If we already have 6 ticks with text, fill no more than 20% of the axis
] ],
'showValues': showValues,
} }
self.textWidth = 30 ## Keeps track of maximum width / height of tick text self.textWidth = 30 ## Keeps track of maximum width / height of tick text
@ -242,31 +242,31 @@ class AxisItem(GraphicsWidget):
"""Set the height of this axis reserved for ticks and tick labels. """Set the height of this axis reserved for ticks and tick labels.
The height of the axis label is automatically added.""" The height of the axis label is automatically added."""
if h is None: if h is None:
h = 0 if not self.style['showValues']:
if self.showValues: h = 0
if self.style['autoExpandTextSpace'] is True: elif self.style['autoExpandTextSpace'] is True:
h = self.textHeight h = self.textHeight
else: else:
h = self.style['tickTextHeight'] h = self.style['tickTextHeight']
h += max(0, self.tickLength) + self.style['tickTextOffset'][1] textOffset = self.style['tickTextOffset'][1] if self.style['showValues'] else 0
h += max(0, self.tickLength) + textOffset
if self.label.isVisible(): if self.label.isVisible():
h += self.label.boundingRect().height() * 0.8 h += self.label.boundingRect().height() * 0.8
self.setMaximumHeight(h) self.setMaximumHeight(h)
self.setMinimumHeight(h) self.setMinimumHeight(h)
self.picture = None self.picture = None
def setWidth(self, w=None): def setWidth(self, w=None):
"""Set the width of this axis reserved for ticks and tick labels. """Set the width of this axis reserved for ticks and tick labels.
The width of the axis label is automatically added.""" The width of the axis label is automatically added."""
if w is None: if w is None:
w = 0 if not self.style['showValues']:
if self.showValues: w = 0
if self.style['autoExpandTextSpace'] is True: elif self.style['autoExpandTextSpace'] is True:
w = self.textWidth w = self.textWidth
else: else:
w = self.style['tickTextWidth'] w = self.style['tickTextWidth']
w += max(0, self.tickLength) + self.style['tickTextOffset'][0] textOffset = self.style['tickTextOffset'][0] if self.style['showValues'] else 0
if self.label.isVisible(): if self.label.isVisible():
w += self.label.boundingRect().height() * 0.8 ## bounding rect is usually an overestimate w += self.label.boundingRect().height() * 0.8 ## bounding rect is usually an overestimate
self.setMaximumWidth(w) self.setMaximumWidth(w)
@ -779,89 +779,93 @@ class AxisItem(GraphicsWidget):
textSize2 = 0 textSize2 = 0
textRects = [] textRects = []
textSpecs = [] ## list of draw textSpecs = [] ## list of draw
if self.showValues:
for i in range(len(tickLevels)): # If values are hidden, return early
## Get the list of strings to display for this level if not self.style['showValues']:
if tickStrings is None: return (axisSpec, tickSpecs, textSpecs)
spacing, values = tickLevels[i]
strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing) for i in range(len(tickLevels)):
## Get the list of strings to display for this level
if tickStrings is None:
spacing, values = tickLevels[i]
strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing)
else:
strings = tickStrings[i]
if len(strings) == 0:
continue
## ignore strings belonging to ticks that were previously ignored
for j in range(len(strings)):
if tickPositions[i][j] is None:
strings[j] = None
## Measure density of text; decide whether to draw this level
rects = []
for s in strings:
if s is None:
rects.append(None)
else: else:
strings = tickStrings[i] br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s))
## boundingRect is usually just a bit too large
## (but this probably depends on per-font metrics?)
br.setHeight(br.height() * 0.8)
if len(strings) == 0: rects.append(br)
continue textRects.append(rects[-1])
## ignore strings belonging to ticks that were previously ignored if i > 0: ## always draw top level
for j in range(len(strings)): ## measure all text, make sure there's enough room
if tickPositions[i][j] is None: if axis == 0:
strings[j] = None textSize = np.sum([r.height() for r in textRects])
textSize2 = np.max([r.width() for r in textRects]) if textRects else 0
else:
textSize = np.sum([r.width() for r in textRects])
textSize2 = np.max([r.height() for r in textRects]) if textRects else 0
## Measure density of text; decide whether to draw this level ## If the strings are too crowded, stop drawing text now.
rects = [] ## We use three different crowding limits based on the number
for s in strings: ## of texts drawn so far.
if s is None: textFillRatio = float(textSize) / lengthInPixels
rects.append(None) finished = False
else: for nTexts, limit in self.style['textFillLimits']:
br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s)) if len(textSpecs) >= nTexts and textFillRatio >= limit:
## boundingRect is usually just a bit too large finished = True
## (but this probably depends on per-font metrics?)
br.setHeight(br.height() * 0.8)
rects.append(br)
textRects.append(rects[-1])
if i > 0: ## always draw top level
## measure all text, make sure there's enough room
if axis == 0:
textSize = np.sum([r.height() for r in textRects])
textSize2 = np.max([r.width() for r in textRects]) if textRects else 0
else:
textSize = np.sum([r.width() for r in textRects])
textSize2 = np.max([r.height() for r in textRects]) if textRects else 0
## If the strings are too crowded, stop drawing text now.
## We use three different crowding limits based on the number
## of texts drawn so far.
textFillRatio = float(textSize) / lengthInPixels
finished = False
for nTexts, limit in self.style['textFillLimits']:
if len(textSpecs) >= nTexts and textFillRatio >= limit:
finished = True
break
if finished:
break break
if finished:
break
#spacing, values = tickLevels[best] #spacing, values = tickLevels[best]
#strings = self.tickStrings(values, self.scale, spacing) #strings = self.tickStrings(values, self.scale, spacing)
for j in range(len(strings)): for j in range(len(strings)):
vstr = strings[j] vstr = strings[j]
if vstr is None: ## this tick was ignored because it is out of bounds if vstr is None: ## this tick was ignored because it is out of bounds
continue continue
vstr = asUnicode(vstr) vstr = asUnicode(vstr)
x = tickPositions[i][j] x = tickPositions[i][j]
#textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr) #textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr)
textRect = rects[j] textRect = rects[j]
height = textRect.height() height = textRect.height()
width = textRect.width() width = textRect.width()
#self.textHeight = height #self.textHeight = height
offset = max(0,self.tickLength) + textOffset offset = max(0,self.tickLength) + textOffset
if self.orientation == 'left': if self.orientation == 'left':
textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter
rect = QtCore.QRectF(tickStop-offset-width, x-(height/2), width, height) rect = QtCore.QRectF(tickStop-offset-width, x-(height/2), width, height)
elif self.orientation == 'right': elif self.orientation == 'right':
textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter
rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height) rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height)
elif self.orientation == 'top': elif self.orientation == 'top':
textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom
rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height) rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height)
elif self.orientation == 'bottom': elif self.orientation == 'bottom':
textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop
rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height) rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height)
#p.setPen(self.pen()) #p.setPen(self.pen())
#p.drawText(rect, textFlags, vstr) #p.drawText(rect, textFlags, vstr)
textSpecs.append((rect, textFlags, vstr)) textSpecs.append((rect, textFlags, vstr))
profiler('compute text') profiler('compute text')
## update max text size if needed. ## update max text size if needed.
self._updateMaxTextSize(textSize2) self._updateMaxTextSize(textSize2)

View File

@ -58,7 +58,7 @@ class HistogramLUTItem(GraphicsWidget):
self.region = LinearRegionItem([0, 1], LinearRegionItem.Horizontal) self.region = LinearRegionItem([0, 1], LinearRegionItem.Horizontal)
self.region.setZValue(1000) self.region.setZValue(1000)
self.vb.addItem(self.region) self.vb.addItem(self.region)
self.axis = AxisItem('left', linkView=self.vb, maxTickLength=-10, showValues=False) self.axis = AxisItem('left', linkView=self.vb, maxTickLength=-10)
self.layout.addItem(self.axis, 0, 0) self.layout.addItem(self.axis, 0, 0)
self.layout.addItem(self.vb, 0, 1) self.layout.addItem(self.vb, 0, 1)
self.layout.addItem(self.gradient, 0, 2) self.layout.addItem(self.gradient, 0, 2)