1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#!/usr/bin/env bash
set -exo pipefail
query='^as ^li'
function floor {
printf %.f $1
}
function ceil {
printf %.f $(bc <<< "$1+1")
}
function dec {
bc <<< "$1-1"
}
function inc {
bc <<< "$1+1"
}
function exp10 {
bc <<< "10^$1"
}
function log10 {
bc -l <<< "l($1)/l(10)"
}
function add {
bc -l <<< "$1 + $2"
}
# colors
purple="#6961ff"
green="#61ff69"
red="#ff6961"
datefmt="%Y-%m-%d"
today=$(date +$datefmt)
xstart=$(date -d"2 years ago" +$datefmt)
# basically just calculates the log10 and removes some columns
process_row=$(cat <<EOF
import csv, sys, math
from datetime import datetime
data = sys.stdin.readlines()
rdr = csv.reader(data)
next(rdr, None) # skip header
prev=None
for row in rdr:
date = row[1]
networth = float(row[6][:-3].replace(",", "").strip())
if prev:
x1 = datetime.strptime(prev[0], "$datefmt")
x2 = datetime.strptime(date, "$datefmt")
y1 = prev[1]
y2 = networth
change = (y1-y2) / max((x1-x2).days, 1)
change = ((networth / prev[1]) - 1) * 100
else:
change = 1
level = math.log10(networth)
print(date)
print(f"{date},{level:.2f},{networth:.2f},{change}")
prev = (date, networth)
EOF
)
networth=$(hledger bal $query --depth=1 --value=now --infer-value \
| tail -n1 \
| awk '{ print $1 }' \
| tr -d ','
)
level=$(log10 $networth)
flevel=$(floor $level)
data=$(mktemp --suffix=-data)
hledger reg $query --value=end,USD --infer-value -O csv \
| python3 -c "$process_row" \
> $data
plot=$(mktemp --suffix=-plot)
# here's the actual plotting code
cat <<EOF > $plot
set datafile separator ","
set terminal png size 2560,1920
#set term dumb
set multiplot
set size 1, 0.5
set grid
# x axis
set xdata time
set timefmt '$datefmt'
set xrange ['$xstart':'$today']
set format x '$datefmt'
set xtics rotate by 60 offset 0,-1.5 out nomirror
# Level
set origin 0, 0.5
set ytics 0.2
set yrange [$(floor $(dec $level)):$(ceil $level)]
set ylabel "Overall Level" textcolor rgb "green"
plot '$data' using 1:2 linecolor rgb "red" smooth bezier with lines title "Level ($level)", \
$(inc $flevel) linecolor rgb "$purple" with lines title "Level $(inc $flevel)", \
$flevel linecolor rgb "$green" with lines title "Level $flevel", \
$(dec $flevel) linecolor rgb "$red" with lines title "Level $(dec $flevel)"
# Net worth, within current level
set origin 0, 0.0
set ytics $(exp10 $level)
set yrange [$(exp10 $(dec $flevel)):$(exp10 $(inc $flevel))]
set ylabel "Net worth within current level" textcolor rgb "green"
plot '$data' using 1:3 linecolor rgb "green" with filledcurves x1 title "Net Worth ($networth)", \
$(exp10 $(inc $flevel)) linecolor rgb "$purple" with lines title "Level $(inc $flevel)", \
$(exp10 $flevel) linecolor rgb "$green" with lines title "Level $flevel", \
$(exp10 $(dec $flevel)) linecolor rgb "$red" with lines title "Level $(dec $flevel)"
# Rate of change
#set origin 0, 0
#set ytics 10
#set yrange [-100:100]
#set ylabel "Rate of change"
#plot '$data' using 1:4 linecolor rgb "green" smooth csplines with lines title "rate of change"
unset multiplot
EOF
gnuplot -p $plot
|