Browse Source

add caption to graph and fix graph scale

badge shows all time data (limited only by backend query)
  - all time min/max and all time average (true weighted average of cost per unit)
graph shows last x number of data such that x is the canvas size
  - min/max over displayed data, and median cost per unit over displayed data (not taking quantity into account)

could update to recalculate true average over displayed data - just need to weight by quantity
Daniel Sheffield 2 years ago
parent
commit
b53b7285a4
2 changed files with 32 additions and 6 deletions
  1. 19 3
      app/activities/TransactionEditor.py
  2. 13 3
      app/widgets.py

+ 19 - 3
app/activities/TransactionEditor.py

@@ -140,17 +140,33 @@ class TransactionEditor(FocusWidget):
         
         assert len(df['avg'].unique()) == 1, f"There should be only one average price: {df['avg'].unique()}"
         
+        # all time (or all data) avg(mean), min, max
         _avg, _min, _max = [
           float(x) for x in df[['avg','min','max']].iloc[0]
         ]
         self.rating.update_rating(_avg, _min, _max, unit, price=price, quantity=quantity)
+
+        # after truncating, need to recalculate avg(median), min, max
         df = df.sort_values('ts_raw', ascending=True).truncate(after=self.graph._canvas_width-1)
         self.graph.set_data(
-            df[['$/unit']].apply(lambda x: (float(x['$/unit']),), axis=1),
-            df['max'].apply(float).iloc[0],
-            labels=[_min, _avg, _max]
+            df[['$/unit']].apply(
+                lambda x: (float(x['$/unit']),), axis=1
+            ), float(df['$/unit'].max()), vscale=[x for x in map(float, [
+                df['$/unit'].min(),
+                df['$/unit'].median(),
+                df['$/unit'].max()
+            ])]
         )
         self.graph.set_bar_width(1)
+        # canvas_width = 10 + pad + pad + 10
+        date_strlen = (self.graph.canvas_width - 20)
+        ex = "─" if date_strlen % 2 else ""
+        plen = date_strlen//2
+        caption = f"{df['ts_raw'].min():%d/%m/%Y}"
+        caption += f"{{p:>{plen}}}{ex}{{p:<{plen}}}".format(
+            p="─")
+        caption += f"{df['ts_raw'].max():%d/%m/%Y}"
+        self.graph.set_caption(caption)
 
 
 

+ 13 - 3
app/widgets.py

@@ -326,9 +326,14 @@ class FlowBarGraphWithVScale(urwid.Columns):
     def set_bar_width(self, width):
         self.graph.set_bar_width(width)
     
-    def set_data(self, data, _max, labels=None):
+    def set_caption(self, text):
+        self.graph_caption.set_text(text)
+    
+    def set_data(self, data, _max, vscale=None, caption=None):
+        labels = vscale or []
+        caption = caption or u''
         top = self.height
-        scale = (_max/top)*(top+1)
+        scale = _max*(top+1)/top
         self.graph.set_data(data, scale)
         if labels is None:
             return
@@ -336,6 +341,7 @@ class FlowBarGraphWithVScale(urwid.Columns):
         self.graph_vscale.set_scale([
             ((x*top)//scale, f'{x:>5.2f} ') for x in labels
         ], top)
+        self.graph_caption.set_text(caption)
     
     def __init__(self, cols, rows, attr, *args, hatt=None, **kwargs):
         self._total_width = cols
@@ -344,8 +350,12 @@ class FlowBarGraphWithVScale(urwid.Columns):
         self._canvas_width = cols - 6
         self.graph = FlowBarGraph(rows, attr, hatt=hatt)
         self.graph_vscale = FlowGraphVScale(self.graph, [], 0)
+        self.graph_caption = urwid.Text(u'')
         super().__init__([
             (self._vscale_width, self.graph_vscale),
-            (self._canvas_width, self.graph)
+            (self._canvas_width, urwid.Pile([
+                self.graph,
+                self.graph_caption
+            ]))
         ], *args, **kwargs)