PHP/JavaScript webapp to analyse spending habits
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Spending Analyser</title>
  5. <script src="externals/flot/jquery.js" type="text/javascript"></script>
  6. <script src="externals/flot/jquery.flot.js" type="text/javascript"></script>
  7. <script src="externals/flot/jquery.flot.pie.js" type="text/javascript"></script>
  8. <script src="data.php" type="text/javascript"></script>
  9. <script type="text/javascript">
  10. var previousPoint = null;
  11. var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  12. function showTooltip(x, y, contents) {
  13. $('<div id="tooltip">' + contents + '</div>').css( {
  14. position: 'absolute',
  15. display: 'none',
  16. top: y + 5,
  17. left: x + 5,
  18. border: '1px solid #fdd',
  19. padding: '2px',
  20. 'background-color': '#fee',
  21. }).appendTo("body").fadeIn(200);
  22. }
  23. $(function() {
  24. var transData = [{label: 'Income', data: []}, {label: 'Expense', data: []}];
  25. $.each(data, function(month, entries) {
  26. var split = month.split('-');
  27. var timestamp = new Date(split[0], split[1] - 1).getTime();
  28. var sum = [0, 0];
  29. $.each(entries, function() {
  30. if (this.Category == '(Ignored)') { return; }
  31. sum[this.Amount < 0 ? 1 : 0] += this.Amount;
  32. });
  33. transData[0].data.push([timestamp, sum[0]]);
  34. transData[1].data.push([timestamp, sum[1]]);
  35. });
  36. $.plot($('#history'), transData, {
  37. xaxis: { mode: 'time', timeformat: '%y/%m'},
  38. series: {
  39. lines: { show: true },
  40. points: { show: true }
  41. },
  42. grid: { hoverable: true, clickable: true },
  43. });
  44. $("#history").bind("plothover", function (event, pos, item) {
  45. if (item) {
  46. var id = {dataIndex: item.dataIndex, seriesIndex: item.seriesIndex};
  47. if (previousPoint == null || previousPoint.dataIndex != id.dataIndex || previousPoint.seriesIndex != id.seriesIndex) {
  48. previousPoint = id;
  49. $("#tooltip").remove();
  50. var x = item.datapoint[0],
  51. y = item.datapoint[1].toFixed(2);
  52. var date = new Date(x);
  53. showTooltip(item.pageX, item.pageY,
  54. (item.seriesIndex == 0 ? "Money in" : "Money out") + " during " + months[date.getMonth()] + " " + date.getFullYear() + " = " + y);
  55. }
  56. } else {
  57. $("#tooltip").remove();
  58. previousPoint = null;
  59. }
  60. });
  61. $('#history').bind('plotclick', function(event, pos, item) {
  62. if (item) {
  63. var incoming = item.seriesIndex == 0;
  64. var dateOb = new Date(item.datapoint[0]);
  65. var date = dateOb.getFullYear() + '-' + (dateOb.getMonth() < 9 ? '0' : '') + (dateOb.getMonth() + 1);
  66. $('#historytable tr.data').remove();
  67. $('#historytable').show();
  68. $('#historytable h3').text('Transactions for ' + months[dateOb.getMonth()] + ' ' + dateOb.getFullYear());
  69. var pieData = {};
  70. var table = $('#historytable table');
  71. $.each(data[date], function(index, trans) {
  72. if (incoming != trans.Amount > 0) { return; }
  73. var tr = $('<tr/>').addClass('data').appendTo(table);
  74. trans.Category && trans.Category == '(Ignored)' && tr.addClass('ignored');
  75. $('<td/>').text(trans.Date.date.split(' ')[0]).appendTo(tr);
  76. $('<td/>').text(trans.Type ? trans.Type : 'Other').appendTo(tr);
  77. $('<td/>').text(trans.Category ? trans.Category : '').appendTo(tr);
  78. $('<td/>').text(trans.Description).appendTo(tr);
  79. $('<td/>').text(trans.Amount).appendTo(tr);
  80. var category = trans.Category ? trans.Category : 'Unsorted';
  81. if (category != '(Ignored)') {
  82. if (!pieData[category]) { pieData[category] = 0; }
  83. pieData[category] += Math.abs(trans.Amount);
  84. }
  85. });
  86. var seriesData = [];
  87. $.each(pieData, function(category, amount) {
  88. seriesData.push({ label: category + ' (' + Math.round(amount) + ')', data: amount });
  89. });
  90. seriesData.sort(function(a, b) { return b.data - a.data; });
  91. $.plot($('#expense'), seriesData, {
  92. series: { pie: { show: true, innerRadius: 0.5 } }
  93. });
  94. }
  95. });
  96. });
  97. </script>
  98. <style type="text/css">
  99. .ignored td { color: gray; }
  100. .left { width: 45%; float: left; }
  101. .right { margin-left: 50%; }
  102. h2 { margin-top: 0; }
  103. </style>
  104. </head>
  105. <body>
  106. <div class="left">
  107. <h2>Transaction History</h2>
  108. <div id="history" style="width: 600px; height: 300px;"></div>
  109. <div id="historytable" style="display: none;"><h3>Transactions for ??</h3><table><tr><th>Date</th><th>Type</th><th>Category</th><th>Description</th><th>Amount</th></tr></table></div>
  110. </div>
  111. <div class="right">
  112. <h2>Categories</h2>
  113. <div id="expense" style="width: 600px; height: 300px;"></div>
  114. </div>
  115. </body>
  116. </html>