NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

bargraph.py (8584B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\graphs\bargraph.py
      2 from carbonui.primitives.fill import Fill
      3 from carbonui.primitives.polygon import Polygon
      4 import carbonui.const as uiconst
      5 from carbonui.graphs import animations
      6 from carbonui.graphs.axis import AxisOrientation
      7 from carbonui.uicore import uicore
      8 from carbonui.util import colorblind
      9 from carbonui.util.color import Color
     10 
     11 class DynamicHint(object):
     12 
     13     def __init__(self, callback):
     14         self._callback = callback
     15 
     16     def __getitem__(self, item):
     17         return self._callback(item)
     18 
     19 
     20 class BarGraph(Polygon):
     21     default_name = 'BarGraph'
     22     default_state = uiconst.UI_NORMAL
     23     default_barSize = 7
     24 
     25     def ApplyAttributes(self, attributes):
     26         Polygon.ApplyAttributes(self, attributes)
     27         self._categoryAxis = attributes['categoryAxis']
     28         self._valueAxis = attributes['valueAxis']
     29         self._orientation = attributes.get('orientation', AxisOrientation.VERTICAL)
     30         self._categoryAxis.onChange.connect(self._AxisChanged)
     31         self._valueAxis.onChange.connect(self._AxisChanged)
     32         self._values = attributes['values']
     33         self._barColors = attributes.get('barColors', None)
     34         self._vertices = None
     35         self.barColor = self.GetRGBA()
     36         self.hoverColor = attributes.get('hoverColor', self.barColor)
     37         self.negativeColor = attributes.get('negativeColor', self.barColor)
     38         self.negativeHoverColor = attributes.get('negativeHoverColor', self.negativeColor)
     39         self.barSize = attributes.get('barSize', self.default_barSize)
     40         self.barSizeMinMax = attributes.get('barSizeMinMax', (self.barSize, self.barSize))
     41         self.color = (1, 1, 1, 1)
     42         self._locked = False
     43         self._dirty = False
     44         self._originalColor = self.color
     45         self._animation = None
     46         self._hoverIndex = None
     47         self._tooltipRect = None
     48         self._Build()
     49 
     50     def GetLegendItem(self):
     51         return Fill(name='legendVolume', color=self.barColor, align=uiconst.TOLEFT)
     52 
     53     @property
     54     def hint(self):
     55         h = getattr(self, '_hint', None)
     56         if not isinstance(h, basestring) and hasattr(h, '__getitem__'):
     57             return h[self._hoverIndex]
     58         return h
     59 
     60     @hint.setter
     61     def hint(self, value):
     62         Polygon.hint.fset(self, value)
     63 
     64     def GetTooltipPosition(self):
     65         return self._tooltipRect
     66 
     67     def Animate(self, animationType, animationDynamics, duration):
     68         self.CancelAnimation()
     69         self._animation = animations.CreateAnimation(self, self._categoryAxis, self._valueAxis, self._orientation, animationType, animationDynamics, duration, 4)
     70 
     71     def CancelAnimation(self, applyLastFrame = True):
     72         self.StopAnimations()
     73         self.opacity = 1.0
     74         if self._animation:
     75             self._animation.Cancel(applyLastFrame)
     76             self._animation = None
     77 
     78     def Close(self):
     79         self.CancelAnimation(False)
     80         super(BarGraph, self).Close()
     81         self._categoryAxis.onChange.disconnect(self._AxisChanged)
     82         self._valueAxis.onChange.disconnect(self._AxisChanged)
     83 
     84     def _Build(self):
     85         dpiScaling = uicore.desktop.dpiScaling
     86         barWidth = self._GetBarWidth()
     87         barWidth *= dpiScaling
     88         axisZero = self._valueAxis.MapToViewport(0) * dpiScaling
     89         positions = []
     90         colors = []
     91         triangles = []
     92         for i, (x, y, value) in enumerate(zip(self._categoryAxis.MapDataPointsToViewport(), self._valueAxis.MapSequenceToViewport(self._values), self._values)):
     93             x *= dpiScaling
     94             y *= dpiScaling
     95             color = self.GetBarColor(i, value)
     96             if self._orientation == AxisOrientation.VERTICAL:
     97                 positions.append((x - barWidth, y))
     98                 positions.append((x + barWidth, y))
     99                 positions.append((x + barWidth, axisZero))
    100                 positions.append((x - barWidth, axisZero))
    101             else:
    102                 positions.append((y, x - barWidth))
    103                 positions.append((y, x + barWidth))
    104                 positions.append((axisZero, x + barWidth))
    105                 positions.append((axisZero, x - barWidth))
    106             colors.append(color)
    107             colors.append(color)
    108             colors.append(color)
    109             colors.append(color)
    110             triangles.append((4 * i, 4 * i + 1, 4 * i + 2))
    111             triangles.append((4 * i + 2, 4 * i + 3, 4 * i))
    112 
    113         self.AppendVertices(positions, None, colors)
    114         self.renderObject.AppendTriangles(triangles)
    115         self.width = max((x[0] for x in positions))
    116         self.height = max((x[1] for x in positions))
    117 
    118     def _Rescale(self):
    119         dpiScaling = uicore.desktop.dpiScaling
    120         barWidth = self._GetBarWidth()
    121         barWidth *= dpiScaling
    122         axisZero = self._valueAxis.MapToViewport(0) * dpiScaling
    123         positions = []
    124         for i, (x, y) in enumerate(zip(self._categoryAxis.MapDataPointsToViewport(), self._valueAxis.MapSequenceToViewport(self._values))):
    125             x *= dpiScaling
    126             y *= dpiScaling
    127             if self._orientation == AxisOrientation.VERTICAL:
    128                 positions.append((x - barWidth, y))
    129                 positions.append((x + barWidth, y))
    130                 positions.append((x + barWidth, axisZero))
    131                 positions.append((x - barWidth, axisZero))
    132             else:
    133                 positions.append((y, x - barWidth))
    134                 positions.append((y, x + barWidth))
    135                 positions.append((axisZero, x + barWidth))
    136                 positions.append((axisZero, x - barWidth))
    137 
    138         self.renderObject.SetVertices(positions)
    139 
    140     def _GetBarWidth(self):
    141         barWidth = abs(self._categoryAxis.MapToViewport(0) - self._categoryAxis.MapToViewport(1)) - 1
    142         barWidth = min(max(barWidth, self.barSizeMinMax[0]), self.barSizeMinMax[1]) / 2.0
    143         return barWidth
    144 
    145     def _AxisChanged(self, _):
    146         if self._locked:
    147             self._dirty = True
    148         else:
    149             self._Rescale()
    150 
    151     def AddBarHighlight(self, barIndex):
    152         self._hoverIndex = barIndex
    153         color = self.GetBarHoverColor(barIndex, self._values[self._hoverIndex])
    154         self._SetBarColor(color)
    155 
    156     def _RemoveBarHighlight(self):
    157         if self._hoverIndex is None:
    158             return
    159         color = self.GetBarColor(self._hoverIndex, self._values[self._hoverIndex])
    160         self._SetBarColor(color)
    161         self._hoverIndex = None
    162 
    163     def _SetBarColor(self, color):
    164         color = colorblind.CheckReplaceColor(color)
    165         offset = self._hoverIndex * 4
    166         for each in range(4):
    167             self.renderObject.vertices[offset + each].color = color
    168 
    169         self.renderObject.SetDirty()
    170 
    171     def GetBarColor(self, barIdx, value):
    172         if self._barColors is None:
    173             if value < 0:
    174                 return self.negativeColor
    175             return self.barColor
    176         return self._barColors[barIdx]
    177 
    178     def GetBarHoverColor(self, barIdx, value):
    179         if self._barColors is None:
    180             if value < 0:
    181                 return self.negativeHoverColor
    182             return self.hoverColor
    183         else:
    184             barColor = self._barColors[barIdx]
    185             c = Color(*barColor)
    186             sat = c.GetSaturation()
    187             newSat = min(1.0, max(0.0, sat - 0.3))
    188             hoverColor = c.SetSaturation(newSat).GetRGBA()
    189             return hoverColor
    190 
    191     def OnMouseEnter(self, *args):
    192         index = self.FindMouseoverIndex()
    193         self._RemoveBarHighlight()
    194         self.AddBarHighlight(index)
    195         dpiScaling = uicore.desktop.dpiScaling
    196         offset = index * 4
    197         tl = self.renderObject.vertices[offset].position
    198         br = self.renderObject.vertices[offset + 2].position
    199         pos = self.GetAbsolutePosition()
    200         self._tooltipRect = (tl[0] / dpiScaling + pos[0],
    201          tl[1] / dpiScaling + pos[1],
    202          br[0] / dpiScaling - tl[0] / dpiScaling,
    203          br[1] / dpiScaling - tl[1] / dpiScaling)
    204 
    205     def FindMouseoverIndex(self):
    206         if self._orientation == AxisOrientation.VERTICAL:
    207             x = uicore.uilib.x - self.GetAbsoluteLeft()
    208         else:
    209             x = uicore.uilib.y - self.GetAbsoluteTop()
    210         x = self._categoryAxis.MapFromViewport(x)
    211         index = int(round(x))
    212         return index
    213 
    214     def OnMouseExit(self, *args):
    215         self._RemoveBarHighlight()
    216 
    217     def LockGraphUpdates(self):
    218         self._locked = True
    219 
    220     def UnlockGraphUpdates(self):
    221         if self._locked:
    222             self._locked = False
    223             if self._dirty:
    224                 self._Rescale()