1
0
mirror of https://github.com/elisspace/FxLifeSheet.git synced 2026-08-29 15:44:00 +00:00

Further implement graphs

This commit is contained in:
Felix Krause
2020-12-05 00:39:34 -05:00
parent 3c4702272a
commit 6d43eb97fc
3 changed files with 180 additions and 43 deletions

View File

@@ -4,18 +4,30 @@ require "date"
class API
def fetch(key:, group_by:, start_date:)
#
# Modify and verify parameters
#
group_by = "year#{group_by}" unless group_by.include?("year")
group_by = group_by.to_sym
raise "Invalid group_by" unless [:yearmonth, :yearweek].include?(group_by)
# TODO: Filter start date
results = database.fetch("SELECT ?, AVG(value::numeric) as avg from raw_data where key = ? GROUP BY ? ORDER BY ?", group_by, key, group_by, group_by)
raise "`start_date` must be in format '2019-04'" unless start_date.match(/\d\d\d\d\-\d\d/)
start_timestamp = Date.strptime(start_date, "%Y-%m").strftime("%Q")
#
# Run the query
#
results = database.fetch("SELECT ?, AVG(value::numeric) as avg, SUM(value::numeric) as sum from raw_data where key = ? AND timestamp > ? GROUP BY ? ORDER BY ?", group_by, key, start_timestamp, group_by, group_by)
#
# Return the results
#
return {
total_count: raw_data.where(key: key).count,
grouped_count: results.count,
rows: results.to_a.collect do |row|
row[:avg] = row[:avg].truncate(5).to_s('F').to_f # convert from BigFloat to float
row[:sum] = row[:sum].truncate(5).to_s('F').to_f # convert from BigFloat to float
if group_by == :yearmonth
row[:as_date] = Date.strptime(row[:yearmonth].to_s, "%Y%m")
else

View File

@@ -1,36 +1,126 @@
<html>
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<form>
<select class="keys" id="keys-0" onchange="updateKeys(0)"></select>
<select class="keys" id="keys-1" onchange="updateKeys(1)"></select>
<select class="keys" id="keys-2" onchange="updateKeys(2)"></select>
<select class="keys" id="keys-3" onchange="updateKeys(3)"></select>
<select class="keys" id="keys-4" onchange="updateKeys(4)"></select>
<form id="mainForm" onSubmit="return false;">
<span id="keysContainer">
<table id="keysTable">
<tr>
<th>Key</th>
<th>Avg</th>
</tr>
<tr>
<td><select class="keys" id="keys-0" onchange="updateKeys(0)" /></td>
<td><input type="checkbox" id="keys-avg-0" onchange="updateKeys(0)" checked="checked" /></td>
</tr>
<tr>
<td><select class="keys" id="keys-1" onchange="updateKeys(1)" /></td>
<td><input type="checkbox" id="keys-avg-1" onchange="updateKeys(1)" checked="checked" /></td>
</tr>
<tr>
<td><select class="keys" id="keys-2" onchange="updateKeys(2)" /></td>
<td><input type="checkbox" id="keys-avg-2" onchange="updateKeys(2)" checked="checked" /></td>
</tr>
<tr>
<td><select class="keys" id="keys-3" onchange="updateKeys(3)" /></td>
<td><input type="checkbox" id="keys-avg-3" onchange="updateKeys(3)" checked="checked" /></td>
</tr>
<tr>
<td><select class="keys" id="keys-4" onchange="updateKeys(4)" /></td>
<td><input type="checkbox" id="keys-avg-4" onchange="updateKeys(4)" checked="checked" /></td>
</tr>
</table>
</span>
<span id="attributesContainer">
<h2>Attributes</h2>
<table id="attributesTable">
<tr>
<td>Start date</td>
<td><input type="text" value="2019-04" id="start-date" name="start-date" onchange="updatedAttribute()" /></td>
</tr>
</table>
</span>
</form>
<div id='myDiv' />
<div id='myGraph' />
</body>
<script type="text/javascript">
let host = "http://127.0.0.1:4567"
var keys = []
var allData = []
var allAxis = []
// Multiple axis https://plotly.com/javascript/multiple-axes/
for (let currentIndex of Array(5).keys()) {
let current = {
x: [],
y: [],
name: 'yaxis' + (currentIndex + 1) + ' data',
type: 'scatter',
line: {shape: 'spline'}
}
if (currentIndex > 0) { current["yaxis"] = "y" + (currentIndex + 1) }
allData.push(current)
};
console.log(allData)
var layout = {
title: 'Life Sheet Data'
title: 'Life Sheet Data',
yaxis: {
titlefont: {color: '#1f77b4'},
tickfont: {color: '#1f77b4'},
showgrid: false,
zeroline: false,
showticklabels: false
},
yaxis2: {
titlefont: {color: '#ff7f0e'},
tickfont: {color: '#ff7f0e'},
anchor: 'free',
overlaying: 'y',
showgrid: false,
zeroline: false,
showticklabels: false
},
yaxis3: {
titlefont: {color: '#d62728'},
tickfont: {color: '#d62728'},
anchor: 'x',
overlaying: 'y',
showgrid: false,
zeroline: false,
showticklabels: false
},
yaxis4: {
titlefont: {color: '#9467bd'},
tickfont: {color: '#9467bd'},
anchor: 'free',
overlaying: 'y',
showgrid: false,
zeroline: false,
showticklabels: false
},
yaxis5: {
anchor: 'free',
overlaying: 'y',
showgrid: false,
zeroline: false,
showticklabels: false
},
};
Plotly.newPlot('myDiv', allData, layout);
loadKeys()
loadData("mood", 0)
loadData("weekLifeProgress", 1)
Plotly.newPlot('myGraph', allData, layout);
function loadKeys() {
loadKeys(function() {
loadData("mood", 0)
loadData("mood", 1)
loadData("sleepDurationWithings", 2)
loadData("bedTime", 3)
loadData("gym", 4)
})
function loadKeys(callback) {
httpGetAsync(host + "/keys", function(data) {
selects = document.getElementsByClassName("keys");
for (let i = 0; i < selects.length; i++) {
@@ -41,6 +131,7 @@
selects[i].appendChild(opt);
})
}
callback();
})
}
@@ -49,30 +140,29 @@
loadData(select.value, index)
}
function updatedAttribute() {
for (let currentIndex of Array(5).keys()) {
updateKeys(currentIndex)
}
}
function loadData(key, index) {
httpGetAsync(host + "/data?group_by=month&key=" + key, function(data) {
let newAxis = {
title: 'yaxis ' + key,
titlefont: {color: '#ff7f0e'},
tickfont: {color: '#ff7f0e'},
anchor: 'free',
overlaying: 'y',
// TODO: remove the line below
select = document.getElementById("keys-" + index)
select.value = key
let startDate = document.getElementById("start-date")
httpGetAsync(host + "/data?group_by=month&key=" + key + "&start_date=" + startDate.value, function(data) {
allData[index]["x"] = data.rows.map((r) => r.as_date)
if (document.getElementById("keys-avg-" + index).checked) {
allData[index]["y"] = data.rows.map((r) => Math.round(r.avg * 1000) / 1000)
} else {
allData[index]["y"] = data.rows.map((r) => Math.round(r.sum * 1000) / 1000)
}
layout["yaxis" + index] = newAxis
// Remove item 'seven' from array
// var filteredAry = allData.filter(function(e) { return e[yaxis] == ('y' + index) })
// var filteredAry = ary.filter(e => e !== 'seven')
allData.push({
x: data.rows.map((r) => r.as_date),
y: data.rows.map((r) => r.avg),
name: key,
type: 'scatter',
yaxis: 'y' + index,
})
allData[index]["name"] = key
Plotly.redraw('myDiv')
Plotly.redraw('myGraph')
console.log(allData)
console.log(layout)
})
@@ -91,14 +181,49 @@
</script>
<style type="text/css">
#myDiv {
#myGraph {
width: "100%";
height: 500;
}
.keys {
#keysTable > tbody > tr > th {
padding: 15px;
font-weight: 800;
}
#keysTable > tbody > tr > td {
padding: 5px;
text-align: center;
}
select.keys {
display: block;
height: 35px;
margin: 20px 0px;
height: 40px;
line-height: 40px;
}
#keysContainer {
float: left;
width: 340px;
}
#keysContainer input {
height: 20px;
width: 20px;
}
#keysContainer tr {
margin: 0;
padding: 0;
}
#attributesContainer {
float: right;
width: calc(100% - 550px);
}
#mainForm {
height: 300px;
padding: 20px;
}
* {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
}
td:first-child {
text-align: right;
}
</style>
</html>

View File

@@ -19,7 +19,7 @@ get "/data" do
JSON.pretty_generate(api.fetch(
key: params.fetch("key"),
group_by: params.fetch("group_by", "month"),
start_date: params.fetch("start_date", "2019-04")
start_date: params.fetch("start_date", ENV["DEFAULT_MIN_DATE"].strip)
))
end