comparison now works as required
This commit is contained in:
@@ -22,6 +22,6 @@
|
|||||||
2025-11-12,410660.56,2026-10-14,337111.91,2027-10-13,238202.3,2028-10-11,191045.16,2029-10-10,137624.31,2030-10-09,55704.53,,,,,,,Overseas_trip_date,2025-06-01
|
2025-11-12,410660.56,2026-10-14,337111.91,2027-10-13,238202.3,2028-10-11,191045.16,2029-10-10,137624.31,2030-10-09,55704.53,,,,,,,Overseas_trip_date,2025-06-01
|
||||||
2025-11-26,406370.89,2026-10-28,322702.74,2027-10-27,234658.94,2028-10-25,187361.11,2029-10-24,133793.99,2030-10-23,51722.12,,,,,,,Mark_reno_date,2025-09-01
|
2025-11-26,406370.89,2026-10-28,322702.74,2027-10-27,234658.94,2028-10-25,187361.11,2029-10-24,133793.99,2030-10-23,51722.12,,,,,,,Mark_reno_date,2025-09-01
|
||||||
2025-12-10,381758.47,2026-11-11,319692.08,2027-11-10,232115.41,2028-11-08,184475.65,2029-11-07,130534.62,2030-11-06,47961.98,,,,,,,Sell_shares,6
|
2025-12-10,381758.47,2026-11-11,319692.08,2027-11-10,232115.41,2028-11-08,184475.65,2029-11-07,130534.62,2030-11-06,47961.98,,,,,,,Sell_shares,6
|
||||||
2025-12-24,377458.1,2026-11-25,270448.27,2027-11-24,228560.53,2028-11-22,180779.63,2029-11-21,126691.85,2030-11-20,43966.63,,,,,,
|
2025-12-24,377458.1,2026-11-25,270448.27,2027-11-24,228560.53,2028-11-22,180779.63,2029-11-21,126691.85,2030-11-20,43966.63,,,,,,CBA,0
|
||||||
,,2026-12-09,268232.01,2027-12-08,225946.99,2028-12-06,177828.21,2029-12-05,123371.23,2030-12-04,40153.28,,,,,,
|
,,2026-12-09,268232.01,2027-12-08,225946.99,2028-12-06,177828.21,2029-12-05,123371.23,2030-12-04,40153.28,,,,,,TLS,0
|
||||||
,,2026-12-23,264801.78,2027-12-22,222380.56,2028-12-20,174120.17,2029-12-19,119515.97,2030-12-18,36144.95,,,,,,
|
,,2026-12-23,264801.78,2027-12-22,222380.56,2028-12-20,174120.17,2029-12-19,119515.97,2030-12-18,36144.95,,,,,,
|
||||||
|
|||||||
|
8
README
8
README
@@ -1,12 +1,4 @@
|
|||||||
TODO:
|
TODO:
|
||||||
* compare feature
|
|
||||||
[done] -- decided this is best supported by removing export to CSV function, and instead offering export to comparisons database (with a user-defined name)
|
|
||||||
[done] -- then maintain DB of "sets" of comparisons
|
|
||||||
[done] -- then can allow graph compare of current data to 1 (or more) exported comparions set
|
|
||||||
-- and show differences in graph including visually of any var changes in legend / or with tooltips
|
|
||||||
- specifically legend is not working
|
|
||||||
- tooltip (for legend?) not working
|
|
||||||
- highlighting differences in vars at top (maybe via colour of label? and a tooltip?)
|
|
||||||
* make save button create a comparison set to use
|
* make save button create a comparison set to use
|
||||||
(also consider how to clean / re-create db initial values from code -- easily could just drop/recreate per table, and only drop finance, not csets)
|
(also consider how to clean / re-create db initial values from code -- easily could just drop/recreate per table, and only drop finance, not csets)
|
||||||
* then delete export button
|
* then delete export button
|
||||||
|
|||||||
8
db.py
8
db.py
@@ -62,7 +62,9 @@ def init_db():
|
|||||||
CBA_price REAL,
|
CBA_price REAL,
|
||||||
Overseas_trip_date STRING,
|
Overseas_trip_date STRING,
|
||||||
Mark_reno_date STRING,
|
Mark_reno_date STRING,
|
||||||
Sell_shares INTEGER
|
Sell_shares INTEGER,
|
||||||
|
CBA INTEGER,
|
||||||
|
TLS INTEGER
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
cur.execute('''CREATE TABLE IF NOT EXISTS comparison_savings_data (
|
cur.execute('''CREATE TABLE IF NOT EXISTS comparison_savings_data (
|
||||||
@@ -153,13 +155,13 @@ def insert_cset( data ):
|
|||||||
name, D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay,
|
name, D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay,
|
||||||
Car_loan, Car_balloon, Living_Expenses, Savings, Interest_Rate, Inflation, Mich_present,
|
Car_loan, Car_balloon, Living_Expenses, Savings, Interest_Rate, Inflation, Mich_present,
|
||||||
Overseas_trip, Mark_reno, D_leave_owed_in_days, D_TLS_shares, M_TLS_shares, D_CBA_shares,
|
Overseas_trip, Mark_reno, D_leave_owed_in_days, D_TLS_shares, M_TLS_shares, D_CBA_shares,
|
||||||
TLS_price, CBA_price, Overseas_trip_date, Mark_reno_date, Sell_shares
|
TLS_price, CBA_price, Overseas_trip_date, Mark_reno_date, Sell_shares, CBA, TLS
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
:name, :D_Salary, :D_Num_fortnights_pay, :School_Fees, :Car_loan_via_pay,
|
:name, :D_Salary, :D_Num_fortnights_pay, :School_Fees, :Car_loan_via_pay,
|
||||||
:Car_loan, :Car_balloon, :Living_Expenses, :Savings, :Interest_Rate, :Inflation, :Mich_present,
|
:Car_loan, :Car_balloon, :Living_Expenses, :Savings, :Interest_Rate, :Inflation, :Mich_present,
|
||||||
:Overseas_trip, :Mark_reno, :D_leave_owed_in_days, :D_TLS_shares, :M_TLS_shares, :D_CBA_shares,
|
:Overseas_trip, :Mark_reno, :D_leave_owed_in_days, :D_TLS_shares, :M_TLS_shares, :D_CBA_shares,
|
||||||
:TLS_price, :CBA_price, :Overseas_trip_date, :Mark_reno_date, :Sell_shares
|
:TLS_price, :CBA_price, :Overseas_trip_date, :Mark_reno_date, :Sell_shares, :CBA, :TLS
|
||||||
)
|
)
|
||||||
''', data['vars'])
|
''', data['vars'])
|
||||||
cset_id = cur.lastrowid
|
cset_id = cur.lastrowid
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
<title>Finance Form</title>
|
<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.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/highcharts.js"></script>
|
||||||
<script src="https://code.highcharts.com/modules/annotations.js"></script>
|
<script src="https://code.highcharts.com/modules/annotations.js"></script>
|
||||||
@@ -21,24 +23,43 @@
|
|||||||
{% for r in DISP %}
|
{% for r in DISP %}
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
{% for el in r %}
|
{% for el in r %}
|
||||||
|
{% if COMP and COMP['vars'][el.varname] != finance[el.varname] %}
|
||||||
|
{% set extra=" text-primary" %}
|
||||||
|
{% else %}
|
||||||
|
{% set extra="" %}
|
||||||
|
{% endif %}
|
||||||
<div class="{{el.cl}}">
|
<div class="{{el.cl}}">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
<label for="{{el.varname}}"
|
||||||
{% if el.display=="select" %}
|
{% if el.display=="select" %}
|
||||||
<label for="{{el.varname}}" class="col-form-label me-2 text-end float-end">{{el.label}}</label>
|
{% if COMP and COMP['vars'][el.varname] != finance[el.varname] %}
|
||||||
<select class="form-select border border-primary text-primary" id="{{el.varname}}" name="{{el.varname}}" style="width: 120px;" onchange="this.form.submit()">
|
data-bs-toggle="tooltip" title="Comparison was: {{COMP['vars'][el.varname]}}"
|
||||||
|
{% endif %}
|
||||||
|
class="col-form-label me-2 text-end float-end {{extra}}">{{el.label}}
|
||||||
|
</label>
|
||||||
|
<select class="form-select border border-primary text-primary" id="{{el.varname}}" name="{{el.varname}}" style="width: 120px;"
|
||||||
|
onchange="this.form.submit()">
|
||||||
<option value="0">Never</option>
|
<option value="0">Never</option>
|
||||||
{% for el in range( 1,7 ) %}
|
{% for el in range( 1,7 ) %}
|
||||||
<option value="{{el}}">{{el}} years</option>
|
<option value="{{el}}">{{el}} years</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
{% elif el.display=="date" %}
|
{% elif el.display=="date" %}
|
||||||
<label for="{{el.varname}}" class="col-form-label me-2 text-end float-end">{{el.label}}</label>
|
{% if COMP and COMP['vars'][el.varname] != finance[el.varname] %}
|
||||||
|
data-bs-toggle="tooltip" title="Comparison was: {{COMP['vars'][el.varname]}}"
|
||||||
|
{% endif %}
|
||||||
|
class="col-form-label me-2 text-end float-end {{extra}}">{{el.label}}
|
||||||
|
</label>
|
||||||
<input type="number" step="any" class="form-control text-end float-end border border-primary" onchange="this.form.submit()" style="max-width: 120px;"
|
<input type="number" step="any" class="form-control text-end float-end border border-primary" onchange="this.form.submit()" style="max-width: 120px;"
|
||||||
id="{{el.varname}}" name="{{el.varname}}" value="{{ finance[el.varname] }}" {{el.display}}>
|
id="{{el.varname}}" name="{{el.varname}}" value="{{ finance[el.varname] }}" {{el.display}}>
|
||||||
<input type="date" class="form-control text-end float-end border border-primary" id="{{el.datevarname}}" style="max-width: 150px;"
|
<input type="date" class="form-control text-end float-end border border-primary" id="{{el.datevarname}}" style="max-width: 150px;"
|
||||||
name="{{el.datevarname}}" value="{{ finance[el.datevarname] }}" onchange="this.form.submit()">
|
name="{{el.datevarname}}" value="{{ finance[el.datevarname] }}" onchange="this.form.submit()">
|
||||||
{% else %}
|
{% else %}
|
||||||
<label for="{{el.varname}}" class="col-form-label me-2 text-end float-end">{{el.label}}</label>
|
{% if COMP and COMP['vars'][el.varname] != finance[el.varname] %}
|
||||||
|
data-bs-toggle="tooltip" title="Comparison was: {{COMP['vars'][el.varname]}}"
|
||||||
|
{% endif %}
|
||||||
|
class="col-form-label me-2 text-end float-end {{extra}}">{{el.label}}
|
||||||
|
</label>
|
||||||
{% if el.display== "readonly" %}
|
{% if el.display== "readonly" %}
|
||||||
{% set bg="bg-light" %}
|
{% set bg="bg-light" %}
|
||||||
{% set bd="" %}
|
{% set bd="" %}
|
||||||
@@ -99,7 +120,8 @@
|
|||||||
<div class="alert alert-success">Super kicks in!!!</div>
|
<div class="alert alert-success">Super kicks in!!!</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if COMP %}
|
{% if COMP %}
|
||||||
<div class="alert alert-info">Note: value in blue<br>above is value we<br>should have been<br>at when comparing<br> to saved values</div>
|
<div style="width:168px" class="alert alert-info">Note: The blue $ figure above is the final value of compared to set. Hover over blue labels above to see what compared to value was</div>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@@ -146,6 +168,9 @@
|
|||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
$('#Sell_shares').val( {{finance['Sell_shares']}} )
|
$('#Sell_shares').val( {{finance['Sell_shares']}} )
|
||||||
$('#compare_to').val( {{finance['compare_to']}} )
|
$('#compare_to').val( {{finance['compare_to']}} )
|
||||||
|
|
||||||
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll("[data-bs-toggle='tooltip']"))
|
||||||
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl) })
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
@@ -157,14 +182,12 @@
|
|||||||
const compChartData = compSavingsData.map(entry => [new Date(entry[0]).getTime(), parseFloat(entry[1])]);
|
const compChartData = compSavingsData.map(entry => [new Date(entry[0]).getTime(), parseFloat(entry[1])]);
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
// Get the legend name and vars for the tooltip
|
// Get the legend name and vars for the tooltip
|
||||||
const legendName = 'Savings';
|
const legendName = 'Savings';
|
||||||
const vars = JSON.parse('{{ finance | tojson }}');
|
const vars = JSON.parse('{{ finance | tojson }}');
|
||||||
|
|
||||||
// Tooltip content from vars
|
// Tooltip content from vars
|
||||||
const tooltipContent = Object.entries(vars).map(([key, value]) => `${key}: ${value}`).join('<br>');
|
const tooltipContent = Object.entries(vars).map(([key, value]) => `${key}: ${value}`).join('<br>');
|
||||||
console.log(tooltipContent)
|
|
||||||
|
|
||||||
// Calculate plot bands for each year with alternating background colors
|
// Calculate plot bands for each year with alternating background colors
|
||||||
const plotBands = [];
|
const plotBands = [];
|
||||||
@@ -194,6 +217,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const annotations = [];
|
const annotations = [];
|
||||||
|
// the al, x, offset are used to make the altenrate annotations be on slightly different vertical offsets (size is based on $'s)
|
||||||
|
// al alternates every 2 annotations left / right (so 2 left, then 2 right), x is just used to also move the label more left/right to get the connecting line
|
||||||
var offset=13
|
var offset=13
|
||||||
var al='left'
|
var al='left'
|
||||||
var x=-130
|
var x=-130
|
||||||
@@ -218,7 +243,7 @@
|
|||||||
});
|
});
|
||||||
if( offset == 150 ) { offset=100 } else { offset=150 }
|
if( offset == 150 ) { offset=100 } else { offset=150 }
|
||||||
if( done == 2 ) {
|
if( done == 2 ) {
|
||||||
if( al=='right' ) { console.log('change to left'); al='left'; x=-130 } else { console.log('change to right'); al='right'; x=130 }
|
if( al=='right' ) { al='left'; x=-130 } else { al='right'; x=130 }
|
||||||
done=0
|
done=0
|
||||||
}
|
}
|
||||||
done++
|
done++
|
||||||
@@ -236,13 +261,12 @@
|
|||||||
plotBands: plotBands // Alternating background for years
|
plotBands: plotBands // Alternating background for years
|
||||||
},
|
},
|
||||||
yAxis: { title: { text: 'Amount ($)' } },
|
yAxis: { title: { text: 'Amount ($)' } },
|
||||||
legend: { labelFormatter: function () { return `<span title="${tooltipContent}">${legendName}</span>`; } },
|
|
||||||
tooltip: { pointFormat: '{point.x:%Y-%m-%d}: <b>{point.y:.2f}</b>' },
|
tooltip: { pointFormat: '{point.x:%Y-%m-%d}: <b>{point.y:.2f}</b>' },
|
||||||
annotations: annotations, // Add annotations
|
annotations: annotations, // Add annotations
|
||||||
series: [
|
series: [
|
||||||
{ name: legendName, data: chartData, marker: { radius: 2 } }
|
{ name: "Savings", data: chartData, marker: { radius: 2 } }
|
||||||
{% if COMP %}
|
{% if COMP %}
|
||||||
,{ name: "TEST", data: compChartData, marker: { radius: 2 } }
|
,{ name: "{{COMP['vars']['name']}}", data: compChartData, marker: { radius: 2 } }
|
||||||
{% endif %}
|
{% endif %}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user