Add graphing support into pyfa (first iteration, very basic)
This commit is contained in:
2
eos
2
eos
Submodule eos updated: e9c7fe1c4c...e04c5588ba
1
gui/builtinGraphs/__init__.py
Executable file
1
gui/builtinGraphs/__init__.py
Executable file
@@ -0,0 +1 @@
|
||||
__all__ = ["fitDps"]
|
||||
93
gui/builtinGraphs/fitDps.py
Executable file
93
gui/builtinGraphs/fitDps.py
Executable file
@@ -0,0 +1,93 @@
|
||||
#===============================================================================
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from gui.graph import Graph
|
||||
import service
|
||||
from gui import bitmapLoader
|
||||
from eos.graph.fitDps import FitDpsGraph as FitDps
|
||||
from eos.graph import Data
|
||||
import gui.mainFrame
|
||||
import service
|
||||
|
||||
class FitDpsGraph(Graph):
|
||||
propertyAttributeMap = {"transversal": "maxVelocity",
|
||||
"distance": "maxRange",
|
||||
"signatureRadius": "signatureRadius",
|
||||
"velocity": "maxVelocity"}
|
||||
|
||||
propertyLabelMap = {"transversal": "Transversal Speed:",
|
||||
"distance": "Distance to Target:",
|
||||
"signatureRadius": "Target Signature Radius:",
|
||||
"velocity": "Target Velocity:"}
|
||||
|
||||
def __init__(self):
|
||||
Graph.__init__(self)
|
||||
self.name = "DPS"
|
||||
self.fitDps = None
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def getFields(self):
|
||||
return FitDps.defaults
|
||||
|
||||
def getLabels(self):
|
||||
return self.propertyLabelMap
|
||||
|
||||
def getIcons(self):
|
||||
icons = {}
|
||||
sFit = service.Attribute.getInstance()
|
||||
for key, attrName in self.propertyAttributeMap.iteritems():
|
||||
iconFile = sFit.getAttributeInfo(attrName).icon.iconFile
|
||||
bitmap = bitmapLoader.getBitmap(iconFile, "pack")
|
||||
if bitmap:
|
||||
icons[key] = bitmap
|
||||
|
||||
return icons
|
||||
|
||||
def getPoints(self, fields):
|
||||
sFit = service.Fit.getInstance()
|
||||
fit = sFit.getFit(self.mainFrame.getActiveFit())
|
||||
fitDps = getattr(self, "fitDps", None)
|
||||
if fitDps is None or fitDps.fit != fit:
|
||||
fitDps = self.fitDps = FitDps(fit)
|
||||
|
||||
fitDps.clearData()
|
||||
variable = None
|
||||
for fieldName, value in fields.iteritems():
|
||||
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"
|
||||
|
||||
fitDps.setData(d)
|
||||
|
||||
if variable is None:
|
||||
return False, "No variable"
|
||||
|
||||
x = []
|
||||
y = []
|
||||
for point, val in fitDps.getIterator():
|
||||
x.append(point[variable])
|
||||
y.append(val)
|
||||
|
||||
return x, y
|
||||
|
||||
FitDpsGraph.register()
|
||||
36
gui/graph.py
Executable file
36
gui/graph.py
Executable file
@@ -0,0 +1,36 @@
|
||||
#===============================================================================
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
class Graph(object):
|
||||
views = []
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
Graph.views.append(cls)
|
||||
|
||||
def __init__(self):
|
||||
self.name = ""
|
||||
|
||||
def getFields(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def getIcons(self):
|
||||
return None
|
||||
|
||||
from gui.builtinGraphs import *
|
||||
@@ -20,21 +20,113 @@
|
||||
import wx
|
||||
try:
|
||||
import matplotlib as mpl
|
||||
mpl.use('wxagg')
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
|
||||
from matplotlib.figure import Figure
|
||||
import mpl_toolkits.axisartist as AA
|
||||
enabled = True
|
||||
except:
|
||||
print "problems importing matplotlib, continueing without graphs"
|
||||
Enabled = False
|
||||
|
||||
from gui.graph import Graph
|
||||
from gui import bitmapLoader
|
||||
|
||||
class GraphFrame(wx.Frame):
|
||||
def __init__(self, parent):
|
||||
wx.Frame.__init__(self, parent)
|
||||
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||
wx.Frame.__init__(self, parent, style=style)
|
||||
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.SetSizer(self.mainSizer)
|
||||
|
||||
self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
|
||||
self.mainSizer.Add(self.graphSelection, 0, wx.EXPAND)
|
||||
|
||||
self.figure = mpl.figure.Figure(figsize=(4,2))
|
||||
self.figure = Figure(figsize=(4, 3))
|
||||
self.canvas = Canvas(self, -1, self.figure)
|
||||
self.subplot = self.figure.add_subplot(111)
|
||||
|
||||
self.mainSizer.Add(self.canvas, 0, wx.EXPAND)
|
||||
|
||||
self.gridPanel = wx.Panel(self)
|
||||
self.mainSizer.Add(self.gridPanel, 1, wx.EXPAND)
|
||||
|
||||
dummyBox = wx.BoxSizer(wx.VERTICAL)
|
||||
self.gridPanel.SetSizer(dummyBox)
|
||||
|
||||
self.gridSizer = wx.FlexGridSizer(0, 3)
|
||||
self.gridSizer.AddGrowableCol(2)
|
||||
dummyBox.Add(self.gridSizer, 0, wx.EXPAND)
|
||||
|
||||
for view in Graph.views:
|
||||
view = view()
|
||||
self.graphSelection.Append(view.name, view)
|
||||
|
||||
self.graphSelection.SetSelection(0)
|
||||
self.fields = {}
|
||||
self.select(0)
|
||||
|
||||
def getView(self):
|
||||
return self.graphSelection.GetClientData(self.graphSelection.GetSelection())
|
||||
|
||||
def getValues(self):
|
||||
values = {}
|
||||
for fieldName, field in self.fields.iteritems():
|
||||
values[fieldName] = field.GetLabel()
|
||||
|
||||
return values
|
||||
|
||||
def select(self, index):
|
||||
view = self.getView()
|
||||
icons = view.getIcons()
|
||||
labels = view.getLabels()
|
||||
sizer = self.gridSizer
|
||||
self.gridPanel.DestroyChildren()
|
||||
self.fields.clear()
|
||||
|
||||
#Setup textboxes
|
||||
for field, defaultVal in view.getFields().iteritems():
|
||||
if icons:
|
||||
icon = icons.get(field)
|
||||
if icon is not None:
|
||||
static = wx.StaticBitmap(self.gridPanel)
|
||||
static.SetBitmap(icon)
|
||||
sizer.Add(static, 0)
|
||||
|
||||
if labels:
|
||||
label = labels.get(field)
|
||||
label = label if label is not None else field
|
||||
else:
|
||||
label = field
|
||||
|
||||
sizer.Add(wx.StaticText(self.gridPanel, wx.ID_ANY, label), 0)
|
||||
textBox = wx.TextCtrl(self.gridPanel, wx.ID_ANY, style=0)
|
||||
self.fields[field] = textBox
|
||||
textBox.Bind(wx.EVT_TEXT, self.onFieldChanged)
|
||||
sizer.Add(textBox, 1, wx.EXPAND | wx.TOP, 2)
|
||||
if defaultVal is not None:
|
||||
if not isinstance(defaultVal, basestring):
|
||||
defaultVal = ("%f" % defaultVal).rstrip("0")
|
||||
if defaultVal[-1:] == ".":
|
||||
defaultVal = defaultVal + "0"
|
||||
|
||||
textBox.ChangeValue(defaultVal)
|
||||
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
values = self.getValues()
|
||||
view = self.getView()
|
||||
success, status = view.getPoints(values)
|
||||
if not success:
|
||||
#TODO: Add a pwetty statys bar to report errors with
|
||||
return
|
||||
|
||||
x, y = success, status
|
||||
|
||||
self.subplot.plot(x, y)
|
||||
self.canvas.draw()
|
||||
def onFieldChanged(self, event):
|
||||
try:
|
||||
self.draw()
|
||||
except:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user