diff --git a/src/html/api/entry.php b/src/html/api/entry.php index 2088b9f..e748741 100644 --- a/src/html/api/entry.php +++ b/src/html/api/entry.php @@ -17,7 +17,7 @@ class EntryAPI extends RestAPI { $account=$this->_request['account']; - $statement=$connection->prepare("select id, value_date, operation_date, label, value, account_id, sold, pointedSold from (select *, sum(value) over(order by value_date, operation_date, label desc, value desc) as sold, sum(value) over(partition by operation_date is not null order by value_date, operation_date, label desc, value desc) as pointedSold from entry where account_id=:account order by value_date desc, operation_date desc, label, value) as e where date_trunc('month', e.value_date) = :day "); + $statement=$connection->prepare("select id, value_date, operation_date, label, value, account_id, sold, pointedsold, category from (select *, sum(value) over(order by value_date, operation_date, label desc, value desc) as sold, sum(value) over(partition by operation_date is not null order by value_date, operation_date, label desc, value desc) as pointedSold from entry where account_id=:account order by value_date desc, operation_date desc, label, value) as e where date_trunc('month', e.value_date) = :day "); $statement->bindParam("day", $day); $statement->bindParam("account", $account); @@ -36,9 +36,9 @@ class EntryAPI extends RestAPI { $connection=$this->get_db_connection(); if($entry['id'] != null) { - $statement=$connection->prepare("update entry set value_date=:value_date, operation_date=:operation_date, label=:label, value=:value, account_id=:account where id=:id"); + $statement=$connection->prepare("update entry set value_date=:value_date, operation_date=:operation_date, label=:label, value=:value, account_id=:account, category=:category where id=:id"); } else { - $statement=$connection->prepare("insert into entry (value_date, operation_date, label, value, account_id) values (:value_date, :operation_date, :label, :value, :account)"); + $statement=$connection->prepare("insert into entry (value_date, operation_date, label, value, account_id) values (:value_date, :operation_date, :label, :value, :account, :category)"); } $statement->bindParam("value_date", $entry['value_date']); @@ -47,6 +47,7 @@ class EntryAPI extends RestAPI { $statement->bindParam("value", $entry['value']); $statement->bindParam("account", $entry['account']); $statement->bindParam("id", $entry['id']); + $statement->bindParam("category", $entry['category']); $return=$statement->execute(); diff --git a/src/html/index.html b/src/html/index.html index 8061bdc..13b9701 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -33,20 +33,28 @@ -
+
-
-
-
-
- -
+
+
+
+
+
+
+
+ + +
+
+ +
@@ -56,6 +64,7 @@ + @@ -64,6 +73,8 @@
Montant Solde Solde pointéCatégorie Actions
+ +
@@ -89,6 +100,7 @@ + @@ -104,6 +116,7 @@ + @@ -112,7 +125,6 @@ - @@ -122,6 +134,7 @@ + diff --git a/src/html/jquery/jquery.ba-resize.min.js b/src/html/jquery/jquery.ba-resize.min.js deleted file mode 100644 index c678883..0000000 --- a/src/html/jquery/jquery.ba-resize.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * jQuery resize event - v1.1 - 3/14/2010 - * http://benalman.com/projects/jquery-resize-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this); \ No newline at end of file diff --git a/src/html/js/entries.js b/src/html/js/entries.js index f749eae..0f9c001 100644 --- a/src/html/js/entries.js +++ b/src/html/js/entries.js @@ -7,6 +7,7 @@ function entry(data){ var account = ko.utils.unwrapObservable(data.account); var sold = ko.utils.unwrapObservable(data.sold); var pointedSold = ko.utils.unwrapObservable(data.pointedSold); + var category = ko.utils.unwrapObservable(data.category); this.id=ko.observable(id ? id : null); this.value_date=ko.observable(value_date ? value_date : null); @@ -16,6 +17,7 @@ function entry(data){ this.account=ko.observable(account ? account : null); this.sold=ko.observable(sold ? sold : null); this.pointedSold=ko.observable(pointedSold ? pointedSold : null); + this.category=ko.observable(category ? category : null); } function message(alertType, title, message) { @@ -34,17 +36,41 @@ var ListViewModel = function() { self.months = ko.observableArray(); self.month = ko.observable(); - self.pointedSold = ko.observable(); - self.futureSold = ko.observable(); - self.currentSold = ko.observable(); - self.selectedItem = ko.observable(); self.savedItem = ko.observable(); self.itemToRemove = ko.observable(); self.chart = null; + self.categoriesChart = ko.computed(function() { + var entries=ko.utils.unwrapObservable(self.entries); + + var chartValues = []; + var chartValuesTmp = {}; + + $.each(entries, function(index, entry) { + var category = entry.category(); + var value = entry.value() ? Number(entry.value()) : null; + + if(category && value) { + var oldValue = 0.0; + + if(chartValuesTmp[category]) { + oldValue = chartValuesTmp[category]; + } + + chartValuesTmp[category] = oldValue - value + } + }); + + $.each(chartValuesTmp, function(key, value) { + chartValues.push([key, value]); + }); + + return chartValues; + }); + self.entriesChart = ko.computed(function() { - var entries = self.entries().slice().reverse(); + var entries = ko.utils.unwrapObservable(self.entries).slice().reverse(); var chartValues = []; var chartValuesTmp = {}; @@ -113,7 +139,8 @@ var ListViewModel = function() { value: element.value, account: element.account_id, sold: element.sold, - pointedSold: element.operation_date ? element.pointedsold : '' + pointedSold: element.operation_date ? element.pointedsold : '', + category: element.category })); }); @@ -357,64 +384,84 @@ ko.bindingHandlers.dateValue = { }; drawChart = function(entries, element) { - if(entries && entries.length > 0) { - var firstDate, lastDate; - var chartValues = [[], []]; + // clear previous chart + $(element).html(""); - var day = 24 * 60 * 60 * 1000; + if(entries && entries.length > 0) { + var day = 24 * 60 * 60 * 1000; - lastDate = new Date(Date.parse(entries[entries.length -1][0]).valueOf() + 1 * day); - firstDate = new Date(Date.parse(entries[0][0]).valueOf() - 1 * day); + var lastDate = new Date(Date.parse(entries[entries.length -1][0]).valueOf() + 1 * day); + var firstDate = new Date(Date.parse(entries[0][0]).valueOf() - 1 * day); + var chartValues = [[], []]; - // For the '0' line. - chartValues[0].push( - [new Date(firstDate.valueOf()).toString(), 0], - [new Date(lastDate.valueOf()).toString(), 0]); + // For the '0' line. + chartValues[0].push( + [new Date(firstDate.valueOf()).toString(), 0], + [new Date(lastDate.valueOf()).toString(), 0]); - // Push last entry - chartValues[1] = entries; + chartValues[1] = entries; - // clear previous chart - $(element).html(""); - $(element).resize(); + // plot chart + window.chart = $.jqplot(element.id, chartValues, { + axes:{ + xaxis:{ + renderer:$.jqplot.DateAxisRenderer, + tickOptions: {formatString: "%F"} + }, + yaxis: { + autoscale: true, + } + }, + highlighter: { + show:true, + yvalues: 4, + formatString:'
date:%s
open:%s
hi:%s
low:%s
close:%s
' + }, - // plot chart - jqplot = $.jqplot(element.id, chartValues, { - axes:{ - xaxis:{ - renderer:$.jqplot.DateAxisRenderer, - tickOptions: {formatString: "%F"} - }, - yaxis: { - autoscale: true, - //tickOptions: {formatString: "%f"} - } - }, - highlighter: { - show:true, - //tooltipAxes: 'y', - yvalues: 4, - formatString:'
date:%s
open:%s
hi:%s
low:%s
close:%s
' - }, + series: [{ + linePattern: "dashed", + lineWidth: 1, + color: "red", + showMarker: false + },{ + renderer:$.jqplot.OHLCRenderer, + color: "blue", + lineWidth: 3, + rendererOptions:{ + }}], + }); + } +}; - series: [{ - linePattern: "dashed", - lineWidth: 1, - color: "red", - showMarker: false - },{ - renderer:$.jqplot.OHLCRenderer, - color: "blue", - lineWidth: 3, - rendererOptions:{ - //candleStick: true - }}], - });//*/ +drawPieChart = function(entries, element) { + // clear previous chart + $(element).html(""); - $(element).resize(function() { - jqplot.replot({resetAxes: true}); - }); - } + if(entries && entries.length > 0) { + var chartValues = [[]]; + + chartValues[0] = entries; + + // plot chart + window.pieChart = $.jqplot(element.id, chartValues, { + seriesDefaults: { + renderer: $.jqplot.PieRenderer, + rendererOptions: { + showDataLabels: true + } + }, + legend: { + show: true, + location: 'e' + }, + highlighter: { + show: true, + formatString:'%s: %s', + tooltipLocation:'sw', + useAxesFormatters:false + } + }); + } }; ko.bindingHandlers.chart = { @@ -432,10 +479,35 @@ ko.bindingHandlers.chart = { } }; +ko.bindingHandlers.pieChart = { + init: function (element, valueAccessor, allBindingsAccessor, viewModel) { + // empty - left as placeholder if needed later + }, + + update: function (element, valueAccessor, allBindingsAccessor, viewModel) { + var unwrap = ko.utils.unwrapObservable; + var dataSource = valueAccessor(); + + //var entries = dataSource ? unwrap(dataSource) : null; + var entries = dataSource ? unwrap(dataSource) : null; + drawPieChart(entries, element); + } +}; + $(document).ajaxError(function(event, xhr, settings) { message("error", "Error.", xhr.statusText); }); +$(window).resize(function() { + if(window.chart) { + window.chart.replot({resetAxes: true}); + } + + if(window.chart) { + window.pieChart.replot({resetAxes: true}); + } +}); + var viewModel = new ListViewModel(); ko.applyBindings(viewModel); diff --git a/src/sql/01_init.sql b/src/sql/01_init.sql index 82112ed..7d360f3 100644 --- a/src/sql/01_init.sql +++ b/src/sql/01_init.sql @@ -12,7 +12,8 @@ CREATE TABLE "entry" ( "label" VARCHAR(500) NOT NULL, "comment" VARCHAR(500), "value" NUMERIC(15,4) NOT NULL, - "account_id" INTEGER NOT NULL REFERENCES "account"("id") + "account_id" INTEGER NOT NULL REFERENCES "account"("id"), + "category" VARCHAR(100), ); CREATE INDEX on entry(value_date);