Add line style support
This commit is contained in:
@@ -31,7 +31,7 @@ import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
from graphs.data.base import FitGraph
|
||||
from graphs.events import RESIST_MODE_CHANGED
|
||||
from graphs.style import BASE_COLORS, LIGHTNESSES, hsl_to_hsv
|
||||
from graphs.style import BASE_COLORS, LIGHTNESSES, STYLES, hsl_to_hsv
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from service.const import GraphCacheCleanupReason
|
||||
from service.settings import GraphSettings
|
||||
@@ -269,13 +269,14 @@ class GraphFrame(wx.Frame):
|
||||
else:
|
||||
iterList = tuple((f, None) for f in sources)
|
||||
for source, target in iterList:
|
||||
# Get color data
|
||||
# Get line style data
|
||||
try:
|
||||
colorData = BASE_COLORS[source.colorID]
|
||||
except KeyError:
|
||||
pyfalog.warning('Invalid color "{}" for "{}"'.format(source.colorID, source.name))
|
||||
continue
|
||||
color = colorData.hsl
|
||||
lineStyle = 'solid'
|
||||
if target is not None:
|
||||
try:
|
||||
lightnessData = LIGHTNESSES[target.lightnessID]
|
||||
@@ -283,7 +284,14 @@ class GraphFrame(wx.Frame):
|
||||
pyfalog.warning('Invalid lightness "{}" for "{}"'.format(target.lightnessID, target.name))
|
||||
continue
|
||||
color = lightnessData.func(color)
|
||||
try:
|
||||
lineStyleData = STYLES[target.lineStyleID]
|
||||
except KeyError:
|
||||
pyfalog.warning('Invalid line style "{}" for "{}"'.format(target.lightnessID, target.name))
|
||||
continue
|
||||
lineStyle = lineStyleData.mplSpec
|
||||
color = hsv_to_rgb(hsl_to_hsv(color))
|
||||
|
||||
# Get point data
|
||||
try:
|
||||
xs, ys = view.getPlotPoints(
|
||||
@@ -307,14 +315,14 @@ class GraphFrame(wx.Frame):
|
||||
max_y = max(max_y, max_y_this)
|
||||
|
||||
if len(xs) == 1 and len(ys) == 1:
|
||||
self.subplot.plot(xs, ys, color=color, marker='.')
|
||||
self.subplot.plot(xs, ys, color=color, linestyle=lineStyle, marker='.')
|
||||
else:
|
||||
self.subplot.plot(xs, ys, color=color)
|
||||
self.subplot.plot(xs, ys, color=color, linestyle=lineStyle)
|
||||
|
||||
if target is None:
|
||||
legend.append((color, source.shortName))
|
||||
legend.append((color, lineStyle, source.shortName))
|
||||
else:
|
||||
legend.append((color, '{} vs {}'.format(source.shortName, target.shortName)))
|
||||
legend.append((color, lineStyle, '{} vs {}'.format(source.shortName, target.shortName)))
|
||||
except Exception as ex:
|
||||
pyfalog.warning('Invalid values in "{0}"', source.name)
|
||||
self.canvas.draw()
|
||||
@@ -340,8 +348,8 @@ class GraphFrame(wx.Frame):
|
||||
|
||||
legend2 = []
|
||||
for i, iData in enumerate(legend):
|
||||
color, label = iData
|
||||
legend2.append(Patch(color=color, label=label), )
|
||||
color, lineStyle, label = iData
|
||||
legend2.append(Patch(color=color, linestyle=lineStyle, label=label), )
|
||||
|
||||
if len(legend2) > 0 and self.ctrlPanel.showLegend:
|
||||
leg = self.subplot.legend(handles=legend2)
|
||||
|
||||
@@ -27,10 +27,11 @@ from graphs.style import BASE_COLORS, LIGHTNESSES
|
||||
from graphs.wrapper import SourceWrapper, TargetWrapper
|
||||
from gui.builtinViewColumns.graphColor import GraphColor
|
||||
from gui.builtinViewColumns.graphLightness import GraphLightness
|
||||
from gui.builtinViewColumns.graphLineStyle import GraphLineStyle
|
||||
from gui.contextMenu import ContextMenu
|
||||
from service.const import GraphCacheCleanupReason
|
||||
from service.fit import Fit
|
||||
from .stylePickers import ColorPickerPopup, LightnessPickerPopup
|
||||
from .stylePickers import ColorPickerPopup, LightnessPickerPopup, LineStylePickerPopup
|
||||
|
||||
|
||||
class BaseWrapperList(gui.display.Display):
|
||||
@@ -122,7 +123,9 @@ class BaseWrapperList(gui.display.Display):
|
||||
if row != -1:
|
||||
pickers = {
|
||||
self.getColIndex(GraphColor): ColorPickerPopup,
|
||||
self.getColIndex(GraphLightness): LightnessPickerPopup}
|
||||
self.getColIndex(GraphLightness): LightnessPickerPopup,
|
||||
self.getColIndex(GraphLineStyle): LineStylePickerPopup}
|
||||
# In case we had no index for some column, remove None
|
||||
pickers.pop(None, None)
|
||||
col = self.getColumn(event.Position)
|
||||
if col in pickers:
|
||||
@@ -286,7 +289,7 @@ class SourceWrapperList(BaseWrapperList):
|
||||
for colorID in BASE_COLORS:
|
||||
if leastUses == colorUseMap.get(colorID, 0):
|
||||
break
|
||||
self._wrappers.append(SourceWrapper(item, colorID))
|
||||
self._wrappers.append(SourceWrapper(item=item, colorID=colorID))
|
||||
|
||||
def spawnMenu(self, event):
|
||||
selection = self.getSelectedWrappers()
|
||||
@@ -307,6 +310,7 @@ class TargetWrapperList(BaseWrapperList):
|
||||
|
||||
DEFAULT_COLS = (
|
||||
'Graph Lightness',
|
||||
'Graph Line Style',
|
||||
'Base Icon',
|
||||
'Base Name')
|
||||
|
||||
@@ -330,7 +334,7 @@ class TargetWrapperList(BaseWrapperList):
|
||||
for lightnessID in LIGHTNESSES:
|
||||
if leastUses == lightnessUseMap.get(lightnessID, 0):
|
||||
break
|
||||
self._wrappers.append(TargetWrapper(item=item, lightnessID=lightnessID))
|
||||
self._wrappers.append(TargetWrapper(item=item, lightnessID=lightnessID, lineStyleID=None))
|
||||
|
||||
def spawnMenu(self, event):
|
||||
selection = self.getSelectedWrappers()
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from graphs.style import BASE_COLORS, LIGHTNESSES
|
||||
from graphs.style import BASE_COLORS, LIGHTNESSES, STYLES
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from service.const import GraphLightness
|
||||
|
||||
@@ -96,3 +96,11 @@ class LightnessPickerPopup(StylePickerPopup):
|
||||
wrapperAttr = 'lightnessID'
|
||||
ncols = 3
|
||||
nrows = 1
|
||||
|
||||
|
||||
class LineStylePickerPopup(StylePickerPopup):
|
||||
|
||||
styleContainer = STYLES
|
||||
wrapperAttr = 'lineStyleID'
|
||||
ncols = 4
|
||||
nrows = 1
|
||||
|
||||
@@ -20,13 +20,29 @@
|
||||
|
||||
from collections import OrderedDict, namedtuple
|
||||
|
||||
from service.const import GraphColor, GraphLightness
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from service.const import GraphColor, GraphLightness, GraphLineStyle
|
||||
|
||||
|
||||
ColorData = namedtuple('ColorData', ('hsl', 'name', 'iconName'))
|
||||
LightnessData = namedtuple('LightnessData', ('name', 'iconName', 'func'))
|
||||
|
||||
|
||||
class LineStyleData:
|
||||
|
||||
def __init__(self, name, iconNamePrefix, mplSpec):
|
||||
self.name = name
|
||||
self._iconNamePrefix = iconNamePrefix
|
||||
self.mplSpec = mplSpec
|
||||
|
||||
@property
|
||||
def iconName(self):
|
||||
# TODO: add code to use white icon if background is dark
|
||||
return '{}_black'.format(self._iconNamePrefix)
|
||||
|
||||
|
||||
# In HSL format
|
||||
BASE_COLORS = OrderedDict([
|
||||
(GraphColor.red, ColorData((0 / 360.0, 1.0, 0.5), 'Red', 'color_red')),
|
||||
@@ -60,3 +76,10 @@ LIGHTNESSES = OrderedDict([
|
||||
(GraphLightness.normal, LightnessData('Normal', 'lightness_normal', lambda hsl: hsl)),
|
||||
(GraphLightness.dark, LightnessData('Dark', 'lightness_dark', darken)),
|
||||
(GraphLightness.bright, LightnessData('Bright', 'lightness_bright', brighten))])
|
||||
|
||||
|
||||
STYLES = OrderedDict([
|
||||
(GraphLineStyle.solid, LineStyleData('Solid', 'style_solid', 'solid')),
|
||||
(GraphLineStyle.dashed, LineStyleData('Dashed', 'style_dashed', (0, (5, 1)))),
|
||||
(GraphLineStyle.dotted, LineStyleData('Dotted', 'style_dotted', (0, (1, 1)))),
|
||||
(GraphLineStyle.dashdotted, LineStyleData('Dash-dotted', 'style_dashdot', (0, (3, 1, 1, 1))))])
|
||||
|
||||
@@ -110,26 +110,11 @@ class SourceWrapper(BaseWrapper):
|
||||
|
||||
class TargetWrapper(BaseWrapper):
|
||||
|
||||
def __init__(self, item, lightnessID):
|
||||
def __init__(self, item, lightnessID, lineStyleID):
|
||||
super().__init__(item=item)
|
||||
self._lightnessID = lightnessID
|
||||
self.__resistMode = TargetResistMode.auto
|
||||
|
||||
@property
|
||||
def lightnessID(self):
|
||||
return self._lightnessID
|
||||
|
||||
@lightnessID.setter
|
||||
def lightnessID(self, value):
|
||||
self._lightnessID = value
|
||||
|
||||
@property
|
||||
def resistMode(self):
|
||||
return self.__resistMode
|
||||
|
||||
@resistMode.setter
|
||||
def resistMode(self, value):
|
||||
self.__resistMode = value
|
||||
self.lightnessID = lightnessID
|
||||
self.lineStyleID = lineStyleID
|
||||
self.resistMode = TargetResistMode.auto
|
||||
|
||||
def getResists(self, includeLayer=False):
|
||||
em = therm = kin = explo = 0
|
||||
|
||||
55
gui/builtinViewColumns/graphLineStyle.py
Normal file
55
gui/builtinViewColumns/graphLineStyle.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# =============================================================================
|
||||
# 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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from graphs.style import STYLES
|
||||
from graphs.wrapper import TargetWrapper
|
||||
from gui.viewColumn import ViewColumn
|
||||
|
||||
|
||||
class GraphLineStyle(ViewColumn):
|
||||
|
||||
name = 'Graph Line Style'
|
||||
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
self.resizable = False
|
||||
self.size = 20
|
||||
self.maxsize = self.size
|
||||
self.mask = wx.LIST_MASK_TEXT
|
||||
|
||||
def getImageId(self, stuff):
|
||||
if isinstance(stuff, TargetWrapper):
|
||||
try:
|
||||
styleData = STYLES[stuff.lineStyleID]
|
||||
except KeyError:
|
||||
return -1
|
||||
img = self.fittingView.imageList.GetImageIndex(styleData.iconName, 'gui')
|
||||
return img
|
||||
return -1
|
||||
|
||||
def getToolTip(self, stuff):
|
||||
if isinstance(stuff, TargetWrapper):
|
||||
return 'Change line style'
|
||||
return ''
|
||||
|
||||
|
||||
GraphLineStyle.register()
|
||||
@@ -78,6 +78,7 @@ from gui.builtinViewColumns import ( # noqa: E402, F401
|
||||
capacitorUse,
|
||||
graphColor,
|
||||
graphLightness,
|
||||
graphLineStyle,
|
||||
maxRange,
|
||||
misc,
|
||||
price,
|
||||
|
||||
@@ -157,3 +157,11 @@ class GraphLightness(IntEnum):
|
||||
normal = autoId()
|
||||
dark = autoId()
|
||||
bright = autoId()
|
||||
|
||||
|
||||
@unique
|
||||
class GraphLineStyle(IntEnum):
|
||||
solid = autoId()
|
||||
dashed = autoId()
|
||||
dotted = autoId()
|
||||
dashdotted = autoId()
|
||||
|
||||
Reference in New Issue
Block a user