|
@@ -1,4 +1,5 @@
|
1
|
1
|
var previousPoint = null;
|
|
2
|
+var state = {};
|
2
|
3
|
var plots = {};
|
3
|
4
|
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
4
|
5
|
|
|
@@ -23,7 +24,35 @@ function getDateKey(date) {
|
23
|
24
|
return date.getFullYear() + '-' + (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1);
|
24
|
25
|
}
|
25
|
26
|
|
26
|
|
-function showSelectedMonths(start, end, incoming, outgoing) {
|
|
27
|
+function expandLinkHandler(event) {
|
|
28
|
+ var text = $(this).text();
|
|
29
|
+ var expanded = text.substr(0, 2) == '(+';
|
|
30
|
+
|
|
31
|
+ if (!state.expanded) {
|
|
32
|
+ state.expanded = {};
|
|
33
|
+ }
|
|
34
|
+
|
|
35
|
+ if (expanded) {
|
|
36
|
+ state.expanded[event.data.id] = true;
|
|
37
|
+ setState({}, []);
|
|
38
|
+ } else {
|
|
39
|
+ delete state.expanded[event.data.id];
|
|
40
|
+ setState({}, []);
|
|
41
|
+ }
|
|
42
|
+
|
|
43
|
+ colourTableRows($('#historytable'));
|
|
44
|
+ return false;
|
|
45
|
+}
|
|
46
|
+
|
|
47
|
+function setState(newState, invalidatedState) {
|
|
48
|
+ $.extend(true, state, newState);
|
|
49
|
+
|
|
50
|
+ $.each(invalidatedState, function(_, x) { delete state[x]; });
|
|
51
|
+
|
|
52
|
+ $.history.load(JSON.stringify(state));
|
|
53
|
+}
|
|
54
|
+
|
|
55
|
+function showSelectedMonths(start, end, incoming, outgoing, categoryFilter) {
|
27
|
56
|
$('#historytable tr.data').remove();
|
28
|
57
|
$('#historytable').show();
|
29
|
58
|
|
|
@@ -58,42 +87,42 @@ function showSelectedMonths(start, end, incoming, outgoing) {
|
58
|
87
|
if (incoming != trans.Amount > 0) { return; }
|
59
|
88
|
|
60
|
89
|
var category = trans.Category ? trans.Category : 'Unsorted';
|
|
90
|
+
|
|
91
|
+ if (category != '(Ignored)') {
|
|
92
|
+ if (!pieData[category]) { pieData[category] = 0; }
|
|
93
|
+ pieData[category] += Math.abs(trans.Amount);
|
|
94
|
+ }
|
|
95
|
+
|
|
96
|
+ if (categoryFilter && categoryFilter != category) { return; }
|
|
97
|
+
|
61
|
98
|
var tr = $('<tr/>').addClass('data').addClass('category' + category.replace(/[^a-zA-Z]*/g, '')).appendTo(table);
|
62
|
99
|
|
63
|
100
|
if (lastEntry.Description == trans.Description && lastEntry.Type == trans.Type && lastEntry.Category == lastEntry.Category) {
|
64
|
101
|
tr.hide();
|
65
|
102
|
|
66
|
103
|
if (lastEntry.id) {
|
|
104
|
+ var prefix = '(' + (state.expanded && state.expanded[lastEntry.id] ? '-' : '+');
|
67
|
105
|
lastEntry.count++;
|
68
|
|
- $('span', lastEntry.tr).text('(+' + lastEntry.count + ')');
|
|
106
|
+ $('span', lastEntry.tr).text(prefix + lastEntry.count + ')');
|
69
|
107
|
} else {
|
70
|
108
|
lastEntry.id = ++id;
|
71
|
109
|
lastEntry.count = 1;
|
72
|
|
- var a = $('<span>').addClass('link').text('(+1)').appendTo($('td.desc', lastEntry.tr).append(' '));
|
73
|
|
- a.data('otherAmount', lastEntry.Amount);
|
74
|
|
- a.bind('click', { id: lastEntry.id, tr: lastEntry.tr }, function(event) {
|
75
|
|
- $('.hidden' + event.data.id).toggle();
|
76
|
|
-
|
77
|
|
- var text = $(this).text();
|
78
|
|
- text = (text.substr(0, 2) == '(+' ? '(-' : '(+') + text.substr(2);
|
79
|
|
- $(this).text(text);
|
80
|
|
-
|
81
|
|
- var amount = $('.amount', event.data.tr);
|
82
|
|
- var oldAmount = amount.text();
|
83
|
|
- amount.text($(this).data('otherAmount'));
|
84
|
|
- $(this).data('otherAmount', oldAmount);
|
85
|
|
-
|
86
|
|
- colourTableRows($('#historytable'));
|
87
|
|
- });
|
|
110
|
+ var prefix = '(' + (state.expanded && state.expanded[lastEntry.id] ? '-' : '+');
|
|
111
|
+ var a = $('<span>').addClass('link').text(prefix + '1)').appendTo($('td.desc', lastEntry.tr).append(' '));
|
|
112
|
+ a.bind('click', { id: lastEntry.id, tr: lastEntry.tr }, expandLinkHandler);
|
88
|
113
|
}
|
89
|
114
|
|
90
|
115
|
lastEntry.Amount = Math.round(100 * (lastEntry.Amount + trans.Amount)) / 100;
|
91
|
|
- $('.amount', lastEntry.tr).text(lastEntry.Amount);
|
|
116
|
+ if (state.expanded && state.expanded[lastEntry.id]) {
|
|
117
|
+ tr.show();
|
|
118
|
+ } else {
|
|
119
|
+ $('.amount', lastEntry.tr).text(lastEntry.Amount);
|
|
120
|
+ }
|
92
|
121
|
|
93
|
122
|
tr.addClass('collapsed hidden' + lastEntry.id);
|
|
123
|
+
|
94
|
124
|
} else {
|
95
|
|
- lastEntry = trans;
|
96
|
|
- lastEntry.tr = tr;
|
|
125
|
+ lastEntry = $.extend({}, trans, {tr: tr});
|
97
|
126
|
}
|
98
|
127
|
|
99
|
128
|
$('<td/>').text(trans.Date.date.split(' ')[0]).appendTo(tr);
|
|
@@ -101,11 +130,6 @@ function showSelectedMonths(start, end, incoming, outgoing) {
|
101
|
130
|
$('<td/>').text(trans.Category ? trans.Category : '').appendTo(tr);
|
102
|
131
|
$('<td/>').addClass('desc').text(trans.Description).appendTo(tr);
|
103
|
132
|
$('<td/>').addClass('amount').text(trans.Amount).appendTo(tr);
|
104
|
|
-
|
105
|
|
- if (category != '(Ignored)') {
|
106
|
|
- if (!pieData[category]) { pieData[category] = 0; }
|
107
|
|
- pieData[category] += Math.abs(trans.Amount);
|
108
|
|
- }
|
109
|
133
|
});
|
110
|
134
|
}
|
111
|
135
|
|
|
@@ -224,27 +248,35 @@ $(function() {
|
224
|
248
|
var startDate = parseInt(ranges.xaxis.from.toFixed());
|
225
|
249
|
var endDate = parseInt(ranges.xaxis.to.toFixed());
|
226
|
250
|
|
227
|
|
- $.history.load('start:' + startDate + ';end:' + endDate + ';type:expenses');
|
|
251
|
+ if (state.start != startDate || state.end != endDate || state.type != 'expenses') {
|
|
252
|
+ setState({ start: startDate, end: endDate, type: 'expenses' }, ['categoryFilter', 'expanded']);
|
|
253
|
+ }
|
228
|
254
|
});
|
229
|
255
|
|
230
|
256
|
$('#history').bind('plotclick', function(event, pos, item) {
|
231
|
257
|
if (item) {
|
232
|
|
- $.history.load('start:' + item.datapoint[0] + ';end:' + item.datapoint[0] + ';type:' + (item.seriesIndex == 0 ? 'income' : 'expenses'));
|
|
258
|
+ setState({ start: item.datapoint[0], end: item.datapoint[0], type: item.seriesIndex == 0 ? 'income' : 'expenses' }, ['categoryFilter', 'expanded']);
|
233
|
259
|
}
|
234
|
260
|
});
|
235
|
261
|
|
236
|
262
|
$('#expense').bind('plotclick', function(event, pos, item) {
|
237
|
|
- $('#historytable .data').hide();
|
238
|
|
- $('#historytable .category' + item.series.label.replace(/[^a-zA-Z]*/g, '')).show();
|
239
|
|
- colourTableRows($('#historytable'));
|
|
263
|
+ setState({ categoryFilter: item.series.label.replace(/ \([0-9]+\)$/, '') }, ['expanded']);
|
240
|
264
|
});
|
241
|
265
|
|
242
|
266
|
$.history.init(function(hash) {
|
|
267
|
+ var oldState = $.extend({}, state);
|
|
268
|
+
|
|
269
|
+ try {
|
|
270
|
+ state = JSON.parse(hash);
|
|
271
|
+ } catch (ex) {
|
|
272
|
+ state = {};
|
|
273
|
+ }
|
|
274
|
+
|
243
|
275
|
var match = /start:([0-9]+);end:([0-9]+);type:(income|expenses)/.exec(hash);
|
244
|
276
|
|
245
|
|
- if (match != null) {
|
246
|
|
- showSelectedMonths(parseInt(match[1]), parseInt(match[2]), match[3] == 'income', match[3] == 'expenses');
|
247
|
|
- plots.history.setSelection({ xaxis: { from: parseInt(match[1]), to: parseInt(match[2]) }});
|
|
277
|
+ if (state.start && state.end && state.type) {
|
|
278
|
+ showSelectedMonths(state.start, state.end, state.type == 'income', state.type == 'expenses', state.categoryFilter);
|
|
279
|
+ (oldState.start != state.start || oldState.end != state.end) && plots.history.setSelection({ xaxis: { from: state.start, to: state.end }});
|
248
|
280
|
}
|
249
|
281
|
});
|
250
|
282
|
});
|