소스 검색

Don't rebuild masses of DOM to expand/collapse nodes

Few minor bug fixes and a bit of tidying
Closes #6
master
Chris Smith 13 년 전
부모
커밋
30077dbad4
1개의 변경된 파일65개의 추가작업 그리고 21개의 파일을 삭제
  1. 65
    21
      analyser.js

+ 65
- 21
analyser.js 파일 보기

@@ -1,5 +1,6 @@
1 1
 var previousPoint = null;
2 2
 var state = {};
3
+var oldState = {};
3 4
 var plots = {};
4 5
 
5 6
 // -----------------------------------------------------------------------------
@@ -131,11 +132,19 @@ function getDataForRange(start, end) {
131 132
  *
132 133
  * @param newState The new properties to add to the state
133 134
  * @param invalidatedState An array of state keys to remove
135
+ * @param invalidatedSubState An map of state subkeys to remove
134 136
  */
135
-function setState(newState, invalidatedState) {
137
+function setState(newState, invalidatedState, invalidatedSubState) {
138
+ oldState = $.extend(true, {}, state);
139
+
136 140
  $.extend(true, state, newState);
137 141
 
138
- $.each(invalidatedState, function(_, x) { delete state[x]; });
142
+ invalidatedState && $.each(invalidatedState, function(_, x) { delete state[x]; });
143
+ invalidatedSubState && $.each(invalidatedSubState, function(key, values) {
144
+  $.each(values, function() {
145
+   delete state[key][this];
146
+  });
147
+ });
139 148
 
140 149
  $.history.load(JSON.stringify(state));
141 150
 }
@@ -147,8 +156,6 @@ function setState(newState, invalidatedState) {
147 156
  * @param {string} hash The new page fragment
148 157
  */
149 158
 function handleStateChange(hash) {
150
- var oldState = $.extend({}, state);
151
-
152 159
  try {
153 160
   state = JSON.parse(hash);
154 161
  } catch (ex) {
@@ -156,8 +163,13 @@ function handleStateChange(hash) {
156 163
  }
157 164
 
158 165
  if (state.start && state.end && state.type) {
159
-  // Update the transaction table and pie charts
160
-  showSelectedMonths(state.start, state.end, state.type == 'income', state.type == 'expenses', state.categoryFilter, state.expanded);
166
+  if (state.start == oldState.start && state.end == oldState.end && state.type == oldState.type && state.categoryFilter == oldState.categoryFilter) {
167
+   // Just show/hide nodes as required
168
+   ensureExpanded(oldState.expanded, state.expanded);
169
+  } else {
170
+   // Update the transaction table and pie charts
171
+   showSelectedMonths(state.start, state.end, state.type == 'income', state.type == 'expenses', state.categoryFilter, state.expanded);
172
+  }
161 173
 
162 174
   // If the selection has changed, update the visual representation
163 175
   (oldState.start != state.start || oldState.end != state.end) && plots.history.setSelection({ xaxis: { from: state.start, to: state.end }});
@@ -205,22 +217,51 @@ function expandLinkHandler(event) {
205 217
  var text = $(this).text();
206 218
  var expanded = text.substr(0, 2) == '(+';
207 219
 
208
- if (!state.expanded) {
209
-  state.expanded = {};
210
- }
211
-
212 220
  if (expanded) {
213
-  state.expanded[event.data.id] = true;
214
-  setState({}, []);
221
+  var newExpanded = {};
222
+  newExpanded[event.data.id] = true;
223
+  setState({expanded: newExpanded}, []);
215 224
  } else {
216
-  delete state.expanded[event.data.id];
217
-  setState({}, []);
225
+  setState({}, [], {expanded: [event.data.id]});
218 226
  }
219 227
 
220 228
  colourTableRows($('#historytable'));
221 229
  return false;
222 230
 }
223 231
 
232
+/**
233
+ * Ensures that the desired elements are appropriately expanded or collapsed.
234
+ *
235
+ * @param oldList A map containing keys for each entry that was previously expanded
236
+ * @param newList A map containing keys for each entry that should now be expanded
237
+ */
238
+function ensureExpanded(oldList, newList) {
239
+ oldList = oldList || {};
240
+ newList = newList || {};
241
+
242
+ $.each(newList, function(id, _) {
243
+  if (!oldList[id]) {
244
+   // This entry needs to be expanded
245
+   $('.hidden' + id).show();
246
+   var handle = $('#collapseHandle' + id);
247
+   handle.text(handle.text().replace(/\+/, '-'));
248
+   handle.parents('tr').find('td.amount').text(handle.data('single'));
249
+  }
250
+ });
251
+
252
+ $.each(oldList, function(id, _) {
253
+  if (!newList[id]) {
254
+   // This entry needs to be collapsed
255
+   $('.hidden' + id).hide();
256
+   var handle = $('#collapseHandle' + id);
257
+   handle.text(handle.text().replace(/\-/, '+'));
258
+   handle.parents('tr').find('td.amount').text(handle.data('total'));
259
+  }
260
+ });
261
+
262
+ colourTableRows($('#historytable'));
263
+}
264
+
224 265
 /**
225 266
  * Determines if the two transactions should be merged together. That is,
226 267
  * whether the transactions have an identical description, type and category.
@@ -280,15 +321,16 @@ function showSelectedMonths(start, end, incoming, outgoing, categoryFilter, expa
280 321
  var lastEntry = {};
281 322
  var id = 0;
282 323
  var included = getDataForRange(startDate, endDate);
324
+ var filtered = $.grep(included, function(x) {
325
+  var category = x.Category ? x.Category : 'Unsorted';
326
+  return (incoming == x.Amount > 0) && (!categoryFilter || categoryFilter == category);
327
+ });
283 328
 
284
- $.each(included, function() {
329
+ $.each(filtered, function() {
285 330
   trans = this;
286
-  if (incoming != trans.Amount > 0) { return; }
287 331
 
288 332
   var category = trans.Category ? trans.Category : 'Unsorted';
289 333
 
290
-  if (categoryFilter && categoryFilter != category) { return; }
291
-
292 334
   var tr = $('<tr/>').addClass('data').addClass('category' + category.replace(/[^a-zA-Z]*/g, '')).appendTo(table);
293 335
 
294 336
   if (shouldMerge(lastEntry, trans)) {
@@ -300,11 +342,13 @@ function showSelectedMonths(start, end, incoming, outgoing, categoryFilter, expa
300 342
     lastEntry.id = ++id;
301 343
     lastEntry.count = 1;
302 344
     var prefix = '(' + (expanded[lastEntry.id] ? '-' : '+');
303
-    var a = $('<span>').addClass('link').text(prefix + '1)').appendTo($('td.desc', lastEntry.tr).append(' '));
304
-    a.bind('click', { id: lastEntry.id, tr: lastEntry.tr }, expandLinkHandler);
345
+    var a = $('<span>').addClass('link').text(prefix + '1)').attr('id', 'collapseHandle' + lastEntry.id).appendTo($('td.desc', lastEntry.tr).append(' '));
346
+    a.bind('click', { id: lastEntry.id }, expandLinkHandler);
347
+    a.data('single', lastEntry.Amount);
305 348
    }
306 349
 
307 350
    lastEntry.Amount = Math.round(100 * (lastEntry.Amount + trans.Amount)) / 100;
351
+   $('#collapseHandle' + lastEntry.id).data('total', lastEntry.Amount);
308 352
 
309 353
    !expanded[lastEntry.id] && tr.hide() && $('.amount', lastEntry.tr).text(lastEntry.Amount);
310 354
 
@@ -425,7 +469,7 @@ $(function() {
425 469
     var date = new Date(x);
426 470
 
427 471
     var seriesTitles = ["Money in", "Money out", "Balance change"];
428
-    showTooltip(item.pageX, item.pageY, (seriesTitles[item.seriesIndex]) + " during " + months[date.getMonth()] + " " + date.getFullYear() + " = " + y);
472
+    showTooltip(item.pageX, item.pageY, (seriesTitles[item.seriesIndex]) + " during " + date.getDisplayMonth() + " " + date.getFullYear() + " = " + y);
429 473
    }
430 474
   } else {
431 475
    $("#tooltip").remove();

Loading…
취소
저장