diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py index e999ab604..9e770c8ed 100644 --- a/gui/qt/main_window.py +++ b/gui/qt/main_window.py @@ -2388,6 +2388,10 @@ class ElectrumWindow(QMainWindow): h, b = ok_cancel_buttons2(d, _('Export')) vbox.addLayout(h) + + run_hook('export_history_dialog', self,hbox) + self.update() + if not d.exec_(): return diff --git a/plugins/plot.py b/plugins/plot.py new file mode 100644 index 000000000..450a73692 --- /dev/null +++ b/plugins/plot.py @@ -0,0 +1,159 @@ +from PyQt4.QtGui import * +from electrum.plugins import BasePlugin, hook +from electrum.i18n import _ + + +import datetime +from electrum.util import format_satoshis + + +try: + import matplotlib.pyplot as plt + import matplotlib.dates as md + from matplotlib.patches import Ellipse + from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, DrawingArea, HPacker + flag_matlib=True +except: + flag_matlib=False + + + + + +class Plugin(BasePlugin): + + + def fullname(self): + return 'Plot History' + + def description(self): + return '%s\n%s' % (_("Ability to plot transaction history in graphical mode."), _("Warning: Requires matplotlib library.")) + + def is_available(self): + if flag_matlib: + return True + else: + return False + + + + def is_enabled(self): + if not self.is_available(): + return False + else: + return True + + + @hook + def init_qt(self, gui): + self.win = gui.main_window + + @hook + def export_history_dialog(self, d,hbox): + self.wallet = d.wallet + + history = self.wallet.get_tx_history() + + if len(history) > 0: + b = QPushButton(_("Preview plot")) + hbox.addWidget(b) + b.clicked.connect(lambda: self.do_plot(self.wallet)) + else: + b = QPushButton(_("No history to plot")) + hbox.addWidget(b) + + + + def do_plot(self,wallet): + history = wallet.get_tx_history() + balance_Val=[] + fee_val=[] + value_val=[] + datenums=[] + unknown_trans=0 + pending_trans=0 + counter_trans=0 + for item in history: + tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item + if confirmations: + if timestamp is not None: + try: + datenums.append(md.date2num(datetime.datetime.fromtimestamp(timestamp))) + balance_string = format_satoshis(balance, False) + balance_Val.append(float((format_satoshis(balance,False)))*1000.0) + except [RuntimeError, TypeError, NameError] as reason: + unknown_trans=unknown_trans+1 + pass + else: + unknown_trans=unknown_trans+1 + else: + pending_trans=pending_trans+1 + + if value is not None: + value_string = format_satoshis(value, True) + value_val.append(float(value_string)*1000.0) + else: + value_string = '--' + + if fee is not None: + fee_string = format_satoshis(fee, True) + fee_val.append(float(fee_string)) + else: + fee_string = '0' + + if tx_hash: + label, is_default_label = wallet.get_label(tx_hash) + label = label.encode('utf-8') + else: + label = "" + + + f, axarr = plt.subplots(2, sharex=True) + + plt.subplots_adjust(bottom=0.2) + plt.xticks( rotation=25 ) + ax=plt.gca() + x=19 + test11="Unknown transactions = "+str(unknown_trans)+" Pending transactions = "+str(pending_trans)+" ." + box1 = TextArea(" Test : Number of pending transactions", textprops=dict(color="k")) + box1.set_text(test11) + + + box = HPacker(children=[box1], + align="center", + pad=0.1, sep=15) + + anchored_box = AnchoredOffsetbox(loc=3, + child=box, pad=0.5, + frameon=True, + bbox_to_anchor=(0.5, 1.02), + bbox_transform=ax.transAxes, + borderpad=0.5, + ) + + + ax.add_artist(anchored_box) + + + plt.ylabel('mBTC') + plt.xlabel('Dates') + xfmt = md.DateFormatter('%Y-%m-%d') + ax.xaxis.set_major_formatter(xfmt) + + + axarr[0].plot(datenums,balance_Val,marker='o',linestyle='-',color='blue',label='Balance') + axarr[0].legend(loc='upper left') + axarr[0].set_title('History Transactions') + + + xfmt = md.DateFormatter('%Y-%m-%d') + ax.xaxis.set_major_formatter(xfmt) + axarr[1].plot(datenums,fee_val,marker='o',linestyle='-',color='red',label='Fee') + axarr[1].plot(datenums,value_val,marker='o',linestyle='-',color='green',label='Value') + + + + + axarr[1].legend(loc='upper left') + # plt.annotate('unknown transaction = %d \n pending transactions = %d' %(unknown_trans,pending_trans),xy=(0.7,0.05),xycoords='axes fraction',size=12) + plt.show() diff --git a/setup.py b/setup.py index 245d9e4af..477212689 100644 --- a/setup.py +++ b/setup.py @@ -133,6 +133,8 @@ setup( 'electrum_plugins.labels', 'electrum_plugins.trezor', 'electrum_plugins.virtualkeyboard', + 'electrum_plugins.plot', + ], description="Lightweight Bitcoin Wallet", author="Thomas Voegtlin",