From 2a04e60ae0041e98d49300538f25fd4a70a946b1 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 17 May 2019 18:44:52 +0300 Subject: [PATCH] Restore functionality of dmg vs time graph --- eos/graph/__init__.py | 8 +- eos/graph/{fitDmgTime.py => fitDmgVsTime.py} | 63 +++++++++------ gui/builtinGraphs/__init__.py | 2 +- gui/builtinGraphs/fitDmgTime.py | 82 -------------------- gui/builtinGraphs/fitDmgVsTime.py | 43 ++++++++++ gui/graph.py | 14 ++-- gui/graphFrame.py | 2 + 7 files changed, 97 insertions(+), 117 deletions(-) rename eos/graph/{fitDmgTime.py => fitDmgVsTime.py} (71%) delete mode 100644 gui/builtinGraphs/fitDmgTime.py create mode 100644 gui/builtinGraphs/fitDmgVsTime.py diff --git a/eos/graph/__init__.py b/eos/graph/__init__.py index 59fd0dc61..5f1699628 100644 --- a/eos/graph/__init__.py +++ b/eos/graph/__init__.py @@ -47,11 +47,11 @@ class Graph(metaclass=ABCMeta): yield current current += step - def clearCache(self, fitID=None): - if fitID is None: + def clearCache(self, key=None): + if key is None: self.cache.clear() - elif fitID in self.cache: - del self.cache[fitID] + elif key in self.cache: + del self.cache[key] class SmoothGraph(Graph, metaclass=ABCMeta): diff --git a/eos/graph/fitDmgTime.py b/eos/graph/fitDmgVsTime.py similarity index 71% rename from eos/graph/fitDmgTime.py rename to eos/graph/fitDmgVsTime.py index df510daf2..1d8aba564 100644 --- a/eos/graph/fitDmgTime.py +++ b/eos/graph/fitDmgVsTime.py @@ -17,49 +17,62 @@ # along with eos. If not, see . # =============================================================================== -from logbook import Logger from eos.graph import Graph from eos.utils.spoolSupport import SpoolType, SpoolOptions -pyfalog = Logger(__name__) +class FitDmgVsTimeGraph(Graph): + def getPlotPoints(self, fit, extraData, xRange, xAmount): + # We deliberately ignore xAmount here to build graph which will reflect + # all steps of building up the damage + maxTime = xRange[1] + if fit.ID not in self.cache: + self.__generateCache(fit, maxTime) + currentY = 0 + xs = [0] + ys = [0] + cache = self.cache[fit.ID] + for time in sorted(cache): + prevY = currentY + currentX = time / 1000 + currentY = cache[time] + if currentY != prevY: + xs.append(currentX) + ys.append(prevY) + xs.append(currentX) + ys.append(currentY) + if maxTime > max(xs): + xs.append(maxTime) + ys.append(ys[-1]) + return xs, ys -class FitDmgTimeGraph(Graph): - - defaults = {"time": 0} - - def __init__(self, fit, data=None): - Graph.__init__(self, fit, self.calcDmg, data if data is not None else self.defaults) - self.fit = fit - self.__cache = {} - - def calcDmg(self, data): - time = data["time"] * 1000 - closestTime = max((t for t in self.__cache if t <= time), default=None) + def getYForX(self, fit, extraData, x): + time = x * 1000 + cache = self.cache[fit.ID] + closestTime = max((t for t in cache if t <= time), default=None) if closestTime is None: return 0 - return self.__cache[closestTime] + return cache[closestTime] - def recalc(self): + def __generateCache(self, fit, maxTime): + cache = self.cache[fit.ID] = {} def addDmg(addedTime, addedDmg): if addedDmg == 0: return - if addedTime not in self.__cache: - prevTime = max((t for t in self.__cache if t < addedTime), default=None) + if addedTime not in cache: + prevTime = max((t for t in cache if t < addedTime), default=None) if prevTime is None: - self.__cache[addedTime] = 0 + cache[addedTime] = 0 else: - self.__cache[addedTime] = self.__cache[prevTime] - for time in (t for t in self.__cache if t >= addedTime): - self.__cache[time] += addedDmg + cache[addedTime] = cache[prevTime] + for time in (t for t in cache if t >= addedTime): + cache[time] += addedDmg - self.__cache.clear() - fit = self.fit # We'll handle calculations in milliseconds - maxTime = self.data["time"].data[0].end * 1000 + maxTime = maxTime * 1000 for mod in fit.modules: cycleParams = mod.getCycleParameters(reloadOverride=True) if cycleParams is None: diff --git a/gui/builtinGraphs/__init__.py b/gui/builtinGraphs/__init__.py index feeb1efa2..a6ad555da 100644 --- a/gui/builtinGraphs/__init__.py +++ b/gui/builtinGraphs/__init__.py @@ -2,7 +2,7 @@ from gui.builtinGraphs import ( # noqa: E402,F401 # fitDpsRange, # fitDpsTime, - # fitDmgTime, + fitDmgVsTime, # fitShieldRegenAmount, # fitShieldAmountTime, fitCapRegenVsCapPerc, diff --git a/gui/builtinGraphs/fitDmgTime.py b/gui/builtinGraphs/fitDmgTime.py deleted file mode 100644 index 43e475487..000000000 --- a/gui/builtinGraphs/fitDmgTime.py +++ /dev/null @@ -1,82 +0,0 @@ -# ============================================================================= -# Copyright (C) 2010 Diego Duclos -# -# This file is part of pyfa. -# -# pyfa is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# pyfa is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with pyfa. If not, see . -# ============================================================================= - -import gui.mainFrame -from eos.graph import Data -from eos.graph.fitDmgTime import FitDmgTimeGraph as EosFitDmgTimeGraph -from gui.bitmap_loader import BitmapLoader -from gui.graph import Graph -from service.attribute import Attribute - - -class FitDmgTimeGraph(Graph): - - propertyLabelMap = {"time": "Time (seconds)"} - - defaults = EosFitDmgTimeGraph.defaults.copy() - - def __init__(self): - Graph.__init__(self) - self.defaults["time"] = "0-80" - self.name = "Damage Inflicted vs Time" - self.eosGraph = None - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - def getFields(self): - return self.defaults - - def getLabels(self): - return self.propertyLabelMap - - def getIcons(self): - iconFile = Attribute.getInstance().getAttributeInfo('duration').iconID - bitmap = BitmapLoader.getBitmap(iconFile, "icons") - return {"time": bitmap} - - def getPoints(self, fit, fields): - eosGraph = getattr(self, "eosGraph", None) - if eosGraph is None or eosGraph.fit != fit: - eosGraph = self.eosGraph = EosFitDmgTimeGraph(fit) - - eosGraph.clearData() - variable = None - for fieldName, value in fields.items(): - d = Data(fieldName, value) - if not d.isConstant(): - if variable is None: - variable = fieldName - else: - # We can't handle more then one variable atm, OOPS FUCK OUT - return False, "Can only handle 1 variable" - - eosGraph.setData(d) - - if variable is None: - return False, "No variable" - - x = [] - y = [] - eosGraph.recalc() - for point, val in eosGraph.getIterator(): - x.append(point[variable]) - y.append(val) - return x, y - - -FitDmgTimeGraph.register() diff --git a/gui/builtinGraphs/fitDmgVsTime.py b/gui/builtinGraphs/fitDmgVsTime.py new file mode 100644 index 000000000..21f02e0ef --- /dev/null +++ b/gui/builtinGraphs/fitDmgVsTime.py @@ -0,0 +1,43 @@ +# ============================================================================= +# Copyright (C) 2010 Diego Duclos +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +# ============================================================================= + + +from collections import OrderedDict + +from eos.graph.fitDmgVsTime import FitDmgVsTimeGraph as EosGraphDmg +from gui.graph import Graph, XDef, YDef + + +class FitDmgVsTimeGraph(Graph): + + name = 'Damage vs Time' + + def __init__(self): + self.eosGraphDmg = EosGraphDmg() + + @property + def xDef(self): + return XDef(inputDefault='0-80', inputLabel='Time (seconds)', inputIconID=1392, axisLabel='Time, s') + + @property + def yDefs(self): + return OrderedDict([('damage', YDef(switchLabel='Damage inflicted', axisLabel='Damage', eosGraph='eosGraphDmg'))]) + + +FitDmgVsTimeGraph.register() diff --git a/gui/graph.py b/gui/graph.py index 7b75d4688..8e555002c 100644 --- a/gui/graph.py +++ b/gui/graph.py @@ -64,12 +64,16 @@ class Graph(metaclass=ABCMeta): m = re.match('\s*(?P\d+(\.\d+)?)\s*(-\s*(?P\d+(\.\d+)?))?', string) if m is None: return (0, 0) - first = m.group('first') + first = float(m.group('first')) second = m.group('second') - if not second: - return (0, float(first)) - else: - return (float(first), float(second)) + second = float(second) if second is not None else 0 + low = min(first, second) + high = max(first, second) + return (low, high) + + def clearCache(self, *args, **kwargs): + for yDef in self.yDefs.values(): + getattr(self, yDef.eosGraph).clearCache(*args, **kwargs) XDef = namedtuple('XDef', ('inputDefault', 'inputLabel', 'inputIconID', 'axisLabel')) diff --git a/gui/graphFrame.py b/gui/graphFrame.py index dcbf9b884..a2cf09dd3 100644 --- a/gui/graphFrame.py +++ b/gui/graphFrame.py @@ -286,6 +286,8 @@ class GraphFrame(wx.Frame): values = self.getValues() view = self.getView() + # todo: we just drop cache so far, need to drop it only for removed/changed fits + view.clearCache() self.subplot.clear() self.subplot.grid(True) legend = []