Budget/waitForChartWindow.js

201 lines
4.7 KiB
JavaScript

var gui = require('gui');
const { getSummation, toStringDate, toDateByComponents, getAccounts } = require('./utils');
function waitForPrefsChartWindow() {
var rh = 14;
var sp = 4;
var y = sp;
let gadgets = [];
gadgets.push({
kind: "string",
left: sp,
width: 80,
top: sp,
height: rh,
label: "from",
value: "01-01-2026"
});
gadgets.push({
kind: "string",
left: sp,
width: 80,
top: sp,
height: rh,
label: "to",
value: toStringDate(new Date())
});
let win = gui.createWindow({
title: "Summary Chart Prefs",
width: sp + 128 + sp,
height: y + rh + sp + rh + sp,
left: 30,
top: 30,
gadgets: gadgets
});
while (true) {
var evt = gui.waitEvent(win);
if (!evt) continue;
if (evt.type === 'close') {
gui.closeWindow(win);
}
}
}
/**
* @typedef Account
* @property {String} name;
* @property {AccountEntry[]} entries;
*/
/**
* @typedef AccountEntry
* @property {Number} date
* @property {String} subject;
* @property {Number} amount;
* @property {String?} targetAccount;
*/
/**
* @typedef DataPoint
* @property {Number} timestamp;
* @property {Number} value;
* @property {String} accountName;
* @property {String} tooltip;
*/
/**
*
* @param {*} gui
* @param {*} win
* @param {Account[]} data
* @param {*} rangeFrom
* @param {*} rangeTo
*/
function renderChart(gui, win, data, /** @type {Date} */ rangeFrom, /** @type {Date} */ rangeTo) {
var rh = 14;
var sp = 4;
var y = sp;
const gfx = gui.gfx;
let datapoints = [];
for (let i = 0; i < data.entries.length;++i) {
datapoints.push({
x: data.entries[i].date,
v: data.entries[i].amount
});
}
// Compute cumulative series and min/max (include 0 to ensure Y=0 is visible)
let cumulative = [];
let cur = 0;
cumulative.push({ x: datapoints[0].x, y: 0 }); // start at 0
let lowest = 0;
let highest = 0;
for (let i = 0; i < datapoints.length; ++i) {
cur += datapoints[i].v;
cumulative.push({ x: datapoints[i].x, y: cur });
if (cur < lowest) lowest = cur;
if (cur > highest) highest = cur;
}
if (0 < lowest) lowest = 0;
if (0 > highest) highest = 0;
const totalW = Math.max(10, 400 - sp * 3);
const totalH = Math.max(10, 180 - sp * 3);
const left = sp;
const top = sp;
const right = left + totalW;
const bottom = top + totalH;
console.log(lowest, highest);
// X and Y ranges
const minX = cumulative[0].x;
const maxX = cumulative[cumulative.length - 1].x;
const xRange = (maxX === minX) ? 1 : (maxX - minX);
let yRange = highest - lowest;
if (yRange === 0) yRange = 1;
// mapping functions
const mapX = x => left + ((x - minX) / xRange) * totalW;
const mapY = y => bottom - ((y - lowest) / yRange) * totalH; // invert Y
// draw Y=0 axis
const y0 = mapY(0);
gfx.setColor(win, 1);
gfx.drawLine(win, left, y0, right, y0);
gfx.setColor(win, 4);
// draw polyline
let last = cumulative[0];
for (let i = 1; i < cumulative.length; ++i) {
let p = cumulative[i];
gfx.drawLine(win, mapX(last.x), mapY(last.y), mapX(p.x), mapY(p.y));
last = p;
}
}
function waitForChartWindow(data) {
var rh = 14;
var sp = 4;
var y = sp;
let gadgets = [];
let rangeTo = new Date(toDateByComponents("31-12-2024"));
let rangeFrom = new Date(toDateByComponents("01-01-" + rangeTo.getFullYear()));
let win = gui.createWindow({
title: "Summary Chart",
width: sp + 400 + sp,
height: y + 180 + sp,
left: 30,
top: 30,
gadgets: gadgets,
});
renderChart(gui, win, data, rangeFrom, rangeTo);
gui.setMenu(win, [
{
title: 'Chart',
items: [
{ label: 'Save', id: 401, key: 'S'},
{ label: 'Close', id: 499, key: 'Q' }
]
},
{
title: 'Prefs',
items: [
{ label: "Set Daterange", id: 404, key: 'D' },
]
}
]);
while (true) {
var evt = gui.waitEvent(win);
if (!evt) continue;
if (evt.type === 'menu') {
}
if (evt.type === 'close') {
gui.closeWindow(win);
return null;
}
}
}
exports.waitForChartWindow = waitForChartWindow;