[Mod] improve chart appearance

This commit is contained in:
vn.py 2019-07-18 21:06:08 +08:00
parent 9fb8b1fc2b
commit 85e10ddb8a
4 changed files with 106 additions and 36 deletions

View File

@ -2,13 +2,8 @@ from typing import List
import pyqtgraph as pg import pyqtgraph as pg
from vnpy.trader.ui import QtGui
from .manager import BarManager from .manager import BarManager
from .base import AXIS_WIDTH, NORMAL_FONT
AXIS_WIDTH = 0.8
AXIS_FONT = QtGui.QFont("Arial", 10, QtGui.QFont.Bold)
class DatetimeAxis(pg.AxisItem): class DatetimeAxis(pg.AxisItem):
@ -21,7 +16,7 @@ class DatetimeAxis(pg.AxisItem):
self._manager: BarManager = manager self._manager: BarManager = manager
self.setPen(width=AXIS_WIDTH) self.setPen(width=AXIS_WIDTH)
self.setStyle(tickFont=AXIS_FONT, autoExpandTextSpace=True) self.tickFont = NORMAL_FONT
def tickStrings(self, values: List[int], scale: float, spacing: int): def tickStrings(self, values: List[int], scale: float, spacing: int):
""" """

View File

@ -1,3 +1,6 @@
from vnpy.trader.ui import QtGui
WHITE_COLOR = (255, 255, 255) WHITE_COLOR = (255, 255, 255)
BLACK_COLOR = (0, 0, 0) BLACK_COLOR = (0, 0, 0)
GREY_COLOR = (100, 100, 100) GREY_COLOR = (100, 100, 100)
@ -9,6 +12,9 @@ CURSOR_COLOR = (255, 245, 162)
PEN_WIDTH = 1 PEN_WIDTH = 1
BAR_WIDTH = 0.4 BAR_WIDTH = 0.4
AXIS_WIDTH = 0.8
NORMAL_FONT = QtGui.QFont("Arial", 9)
def to_int(value: float) -> int: def to_int(value: float) -> int:
"""""" """"""

View File

@ -55,6 +55,13 @@ class ChartItem(pg.GraphicsObject):
""" """
pass pass
@abstractmethod
def get_info_text(self, ix: int) -> str:
"""
Get information text to show by cursor.
"""
pass
def update_history(self, history: List[BarData]) -> BarData: def update_history(self, history: List[BarData]) -> BarData:
""" """
Update a list of bar data. Update a list of bar data.
@ -204,6 +211,38 @@ class CandleItem(ChartItem):
min_price, max_price = self._manager.get_price_range(min_ix, max_ix) min_price, max_price = self._manager.get_price_range(min_ix, max_ix)
return min_price, max_price return min_price, max_price
def get_info_text(self, ix: int) -> str:
"""
Get information text to show by cursor.
"""
bar = self._manager.get_bar(ix)
if bar:
words = [
"Date",
bar.datetime.strftime("%Y-%m-%d"),
"",
"Time",
bar.datetime.strftime("%H:%M"),
"",
"Open",
str(bar.open_price),
"",
"High",
str(bar.high_price),
"",
"Low",
str(bar.low_price),
"",
"Close",
str(bar.close_price)
]
text = "\n".join(words)
else:
text = ""
return text
class VolumeItem(ChartItem): class VolumeItem(ChartItem):
"""""" """"""
@ -258,3 +297,16 @@ class VolumeItem(ChartItem):
""" """
min_volume, max_volume = self._manager.get_volume_range(min_ix, max_ix) min_volume, max_volume = self._manager.get_volume_range(min_ix, max_ix)
return min_volume, max_volume return min_volume, max_volume
def get_info_text(self, ix: int) -> str:
"""
Get information text to show by cursor.
"""
bar = self._manager.get_bar(ix)
if bar:
text = f"Volume {bar.volume}"
else:
text = ""
return text

View File

@ -6,8 +6,11 @@ from vnpy.trader.ui import QtGui, QtWidgets, QtCore
from vnpy.trader.object import BarData from vnpy.trader.object import BarData
from .manager import BarManager from .manager import BarManager
from .base import GREY_COLOR, WHITE_COLOR, CURSOR_COLOR, BLACK_COLOR, to_int from .base import (
from .axis import DatetimeAxis, AXIS_FONT GREY_COLOR, WHITE_COLOR, CURSOR_COLOR, BLACK_COLOR,
to_int, NORMAL_FONT
)
from .axis import DatetimeAxis
from .item import ChartItem from .item import ChartItem
@ -49,7 +52,8 @@ class ChartWidget(pg.PlotWidget):
def add_cursor(self) -> None: def add_cursor(self) -> None:
"""""" """"""
if not self._cursor: if not self._cursor:
self._cursor = ChartCursor(self, self._manager, self._plots) self._cursor = ChartCursor(
self, self._manager, self._plots, self._item_plot_map)
def add_plot( def add_plot(
self, self,
@ -89,7 +93,7 @@ class ChartWidget(pg.PlotWidget):
# Set right axis # Set right axis
right_axis = plot.getAxis('right') right_axis = plot.getAxis('right')
right_axis.setWidth(60) right_axis.setWidth(60)
right_axis.setStyle(tickFont=AXIS_FONT) right_axis.tickFont = NORMAL_FONT
# Connect x-axis link # Connect x-axis link
if self._plots: if self._plots:
@ -294,7 +298,8 @@ class ChartCursor(QtCore.QObject):
self, self,
widget: ChartWidget, widget: ChartWidget,
manager: BarManager, manager: BarManager,
plots: Dict[str, pg.GraphicsObject] plots: Dict[str, pg.GraphicsObject],
item_plot_map: Dict[ChartItem, pg.GraphicsObject]
): ):
"""""" """"""
super().__init__() super().__init__()
@ -302,6 +307,7 @@ class ChartCursor(QtCore.QObject):
self._widget: ChartWidget = widget self._widget: ChartWidget = widget
self._manager: BarManager = manager self._manager: BarManager = manager
self._plots: Dict[str, pg.GraphicsObject] = plots self._plots: Dict[str, pg.GraphicsObject] = plots
self._item_plot_map: Dict[ChartItem, pg.GraphicsObject] = item_plot_map
self._x: int = 0 self._x: int = 0
self._y: int = 0 self._y: int = 0
@ -346,9 +352,11 @@ class ChartCursor(QtCore.QObject):
""" """
self._y_labels: Dict[str, pg.TextItem] = {} self._y_labels: Dict[str, pg.TextItem] = {}
for plot_name, plot in self._plots.items(): for plot_name, plot in self._plots.items():
label = pg.TextItem(plot_name, fill=CURSOR_COLOR, color=BLACK_COLOR) label = pg.TextItem(
plot_name, fill=CURSOR_COLOR, color=BLACK_COLOR)
label.hide() label.hide()
label.setZValue(2) label.setZValue(2)
label.setFont(NORMAL_FONT)
plot.addItem(label, ignoreBounds=True) plot.addItem(label, ignoreBounds=True)
self._y_labels[plot_name] = label self._y_labels[plot_name] = label
@ -356,17 +364,25 @@ class ChartCursor(QtCore.QObject):
"datetime", fill=CURSOR_COLOR, color=BLACK_COLOR) "datetime", fill=CURSOR_COLOR, color=BLACK_COLOR)
self._x_label.hide() self._x_label.hide()
self._x_label.setZValue(2) self._x_label.setZValue(2)
self._x_label.setFont(NORMAL_FONT)
plot.addItem(self._x_label, ignoreBounds=True) plot.addItem(self._x_label, ignoreBounds=True)
def _init_info(self) -> None: def _init_info(self) -> None:
""" """
""" """
self._info = pg.TextItem("info", color=CURSOR_COLOR) self._infos: Dict[str, pg.TextItem] = {}
self._info.hide() for plot_name, plot in self._plots.items():
self._info.setZValue(2) info = pg.TextItem(
"info",
plot = list(self._plots.values())[0] color=CURSOR_COLOR,
plot.addItem(self._info, ignoreBounds=True) border=CURSOR_COLOR,
fill=BLACK_COLOR
)
info.hide()
info.setZValue(2)
info.setFont(NORMAL_FONT)
plot.addItem(info) # , ignoreBounds=True)
self._infos[plot_name] = info
def _connect_signal(self) -> None: def _connect_signal(self) -> None:
""" """
@ -444,24 +460,25 @@ class ChartCursor(QtCore.QObject):
def update_info(self) -> None: def update_info(self) -> None:
"""""" """"""
bar = self._manager.get_bar(self._x) buf = {}
if bar: for item, plot in self._item_plot_map.items():
op = bar.open_price item_info_text = item.get_info_text(self._x)
hp = bar.high_price if item_info_text:
lp = bar.low_price if plot not in buf:
cp = bar.close_price buf[plot] = item_info_text
v = bar.volume else:
text = f"(open){op} (high){hp} (low){lp} (close){cp} (volume){v}" buf[plot] += ("\n\n" + item_info_text)
else:
text = ""
self._info.setText(text) for plot_name, plot in self._plots.items():
self._info.show() plot_info_text = buf[plot]
info = self._infos[plot_name]
info.setText(plot_info_text)
info.show()
view = list(self._views.values())[0] view = self._views[plot_name]
top_left = view.mapSceneToView(view.sceneBoundingRect().topLeft()) top_left = view.mapSceneToView(view.sceneBoundingRect().topLeft())
self._info.setPos(top_left) info.setPos(top_left)
def move_right(self) -> None: def move_right(self) -> None:
""" """
@ -501,8 +518,8 @@ class ChartCursor(QtCore.QObject):
self._y = 0 self._y = 0
self._plot_name = "" self._plot_name = ""
for line in self._v_lines + self._h_lines: for line in list(self._v_lines.values()) + list(self._h_lines.values()):
line.hide() line.hide()
for label in self._y_labels + [self._x_label]: for label in list(self._y_labels.values()) + [self._x_label]:
label.hide() label.hide()