pointgraph.py (10588B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\graphs\pointgraph.py 2 from itertools import izip 3 import trinity 4 from carbonui import uiconst 5 from carbonui.primitives.polygon import Polygon 6 from carbonui.primitives.sprite import Sprite 7 from carbonui.graphs import animations 8 from carbonui.graphs.axis import AxisOrientation 9 from carbonui.uicore import uicore 10 from carbonui.util import colorblind 11 from carbonui.util.color import Color 12 13 class PointGraph(Polygon): 14 default_state = uiconst.UI_NORMAL 15 default_pointSize = 7 16 default_pointColor = (0.2, 0.54, 1.0, 1.0) 17 default_texturePath = 'res:/UI/Texture/classes/graph/point.png' 18 default_spriteEffect = trinity.TR2_SFX_COPY 19 default_hoverColor = Color.GRAY8 20 default_hideZero = False 21 22 def ApplyAttributes(self, attributes): 23 Polygon.ApplyAttributes(self, attributes) 24 self.hideZero = attributes.get('hideZero', self.default_hideZero) 25 self._categoryAxis = attributes['categoryAxis'] 26 self._valueAxis = attributes['valueAxis'] 27 self._orientation = attributes.get('orientation', AxisOrientation.VERTICAL) 28 self._categoryAxis.onChange.connect(self._AxisChanged) 29 self._valueAxis.onChange.connect(self._AxisChanged) 30 self._values = attributes['values'] 31 self.pointColor = attributes.get('pointColor', (1, 1, 1, 1)) 32 self.hoverColor = attributes.get('hoverColor', self.default_hoverColor) 33 self.pointSize = attributes.get('pointSize', self.default_pointSize) 34 self.pointSizeMinMax = attributes.get('pointSizeMinMax', (self.pointSize, self.pointSize)) 35 self.color = (1, 1, 1, 1) 36 self._locked = False 37 self._dirty = False 38 self._originalColor = self.color 39 self._animation = None 40 self._hoverIndex = None 41 self._tooltipRect = None 42 self._Build() 43 44 def GetLegendItem(self): 45 return Sprite(name='legendPoint', texturePath=self.texturePath, color=self.pointColor, size=(16, 16), align=uiconst.TOLEFT) 46 47 @property 48 def hint(self): 49 if self._hoverIndex is None: 50 return 51 h = getattr(self, '_hint', None) 52 if not isinstance(h, basestring) and hasattr(h, '__getitem__'): 53 return h[self._hoverIndex] 54 return h 55 56 @hint.setter 57 def hint(self, value): 58 Polygon.hint.fset(self, value) 59 60 def GetTooltipPosition(self): 61 return self._tooltipRect 62 63 def Animate(self, animationType, animationDynamics, duration): 64 self.CancelAnimation() 65 self._animation = animations.CreateAnimation(self, self._categoryAxis, self._valueAxis, self._orientation, animationType, animationDynamics, duration, 4) 66 67 def CancelAnimation(self, applyLastFrame = True): 68 self.StopAnimations() 69 self.opacity = 1.0 70 if self._animation: 71 self._animation.Cancel(applyLastFrame) 72 self._animation = None 73 74 def Close(self): 75 try: 76 self.CancelAnimation(False) 77 self._categoryAxis.onChange.disconnect(self._AxisChanged) 78 self._valueAxis.onChange.disconnect(self._AxisChanged) 79 finally: 80 super(PointGraph, self).Close() 81 82 def _Build(self): 83 dpiScaling = uicore.desktop.dpiScaling 84 pointSize2 = self._GetPointSize() 85 positions = [] 86 if self._orientation == AxisOrientation.VERTICAL: 87 for x, y, value in zip(self._categoryAxis.MapDataPointsToViewport(), self._valueAxis.MapSequenceToViewport(self._values), self._values): 88 thisPointSize = self.GetPointSizeForValue(value, pointSize2) 89 x *= dpiScaling 90 y *= dpiScaling 91 positions.append((x - thisPointSize, y - thisPointSize)) 92 positions.append((x + thisPointSize, y - thisPointSize)) 93 positions.append((x + thisPointSize, y + thisPointSize)) 94 positions.append((x - thisPointSize, y + thisPointSize)) 95 96 else: 97 for y, x, value in zip(self._categoryAxis.MapDataPointsToViewport(), self._valueAxis.MapSequenceToViewport(self._values), self._values): 98 thisPointSize = self.GetPointSizeForValue(value, pointSize2) 99 x *= dpiScaling 100 y *= dpiScaling 101 positions.append((x - thisPointSize, y - thisPointSize)) 102 positions.append((x + thisPointSize, y - thisPointSize)) 103 positions.append((x + thisPointSize, y + thisPointSize)) 104 positions.append((x - thisPointSize, y + thisPointSize)) 105 106 texcoords = ((0, 0), 107 (1, 0), 108 (1, 1), 109 (0, 1)) * len(self._values) 110 triangles = [] 111 triangles.extend(((i, i + 1, i + 2) for i in xrange(0, len(self._values) * 4, 4))) 112 triangles.extend(((i + 2, i + 3, i) for i in xrange(0, len(self._values) * 4, 4))) 113 self.AppendVertices(positions, None, self.GetPointColors(), texcoords) 114 self.renderObject.AppendTriangles(triangles) 115 116 def GetPointColors(self): 117 return self.pointColor 118 119 def GetPointSizeForValue(self, value, defaultSize): 120 if self.hideZero and value == 0: 121 return 0 122 return defaultSize 123 124 def _Rescale(self): 125 self.CancelAnimation() 126 self._RemoveBarHighlight() 127 dpiScaling = uicore.desktop.dpiScaling 128 pointSize2 = self._GetPointSize() 129 positions = [] 130 append = positions.append 131 if self._orientation == AxisOrientation.VERTICAL: 132 for x, y, value in izip(self._categoryAxis.MapDataPointsToViewport(), self._valueAxis.MapSequenceToViewport(self._values), self._values): 133 thisPointSize = self.GetPointSizeForValue(value, pointSize2) 134 x *= dpiScaling 135 y *= dpiScaling 136 xl = x - thisPointSize 137 xr = x + thisPointSize 138 yl = y - thisPointSize 139 yr = y + thisPointSize 140 append((xl, yl)) 141 append((xr, yl)) 142 append((xr, yr)) 143 append((xl, yr)) 144 145 else: 146 for y, x, value in izip(self._categoryAxis.MapDataPointsToViewport(), self._valueAxis.MapSequenceToViewport(self._values), self._values): 147 thisPointSize = self.GetPointSizeForValue(value, pointSize2) 148 x *= dpiScaling 149 y *= dpiScaling 150 xl = x - thisPointSize 151 xr = x + thisPointSize 152 yl = y - thisPointSize 153 yr = y + thisPointSize 154 append((xl, yl)) 155 append((xr, yl)) 156 append((xr, yr)) 157 append((xl, yr)) 158 159 self.renderObject.SetVertices(positions) 160 161 def _GetPointSize(self): 162 barWidth = abs(self._categoryAxis.MapToViewport(0) - self._categoryAxis.MapToViewport(1)) 163 barWidth = min(max(barWidth, self.pointSizeMinMax[0]), self.pointSizeMinMax[1]) / 2.0 164 return barWidth 165 166 def _AxisChanged(self, _): 167 if self._locked: 168 self._dirty = True 169 else: 170 self._Rescale() 171 172 def _RemoveBarHighlight(self): 173 if self._hoverIndex is None: 174 return 175 self._SetBarColor(self._GetPointColor(self._hoverIndex), -float(self.pointSize) / 4) 176 self._hoverIndex = None 177 178 def _GetPointColor(self, index): 179 return self.pointColor 180 181 def _SetBarColor(self, color, sizeInc): 182 color = colorblind.CheckReplaceColor(color) 183 offset = self._hoverIndex * 4 184 resize = ((-sizeInc, -sizeInc), 185 (sizeInc, -sizeInc), 186 (sizeInc, sizeInc), 187 (-sizeInc, sizeInc)) 188 for each in xrange(4): 189 v = self.renderObject.vertices[offset + each] 190 v.position = (v.position[0] + resize[each][0], v.position[1] + resize[each][1]) 191 v.color = color 192 193 self.renderObject.SetDirty() 194 195 def OnMouseEnter(self, *args): 196 indexOfPoint = self.GetIndexOfMousedOverPoint() 197 self.HilitePoint(indexOfPoint) 198 offset = indexOfPoint * 4 199 topLeft = self.renderObject.vertices[offset].position 200 bottomRight = self.renderObject.vertices[offset + 2].position 201 graphAbsLeft, graphAbsTop = self.GetAbsolutePosition() 202 dpiScaling = uicore.desktop.dpiScaling 203 tooltipAreaLeft = topLeft[0] / dpiScaling + graphAbsLeft 204 tooltipAreaTop = topLeft[1] / dpiScaling + graphAbsTop 205 tooltipAreaWidth = bottomRight[0] / dpiScaling - topLeft[0] / dpiScaling 206 tooltipAreaHeight = bottomRight[1] / dpiScaling - topLeft[1] / dpiScaling 207 self._tooltipRect = (tooltipAreaLeft, 208 tooltipAreaTop, 209 tooltipAreaWidth, 210 tooltipAreaHeight) 211 212 def GetIndexOfMousedOverPoint(self): 213 if self._orientation == AxisOrientation.VERTICAL: 214 x = uicore.uilib.x - self.GetAbsoluteLeft() 215 else: 216 x = uicore.uilib.y - self.GetAbsoluteTop() 217 x = self._categoryAxis.MapFromViewport(x) 218 indexOfPoint = int(x) 219 dpiScaling = uicore.desktop.dpiScaling 220 graphAbsLeft, graphAbsTop = self.GetAbsolutePosition() 221 startPoint = max(0, indexOfPoint - 5) 222 for tryIndex in xrange(startPoint, startPoint + 10): 223 offset = tryIndex * 4 224 if len(self.renderObject.vertices) <= offset + 2: 225 return indexOfPoint 226 topLeft = self.renderObject.vertices[offset].position 227 bottomRight = self.renderObject.vertices[offset + 2].position 228 tooltipAreaLeft = topLeft[0] / dpiScaling + graphAbsLeft 229 tooltipAreaTop = topLeft[1] / dpiScaling + graphAbsTop 230 tooltipAreaRight = bottomRight[0] / dpiScaling + graphAbsLeft 231 tooltipAreaBottom = bottomRight[1] / dpiScaling + graphAbsTop 232 if tooltipAreaLeft <= uicore.uilib.x <= tooltipAreaRight and tooltipAreaTop <= uicore.uilib.y <= tooltipAreaBottom: 233 return tryIndex 234 235 return indexOfPoint 236 237 def SetValues(self, values): 238 self._values = values 239 240 def HilitePoint(self, index): 241 self._RemoveBarHighlight() 242 self._hoverIndex = index 243 if index is not None: 244 self._SetBarColor(self.hoverColor, float(self.pointSize) / 4) 245 246 def OnMouseExit(self, *args): 247 self._RemoveBarHighlight() 248 249 def LockGraphUpdates(self): 250 self._locked = True 251 252 def UnlockGraphUpdates(self): 253 if self._locked: 254 self._locked = False 255 if self._dirty: 256 self._Rescale()