Added category, added pie chart on categories, removed buggy ba-resize plugin.
This commit is contained in:
parent
6f36d7970f
commit
868cf3138a
@ -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();
|
||||
|
||||
|
@ -33,20 +33,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content" style="margin-top: 116px; margin-bottom: 41px">
|
||||
<div class="row" style="margin-top: 116px"></div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="span8">
|
||||
<div id="chart-placeholder" data-bind="chart: $root.entriesChart"></div>
|
||||
</div>
|
||||
|
||||
<div class="span4"></div>
|
||||
<div class="row">
|
||||
<div class="span8">
|
||||
<div id="entries-chart-placeholder" data-bind="chart: $root.entriesChart"></div>
|
||||
</div>
|
||||
|
||||
<div class="span4">
|
||||
<div id="categories-chart-placeholder" data-bind="pieChart: $root.categoriesChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div id="message-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<a class="btn btn-primary" data-bind="click: $root.add" href="#" title="Add entry"><i class="icon-plus"></i> Ajouter une entrée</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<table class="table table-striped table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -56,6 +64,7 @@
|
||||
<th style="width: 50px">Montant</th>
|
||||
<th style="width: 50px">Solde</th>
|
||||
<th style="width: 50px">Solde pointé</th>
|
||||
<th style="width: 100px">Catégorie</th>
|
||||
<th style="width: 60px">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -64,6 +73,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 21px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -89,6 +100,7 @@
|
||||
<td data-bind="text: value, css: {'text-error': value() < 0 }"></td>
|
||||
<td data-bind="text: sold, css: {'text-error': sold() < 0 }"></td>
|
||||
<td data-bind="text: pointedSold, css: {'text-error': pointedSold() < 0 }"></td>
|
||||
<td data-bind="text: category"></td>
|
||||
<td class="buttons">
|
||||
<a class="btn btn-mini" data-bind="click: $root.edit" href="#" title="edit"><i class="icon-edit"></i></a>
|
||||
<a class="btn btn-mini" data-bind="click: $root.remove" href="#" title="remove"><i class="icon-trash"></i></a>
|
||||
@ -104,6 +116,7 @@
|
||||
<td><input type="text" class="input-mini" data-bind="value: value"/></td>
|
||||
<td data-bind="text: sold"></td>
|
||||
<td data-bind="text: pointedSold"></td>
|
||||
<td><input type="text" class="input-small" data-bind="value: category"/></td>
|
||||
<td class="buttons">
|
||||
<a class="btn btn-mini btn-success" data-bind="click: $root.save" href="#" title="save"><i class="icon-ok"></i></a>
|
||||
<a class="btn btn-mini" data-bind="click: $root.cancel" href="#" title="cancel"><i class="icon-ban-circle"></i></a>
|
||||
@ -112,7 +125,6 @@
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="jquery/jquery.js"></script>
|
||||
<script type="text/javascript" src="jquery/jquery.ba-resize.min.js"></script>
|
||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="datepicker/js/bootstrap-datepicker.js"></script>
|
||||
<script type="text/javascript" src="knockout/knockout.js"></script>
|
||||
@ -122,6 +134,7 @@
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.canvasTextRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.ohlcRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.pieRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.highlighter.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/entries.js"></script>
|
||||
|
9
src/html/jquery/jquery.ba-resize.min.js
vendored
9
src/html/jquery/jquery.ba-resize.min.js
vendored
@ -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);
|
@ -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:'<table class="jqplot-highlighter"><tr><td>date:</td><td>%s</td></tr><tr><td>open:</td><td>%s</td></tr><tr><td>hi:</td><td>%s</td></tr><tr><td>low:</td><td>%s</td></tr><tr><td>close:</td><td>%s</td></tr></table>'
|
||||
},
|
||||
|
||||
// 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:'<table class="jqplot-highlighter"><tr><td>date:</td><td>%s</td></tr><tr><td>open:</td><td>%s</td></tr><tr><td>hi:</td><td>%s</td></tr><tr><td>low:</td><td>%s</td></tr><tr><td>close:</td><td>%s</td></tr></table>'
|
||||
},
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user