From 93823811444bf3d1112784c3d12ca9c67b535238 Mon Sep 17 00:00:00 2001 From: Eneko Illarramendi Date: Thu, 5 Mar 2020 20:29:27 +0100 Subject: [PATCH] chore: initial version of tx chart --- lnbits/core/models.py | 1 + lnbits/core/static/js/wallet.js | 88 +++++++++++++++++++++++++- lnbits/core/templates/core/wallet.html | 32 ++++++---- 3 files changed, 108 insertions(+), 13 deletions(-) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 4a6cb5a..e1f112d 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -59,4 +59,5 @@ class Transaction(NamedTuple): def set_pending(self, pending: bool) -> None: from .crud import update_transaction_status + update_transaction_status(self.payhash, pending) diff --git a/lnbits/core/static/js/wallet.js b/lnbits/core/static/js/wallet.js index 1b8a0de..8cbbdf5 100644 --- a/lnbits/core/static/js/wallet.js +++ b/lnbits/core/static/js/wallet.js @@ -1,5 +1,80 @@ Vue.component(VueQrcode.name, VueQrcode); + +function generateChart(canvas, transactions) { + var txs = []; + var n = 0; + var data = { + labels: [], + sats: [], + cumulative: [] + }; + + _.each(transactions.sort(function (a, b) { + return a.time - b.time; + }), function (tx) { + txs.push({ + day: Quasar.utils.date.formatDate(tx.date, 'YYYY-MM-DDTHH:00'), + sat: tx.sat, + }); + }); + + _.each(_.groupBy(txs, 'day'), function (value, day) { + var sat = _.reduce(value, function(memo, tx) { return memo + tx.sat; }, 0); + n = n + sat; + data.labels.push(day); + data.sats.push(sat); + data.cumulative.push(n); + }); + + new Chart(canvas.getContext('2d'), { + type: 'bar', + data: { + labels: data.labels, + datasets: [ + { + data: data.cumulative, + type: 'line', + label: 'balance', + borderColor: '#673ab7', // deep-purple + borderWidth: 4, + pointRadius: 3, + fill: false + }, + { + data: data.sats, + type: 'bar', + label: 'tx', + backgroundColor: function (ctx) { + var value = ctx.dataset.data[ctx.dataIndex]; + return (value < 0) ? '#e91e63' : '#4caf50'; // pink : green + } + } + ] + }, + options: { + title: { + text: 'Chart.js Combo Time Scale' + }, + tooltips: { + mode: 'index', + intersect:false + }, + scales: { + xAxes: [{ + type: 'time', + display: true, + time: { + minUnit: 'hour', + stepSize: 3 + } + }], + }, + } + }); +} + + new Vue({ el: '#vue', mixins: [windowMixin], @@ -31,6 +106,9 @@ new Vue({ pagination: { rowsPerPage: 10 } + }, + transactionsChart: { + show: false } }; }, @@ -47,7 +125,7 @@ new Vue({ } }, methods: { - openReceiveDialog: function () { + showReceiveDialog: function () { this.receive = { show: true, status: 'pending', @@ -58,7 +136,7 @@ new Vue({ } }; }, - openSendDialog: function () { + showSendDialog: function () { this.send = { show: true, invoice: null, @@ -67,6 +145,12 @@ new Vue({ } }; }, + showChart: function () { + this.transactionsChart.show = true; + this.$nextTick(function () { + generateChart(this.$refs.canvas, this.transactions); + }); + }, createInvoice: function () { var self = this; this.receive.status = 'loading'; diff --git a/lnbits/core/templates/core/wallet.html b/lnbits/core/templates/core/wallet.html index ee4f00c..0565279 100644 --- a/lnbits/core/templates/core/wallet.html +++ b/lnbits/core/templates/core/wallet.html @@ -4,7 +4,12 @@ {% block scripts %} + {{ window_vars(user, wallet) }} + {% assets filters='rjsmin', output='__bundle__/core/chart.js', + 'vendor/chart.js@2.9.3/chart.min.js' %} + + {% endassets %} {% assets filters='rjsmin', output='__bundle__/core/wallet.js', 'vendor/bolt11/utils.js', 'vendor/bolt11/decoder.js', @@ -26,13 +31,13 @@ Send + @click="showSendDialog">Send
Receive + @click="showReceiveDialog">Receive
@@ -45,6 +50,9 @@
Export to CSV + + Show chart +
+ :color="(props.row.sat < 0) ? 'pink' : 'green'"> {{ props.row.memo }} @@ -84,12 +92,6 @@ - - - -
-
-
@@ -167,7 +169,7 @@
- + - + + + + + + + + + {% endblock %}