Compare commits

..

18 Commits

Author SHA1 Message Date
71606035fd fix bug where growth is not calculated properly for future bills / hangover from when I assumed only simple growth as that was all we had before I added new growth menu options 2026-02-11 19:29:07 +11:00
b8c1edc084 fixed bug where insert cset did not show it in menu until a full reload 2026-02-11 12:02:09 +11:00
f0fee15548 new bug when creating new cset 2026-02-10 21:47:43 +11:00
20239d72c8 put improved foreign key constraints on DB to fix bug where when I delete a cset, that was being used to compare_to, it breaks 2026-02-10 21:35:41 +11:00
e3d2d8ea08 remove jquery filter for nav-tabs now we are using nav-pills in vertical mode, it was unnecessary anyway, only one div had navlinks, so just using the rest of the filter, and this fixes the BUG too 2026-02-10 19:14:43 +11:00
8446f59740 can now scroll with wheel in graphs 2026-02-10 19:10:25 +11:00
3a04b8321c 3 x new BUGS 2026-02-10 19:10:02 +11:00
037a9c2d87 add scroll todo 2026-02-10 19:09:29 +11:00
e7a3cb3d7d change formatting of fields so that we cater for scroll-bar or no scroll-bar when we show graph or not in lower part of UI, this stops the fields wrapping onto the next line when the scroll bar appears 2026-02-06 12:12:58 +11:00
2ba2ece1d0 tried to be smarter with tax, decided in the end to use non-code to come up with a figure and hard-code, hopefully not an issue soon anyway :) 2026-02-06 12:12:06 +11:00
0a0a7b321b remove warning / use r"" for regexp string" 2026-02-06 12:11:15 +11:00
85a53c8c5f minor update for bills, this needs to be dynamic 2026-02-06 12:10:31 +11:00
8e2f0ae340 take into account ENV var for snapshots 2026-02-06 12:09:36 +11:00
1cf835b7e7 refined label positions, and tweaked current ME balance 2026-02-06 12:09:02 +11:00
e104dd8270 Applying several hacks to draw labels better -- still not close to great, but bearable now. First we consider 0 amts as non-negative for annotations so they go up not down on the graph :) Second, I am applying a rough approach of knowing where the last label was drawn and draw below that, only do this for negative amts, and even then the difference between y-coords in the y-axis scale and pixels for offsets of labels, just are too annoying 2026-01-18 22:23:04 +11:00
a46b8f895a sort annotations so the historical annotations are drawn first, so up/down labels are mostly working properly 2026-01-18 22:21:14 +11:00
09de41e093 updated BUGS 2026-01-18 00:33:56 +11:00
9c02bc94ff added a favicon, moved horizontal nav-tabs for bills to a vertical nav-pills 2026-01-18 00:33:13 +11:00
12 changed files with 135 additions and 68 deletions

5
BUGS
View File

@@ -1,4 +1,9 @@
* can put in dumb dates - DO SOME INPUT VALIDATION, *sigh*
- e.g. 0026-02-19 for a Gas bill
* kayo bills are wrong in between normal bills
* added an electricity bill by accident for 2018, that kills lots :(
- something to do with missing year of data in quarterly bills - still an issue
* if change a bill (like Amazon), then its future estimates don't update

8
TODO
View File

@@ -1,4 +1,6 @@
bills:
bill for the year (when removed from LE, should be dynamic)
bills html, and growth types are poor code repitition / lame... could I do something more like:
{% for gt in growth %}
{% if gt.name == 'Min' %}
@@ -13,9 +15,3 @@ CALC:
* still get double health insurance bills sometimes (just viewing a new date might trigger this??? or at least when I changed years)
UI:
* add FIXED Annotations:
* historical annotations (at least M_quit_date, Trip_date, school_fees in 25)
* should try AI with how to distribute annotations better
* make bills tabs a vertical navbar instead of horizontal
* make FIRST_YEAR dynamic, and maybe just WARN if next pay is > FIRST_YEAR (let me sort if by hand - probably non-issue as unlikely to be working in late Dec 26)

View File

@@ -304,7 +304,7 @@ def get_growth_value( bt, bill_type ):
finance_data = get_finance_data()
return finance_data['Inflation']
else:
match = re.match("flat-(\d+)", which )
match = re.match(r"flat-(\d+)", which )
if match:
return int(match.group(1))
else:
@@ -643,8 +643,7 @@ def recalcFutureBills():
for fb in future_car_bills:
amt=fb['amount']
bt=fb['bill_type']
# only can use simple growth as its a future bill
growth=bill_types[bt]['ann_growth_simple']
growth = get_growth_value( bill_types, bt )
# factor in growth for next bills
for yr in range( int(car_yr), END_YEAR+1 ):
new_date=f"{yr}-{car_mmdd}"
@@ -661,7 +660,7 @@ def recalcFutureBills():
# deal with future bills due to their starting dates being dynamic
amt=fb['amount']
bt=fb['bill_type']
growth=bill_types[bt]['ann_growth_simple']
growth = get_growth_value( bill_types, bt )
num_ann_bills= bf_id_num[bt_id_freq[bt]]
if num_ann_bills == 1:
# factor in growth for next bill

25
calc.py
View File

@@ -34,7 +34,7 @@ def bill_amount_today(finance, day, bill_data, bt_id_name, total ):
def add_annotation(finance, dt, total, delta, text):
tm = dt.timestamp() * 1000
if delta > 0:
if delta >= 0:
text += f": ${int(abs(delta))}"
else:
text += f": -${int(abs(delta))}"
@@ -66,7 +66,7 @@ def calculate_savings_depletion(finance, bill_data, bill_type):
CBA_price = finance['CBA_price']
Ioniq6_future = finance['Ioniq6_future']
### COMPLEX tax implications with my leave I have not taken. It will be taxed in the year I 'quit' ###
### COMPLEX tax implications with my leave I have not taken. It will be taxed in the financial year I 'quit' ###
# leave in days, 10 business days to a fortnight,
# paid before tax I earn $7830.42 / fortnight. Tax on that will be at 37% or $4933.16 after tax
@@ -76,27 +76,30 @@ def calculate_savings_depletion(finance, bill_data, bill_type):
# this is what I now earn before-tax (and I *THINK* vehicle allowance won't be paid X 12 weeks)
pre_tax_D_earning = 8143.65
# whenever I leave, I get 12 weeks (or 60 business days) + whatever leave they owe me
payout = ((60+D_leave_owed_in_days)/bus_days_in_fortnight) * pre_tax_D_earning
# whenever I quit, I get my leave paid out and I get 12 weeks (or 6 pays) -- notice
payout = ((D_leave_owed_in_days/bus_days_in_fortnight) + 6) * pre_tax_D_earning
# just use redundancy calc...
payout = 83115.84
# payout = 83115.84
print( f"leave payout gross={payout}" )
# However, if I quit in the next fin year - tax will be: $4,288 plus 30c for each $1 over $45,000
# (assuming the 7830.42 * ~90/bus_days_in_fortnight = ~ $64k - > 45k and < $135k bracket is 30%)
# (assuming the 7830.42 * ~90/bus_days_in_fortnight = ~ $64k - > 45k and < $135k bracket is 30% OR .37c for $135->$190k)
# - IF I am close to $190k+, just wait a month and quit in new financial year
# Given, I probably can't stop Deakin doing PAYG deductions, I won't get
# the tax back until the end of the financial year, so work out the
# amount of tax I will get back info: tax_diff_D_leave
tax_on_leave = (payout - 45000)*.37 + 4288
# amount of tax I will get back into: tax_diff_D_leave
tax_on_leave = (payout - 45000)*.30 + 4288
D_leave_after_tax = payout - tax_on_leave
# just use redunancy calc...
D_leave_after_tax = 56518.77
print(f"my calc would say D_leave_after_tax = {D_leave_after_tax}" )
# just use quick google/calc - it claims tax rules apply and are capped at 32% - its possible I get more like 75k then pay tax in July?
D_leave_after_tax = 59000
tax_diff_D_leave = payout - D_leave_after_tax
### FIXME: for now, assume no tax back after leave - think this may be needed if I quit anytime nowish until end of Jun
### FIXME: for now, assume no tax back after leave - see above comment
tax_diff_D_leave = 0
print( f"tax_diff_D_leave: {tax_diff_D_leave}")

View File

@@ -1,2 +1,2 @@
# run once every 5 days or so
0 23 2-27/5 * * finplan /code/snapshot.sh
0 23 2-27/5 * * finplan cd /tmp && ENV="production" /code/snapshot.sh

4
db.py
View File

@@ -8,6 +8,8 @@ def connect_db(as_object):
conn = sqlite3.connect('/data/finance.db')
else:
conn = sqlite3.connect('./finance.db')
# allow deleting cset to clear our compare_to properly in finance table
conn.execute("PRAGMA foreign_keys = ON;")
if as_object:
conn.row_factory = sqlite3.Row # This allows us to access columns by name
return conn
@@ -190,7 +192,7 @@ def get_historical_data():
def get_budget_data(finance_data):
# annual bills - health ins (5k), rates (2.6), electricity (1.2), gas (2.1) - but 1.4 in 2025 due to EU trip, internet (1.6), car insurance (.7), rego (.8), house insurance (2.4), GFC (2.6), water (1.1), eweka (.1), phones (.5), melb. pollen (.03), nabu casa (.1) --- noting phone is elevated presuming I also go onto Aldi plan, but that there is no family discount, and health will be extra after stop working
# fudging below - its more like 15.2 + health, and really gas will be more than 2.1 than 1.4, so about 16+5
bills = 25357.07
bills = 25321.03
BUDGET=[]
BUDGET.append( ('Bills', f"${bills:,.2f}") )
BUDGET.append( ('Buffer', f"${finance_data['CBA']*finance_data['CBA_price']+finance_data['TLS']*finance_data['TLS_price']:,.2f}") )

22
main.py
View File

@@ -33,13 +33,18 @@ def index():
bill_types = get_bill_types()
depletion_date, savings_per_fortnight, final_savings = calculate_savings_depletion(finance_data, bill_data, bill_types)
add_historical_annotations( finance_data )
# now sort this by X, then Y, to get the historical ones in the right order
finance_data['annotations'].sort(key=lambda item: (item['x'], item['y']))
BUDGET=get_budget_data(finance_data)
if depletion_date:
depletion_date=depletion_date.date(); # just show date
# if we are comparing...(compare_to will be 0 / None to start with, and then COMP will be None
if finance_data['compare_to']:
COMP=get_comp_set_data(finance_data['compare_to'])
else:
COMP={}
DISP=[]
# Row 1
@@ -48,7 +53,7 @@ def index():
r.append( FP_VAR( 'Savings', 'Savings' ) )
r.append( FP_VAR( 'Car Loan via Pay', 'Car_loan_via_pay', 'readonly' ) )
r.append( FP_VAR( 'Living Expenses', 'Living_Expenses' ) )
r.append( FP_VAR( 'Overseas Trip', 'Overseas_trip', 'date', 'col-auto', 'Overseas_trip_date' ) )
r.append( FP_VAR( 'Overseas Trip', 'Overseas_trip', 'date', 'col', 'Overseas_trip_date' ) )
DISP.append(r)
# Row 2
@@ -57,7 +62,7 @@ def index():
r.append( FP_VAR( 'Interest Rate', 'Interest_Rate' ) )
r.append( FP_VAR( 'Car Loan (monthly)', 'Car_loan', 'readonly' ) )
r.append( FP_VAR( 'Inflation', 'Inflation' ) )
r.append( FP_VAR( 'Reno Costs', 'Mark_reno', 'date', 'col-auto', 'Mark_reno_date' ) )
r.append( FP_VAR( 'Reno Costs', 'Mark_reno', 'date', 'col', 'Mark_reno_date' ) )
DISP.append(r)
# Row 2
@@ -70,7 +75,7 @@ def index():
ss_opt.append( { 'val': el, 'label': f'{el} years' } )
r.append( FP_VAR( 'Sell Shares for:', 'Sell_shares', 'select', 'col-auto', '', ss_opt ) )
r.append( FP_VAR( 'Car Buyout', 'Car_buyout', 'date', 'col-auto', 'Car_buyout_date' ) )
r.append( FP_VAR( 'Car Buyout', 'Car_buyout', 'date', 'col', 'Car_buyout_date' ) )
DISP.append(r)
# Row 3
@@ -112,14 +117,18 @@ def index():
@app.route('/save', methods=['POST'])
def save():
insert_cset( request.get_json() )
return "200"
cset_id=insert_cset( request.get_json() )
name = request.get_json()['vars']['name']
return jsonify( cset_id=cset_id, name=name )
@app.route('/update', methods=['POST'])
def update():
old_finance_data = get_finance_data()
raw_compare_to = request.form.get('compare_to')
compare_to_value = None if raw_compare_to == "0" else int(raw_compare_to)
finance_data = (
request.form['D_Salary'],
request.form['D_Num_fortnights_pay'],
@@ -145,9 +154,10 @@ def update():
request.form['Mark_reno_date'],
request.form['Car_buyout_date'],
request.form['Sell_shares'],
request.form['compare_to'],
compare_to_value,
request.form['Ioniq6_future']
)
update_finance(finance_data)
new_finance_data = get_finance_data()
# changed Ioniq6_future, Car_buyout_date or D_Num_fortnights_pay, so lets force recalc key_dates, and therefore estimated bills

View File

@@ -1,6 +1,10 @@
#!/bin/bash
DB_FILE="finance.db"
if [ "$ENV" == "production" ]; then
DB_FILE="/data/finance.db"
else
DB_FILE="./finance.db"
fi
HISTORY_TABLE="finance_history"
# Current date in the format you've been using
DATE_STR=$(date +%Y-%m-%d)

11
static/favicon.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="16" cy="16" r="16" fill="#1B2E3C"/>
<rect x="9" y="17" width="4" height="7" rx="1" fill="white"/>
<rect x="15" y="14" width="4" height="10" rx="1" fill="white"/>
<rect x="21" y="10" width="4" height="14" rx="1" fill="white"/>
<path d="M8 14L14 9L18 11L25 4" stroke="lightblue" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M21 4H25V8" stroke="lightblue" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 585 B

View File

@@ -14,7 +14,8 @@
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<style>
.col-form-label { width:140px; }
html { font-size: 80%; }
html { font-size: 75% !important; }
@media (max-width: 2000px) { html { font-size: 70% !important; } }
</style>
</head>
<body>
@@ -193,15 +194,17 @@
<span class="bi bi-x"> Cancel</span> </button>
</div>
<div class="d-flex align-items-start">
<!-- create tabbed view for each bill type -->
<nav id="bills-nav" class="nav nav-tabs">
<nav id="bills-nav" class="nav flex-column nav-pills me-3">
{% for bt in bill_types %}
<button class="nav-link" id="tab-but-{{bt.id}}" data-bs-toggle="tab" data-bs-target="#tab-{{bt.id}}" type="button" role="tab" aria-controls="tab1" aria-selected="true" onClick="SaveTab('{{bt.id}}')">{{bt.name}}</button>
<button class="nav-link w-100 text-end col px-1 py-2" id="tab-but-{{bt.id}}" data-bs-toggle="tab" data-bs-target="#tab-{{bt.id}}" type="button" role="tab" aria-controls="tab1" aria-selected="true" onClick="SaveTab('{{bt.id}}')">{{bt.name}}</button>
{% endfor %}
</nav>
<div class="tab-content">
<div class="col-2 form-check form-switch form-check-inline">
<div class="col form-check form-switch form-check-inline">
<input class="form-check-input" type="checkbox" value="" id="showEstimated" onChange="ToggleEstimated()">
<label class="form-check-label" for="flexCheckDefault">Show Estimates</label>
</div>
@@ -214,8 +217,7 @@
{% for bd in bill_data %}
{% if loop.first %}
<div class="row pt-2">
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Name</ ></div>
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Date</ ></div>
<div class="p-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Date</ ></div>
<div class="p-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Amount</ ></div>
<div class="px-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Actions</ ></div>
<div class="px-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0 h-100"></ ></div>
@@ -229,11 +231,11 @@
<div class="row">
{% set classes="form-control text-center" %}
{% endif %}
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-type-{{bd.id}}" value="{{ bd.name }}" disabled> </div>
<input type="hidden" id="bill-data-type-{{bd.id}}" value="{{ bd.name }}"> </input>
{% if bd.bill_date == 'future' %}
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
<div class="px-0 col"> <input type="text" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
{% else %}
<div class="px-0 col-2"> <input type="date" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
<div class="px-0 col"> <input type="date" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
<script>
if( typeof future_id !== 'undefined' && future_id>0) {
first_col_id={{bd.id}}
@@ -259,6 +261,7 @@
</div>
{% endfor %}
</div>
</div>
<script>
function ToggleEstimated()
@@ -453,7 +456,7 @@
function SaveTab( last_tab )
{
// set the drop-down for new bill to be this tab now...
$("#new-bill-data-type").val( $('.nav-tabs .nav-link.active').prop('id').replace("tab-but-", "") )
$("#new-bill-data-type").val( $('.nav-link.active').prop('id').replace("tab-but-", "") )
$.ajax( { type: 'POST', url: '/saveui', contentType: 'application/json', data: JSON.stringify( { 'last_tab': last_tab } ), success: function() { } } )
}

View File

@@ -14,7 +14,8 @@
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<style>
.col-form-label { width:140px; }
html { font-size: 80%; }
html { font-size: 75% !important; }
@media (max-width: 2000px) { html { font-size: 70% !important; } }
</style>
</head>
<body>

View File

@@ -5,19 +5,20 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
<title>Finance Form</title>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/mouse-wheel-zoom.js"></script>
<script src="https://code.highcharts.com/modules/annotations.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<script src="https://code.highcharts.com/themes/adaptive.js"></script>
<style>
.col-form-label { width:140px; }
html { font-size: 75% !important; }
@media (max-width: 2000px) { html { font-size: 70% !important; } }
@media (max-width: 2000px) { html { font-size: 69% !important; } }
</style>
</head>
<body>
@@ -34,7 +35,7 @@
<ul>
<li>Savings (<a href='https://online.macquarie.com.au/personal/#/login'>Macquarie</a>
+<a href='https://ib.mebank.com.au/authR5/ib/login.jsp'>ME bank</a>
+<a href='https://ib.nab.com.au/login'>NAB</a>) -- noting ME bank is: $1000</li>
+<a href='https://ib.nab.com.au/login'>NAB</a>) -- noting ME bank is: $934.07</li>
<li><a href='https://www.google.com/search?q=asx+tls'>TLS</a>/<a href='https://www.google.com/search?q=asx+cba'>CBA</a> prices</li>
<li>Macq <a href='https://www.macquarie.com.au/everyday-banking/savings-account.html'>Interest rate</a></li>
<li><a href='https://deakinpeople.deakin.edu.au/psc/HCMP/EMPLOYEE/HRMS/c/NUI_FRAMEWORK.PT_AGSTARTPAGE_NUI.GBL?CONTEXTIDPARAMS=TEMPLATE_ID%3aPTPPNAVCOL&scname=ADMN_LEAVE&PTPPB_GROUPLET_ID=DU_LEAVE&CRefName=ADMN_NAVCOLL_3'>D_leave_owed_in_days</a> by: {{key_dates['D_quit_date']}}</li>
@@ -229,7 +230,12 @@
$(function() { $('[data-bs-toggle="popover"]').popover(); });
window.onload = function() {
$('#Sell_shares').val( {{finance['Sell_shares']}} )
{% if finance['compare_to'] %}
$('#compare_to').val( {{finance['compare_to']}} )
{% else %}
// set this to Nothing by default
$('#compare_to').val( 0 )
{% endif %}
$('#Ioniq6_future').val( {{finance['Ioniq6_future']}} )
if( $("#Ioniq6_future option:selected"). text() == 'lease' )
@@ -302,11 +308,43 @@
});
const annotations = [];
// offset is used to make the next annotation be on slightly different vertical offsets (size is based on $'s)
// HACK: start at 13, later we adjust in steps of 50s allowing 4 steps, then we go back to top
var offset=13
// this annotation stuff is painful, its in y-coords for the point
// (based on graphs y-axis, but then needs an offset in absolute pixels) so this two coord systems makes it hard to keep the labels going, there
// are a few hacks below that probably will break if the data changes too much
var last_y = {{finance['annotations'][0]['y']}}
var how_many_up = 0
var how_many_down = 0
var offset_y = 0
var offset_x = 0
// Add annotations for changes greater than 5000
{% for a in finance['annotations'] %}
{% if '-$' in a['label'] %}
how_many_down += 1
offset_y = ({{a['y']}} - last_y)/650 + 25*how_many_down
offset_x = -60-10*how_many_down
if( how_many_down > 12 )
how_many_down =0
// console.log( "{{a['label']}} U:" + how_many_up + ", D: " + how_many_down + ", last_y=" + last_y + ", y={{a['y']}}, offset_y=" + offset_y + ", offset_x=" + offset_x )
last_y = {{a['y']}}
{% else %}
how_many_up += 1
offset_y = -25
{% if a['y'] > 400000 %}
offset_x = -80 -30*(6-how_many_up)
{% else %}
offset_x = -50 -10*how_many_up
{% endif %}
if( how_many_up > 3 )
how_many_up=0
{% endif %}
{% if a['y'] < 250000 %}
offset_y -= 350
{% endif %}
{% if a['y'] < 250000 and a['y'] > 200000 %}
offset_x += 100
{% endif %}
annotations.push({
labels: [{
point: {
@@ -316,26 +354,17 @@
xAxis: 0,
yAxis: 0
},
x: -70,
{% if '-$' in a['label'] %}
y: offset,
{% else %}
y: -20,
{% endif %}
x: offset_x,
y: offset_y,
text: '{{a['label']}}'
}], labelOptions: { allowOverlap: true }
});
{% if a['y'] > 200000 %}
offset = ({{loop.index}} * 50 % 200) +50
{% else %}
offset = -100
{% endif %}
{% endfor %}
document.keep = annotations
// Highcharts configuration
Highcharts.chart('graph', {
chart: { type: 'line' },
chart: { type: 'line', zooming: { type: 'x' } },
colors: [ 'orange' ],
title: { text: 'Savings Over Time' },
xAxis: {
@@ -362,7 +391,7 @@
{% if COMP %}
// Highcharts configuration
Highcharts.chart('graph-comp', {
chart: { type: 'line' },
chart: { type: 'line', zooming: { type: 'x' } },
colors: [
'orange', // Custom color 1
'cyan', // Custom color 2
@@ -416,7 +445,11 @@
url: '/save',
contentType: 'application/json',
data: JSON.stringify({ 'vars': vars, 'savings_data': savingsData }),
success: function() { $('#save_modal').modal('hide'); } } )"
success: function(resp) {
$('#save_modal').modal('hide');
$('#compare_to').append($('<option>', { value: resp.cset_id, text: resp.name }));
}
});"
>Save</button>
</div>
</div>