[IMP] account: improve account_contract_dashboard
Mainly style and js improvements for graphs
This commit is contained in:
@@ -87,7 +87,7 @@ class account_journal(models.Model):
|
||||
short_name = format_date(show_date, 'd MMM', locale=locale)
|
||||
data.append({'x': short_name, 'y':last_balance, 'name': name})
|
||||
|
||||
return [{'values': data, 'color': '#ff7f0e', 'area': True}]
|
||||
return [{'values': data, 'area': True}]
|
||||
|
||||
@api.multi
|
||||
def get_bar_graph_datas(self):
|
||||
@@ -96,7 +96,7 @@ class account_journal(models.Model):
|
||||
if self.type == 'purchase':
|
||||
title = _('Bills you need to pay')
|
||||
today = datetime.strptime(fields.Date.context_today(self), DF)
|
||||
data.append({'label': _('Past'), 'value':0.0, 'color': '#ff0000'})
|
||||
data.append({'label': _('Past'), 'value':0.0, 'type': 'past'})
|
||||
day_of_week = int(format_datetime(today, 'e', locale=self._context.get('lang', 'en_US')))
|
||||
first_day_of_week = today + timedelta(days=-day_of_week+1)
|
||||
for i in range(-1,4):
|
||||
@@ -111,7 +111,7 @@ class account_journal(models.Model):
|
||||
label = str(start_week.day) + '-' +str(end_week.day)+ ' ' + format_date(end_week, 'MMM', locale=self._context.get('lang', 'en_US'))
|
||||
else:
|
||||
label = format_date(start_week, 'd MMM', locale=self._context.get('lang', 'en_US'))+'-'+format_date(end_week, 'd MMM', locale=self._context.get('lang', 'en_US'))
|
||||
data.append({'label':label,'value':0.0, 'color': '#ff0000' if i<0 else '#ff7f0e'})
|
||||
data.append({'label':label,'value':0.0, 'type': 'past' if i<0 else 'future'})
|
||||
|
||||
# Build SQL query to find amount aggregated by week
|
||||
select_sql_clause = """SELECT sum(residual_signed) as total, min(date) as aggr_date from account_invoice where journal_id = %(journal_id)s and state = 'open'"""
|
||||
@@ -132,8 +132,6 @@ class account_journal(models.Model):
|
||||
for index in range(0, len(query_results)):
|
||||
if query_results[index].get('aggr_date') != None:
|
||||
data[index]['value'] = query_results[index].get('total')
|
||||
else:
|
||||
data[index]['color'] = '#ffffff'
|
||||
|
||||
return [{'values': data, 'title': title}]
|
||||
|
||||
|
||||
@@ -5,84 +5,116 @@ var kanban_widgets = require('web_kanban.widgets');
|
||||
|
||||
var JournalDashboardGraph = kanban_widgets.AbstractField.extend({
|
||||
start: function() {
|
||||
var self = this;
|
||||
self.graph_type = self.$node.attr('graph_type')
|
||||
self.display_graph(JSON.parse(self.field.raw_value));
|
||||
this.graph_type = this.$node.attr('graph_type');
|
||||
this.data = JSON.parse(this.field.raw_value);
|
||||
this.display_graph();
|
||||
},
|
||||
display_graph : function(data) {
|
||||
|
||||
display_graph : function() {
|
||||
var self = this;
|
||||
nv.addGraph(function () {
|
||||
self.$el.append('<svg style="height:75px; overflow:visible;">');
|
||||
var type = self.graph_type
|
||||
switch(type) {
|
||||
self.$svg = self.$el.append('<svg>');
|
||||
|
||||
switch(self.graph_type) {
|
||||
|
||||
case "line":
|
||||
var chart = nv.models.lineChart();
|
||||
chart.options({
|
||||
x: function(d,u) { return u},
|
||||
width: self.$el.find('svg').width(),
|
||||
height: self.$el.find('svg').height(),
|
||||
margin: {'left': 15, 'right':10, 'top':10, 'bottom': 20},
|
||||
self.$svg.addClass('o_graph_linechart');
|
||||
|
||||
self.chart = nv.models.lineChart();
|
||||
self.chart.options({
|
||||
x: function(d, u) { return u },
|
||||
margin: {'left': 0, 'right': 0, 'top': 0, 'bottom': 0},
|
||||
showYAxis: false,
|
||||
showLegend: false,
|
||||
tooltips: true,
|
||||
tooltipContent: function(key, x, y, e, graph) {
|
||||
var header = "";
|
||||
$.each(e.series.values, function(k,v){
|
||||
if (v.x === x){
|
||||
header = v.name;
|
||||
return self.create_tooltip(x, y, e);
|
||||
},
|
||||
});
|
||||
self.chart.xAxis
|
||||
.tickFormat(function(d) {
|
||||
var label = '';
|
||||
_.each(self.data, function(v, k){
|
||||
if (v.values[d] && v.values[d].x){
|
||||
label = v.values[d].x;
|
||||
}
|
||||
});
|
||||
return '<h3>' + header + '</h3> <p> Balance ' + y + '</p>'},
|
||||
});
|
||||
chart.xAxis
|
||||
.tickFormat(function(d) {
|
||||
var label = '';
|
||||
$.each(data, function(el){
|
||||
if (data[el].values[d] && data[el].values[d].x){
|
||||
label = data[el].values[d].x;
|
||||
}
|
||||
return label;
|
||||
});
|
||||
return label;
|
||||
})
|
||||
.showMaxMin(false);
|
||||
chart.yAxis.tickFormat(d3.format(',.2f'));
|
||||
self.chart.yAxis
|
||||
.tickFormat(d3.format(',.2f'));
|
||||
|
||||
break;
|
||||
|
||||
case "bar":
|
||||
var bar_color = [];
|
||||
$.each(data[0].values, function(k,v){
|
||||
bar_color.push(v.color);
|
||||
})
|
||||
var chart = nv.models.discreteBarChart()
|
||||
.x(function(d) { return d.label })
|
||||
.y(function(d) { return d.value })
|
||||
.width(self.$el.find('svg').width())
|
||||
.height(self.$el.find('svg').height())
|
||||
.showValues(false)
|
||||
.showYAxis(false)
|
||||
.color(bar_color)
|
||||
.margin({'left': 15, 'right':10, 'top':10, 'bottom': 25})
|
||||
.tooltips(true);
|
||||
chart.xAxis.axisLabel(data[0].title);
|
||||
chart.yAxis.tickFormat(d3.format(',.2f'));
|
||||
self.$svg.addClass('o_graph_barchart');
|
||||
|
||||
self.chart = nv.models.discreteBarChart()
|
||||
.x(function(d) { return d.label })
|
||||
.y(function(d) { return d.value })
|
||||
.showValues(false)
|
||||
.showYAxis(false)
|
||||
.margin({'left': 0, 'right': 0, 'top': 0, 'bottom': 40})
|
||||
.tooltips(true)
|
||||
.tooltipContent(function(key, x, y, e, graph) {
|
||||
return self.create_tooltip(x, y, e);
|
||||
});
|
||||
|
||||
self.chart.xAxis.axisLabel(self.data[0].title);
|
||||
self.chart.yAxis.tickFormat(d3.format(',.2f'));
|
||||
|
||||
break;
|
||||
}
|
||||
self.svg = self.$el.find('svg')[0];
|
||||
d3.select(self.svg)
|
||||
.datum(data)
|
||||
d3.select(self.$el.find('svg')[0])
|
||||
.datum(self.data)
|
||||
.transition().duration(1200)
|
||||
.call(chart);
|
||||
nv.utils.windowResize(function() { d3.select(self.svg).call(chart.width(self.$el.find('svg').width()).height(self.$el.find('svg').height())); self.postprocess(); });
|
||||
|
||||
.call(self.chart);
|
||||
|
||||
self.customize_chart(self.data);
|
||||
|
||||
nv.utils.windowResize(self.on_resize);
|
||||
});
|
||||
//ugly, need to do something else
|
||||
setTimeout(function(){self.postprocess();},2000);
|
||||
|
||||
|
||||
},
|
||||
postprocess: function(){
|
||||
var low_rect = $(this.svg).find('rect').filter(function(){return $(this).attr('height') < 1.0 })
|
||||
low_rect.attr('height', 1);
|
||||
|
||||
on_resize: function(){
|
||||
this.chart.update();
|
||||
this.customize_chart(this.data);
|
||||
},
|
||||
|
||||
customize_chart: function(){
|
||||
|
||||
if (this.graph_type === 'bar') {
|
||||
// Add classes related to time on each bar of the bar chart
|
||||
var bar_classes = _.map(this.data[0].values, function (v, k) {return v.type});
|
||||
|
||||
_.each(this.$('.nv-bar'), function(v, k){
|
||||
v.classList.add(bar_classes[k]);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
create_tooltip: function(x, y, e){
|
||||
var header = _.findWhere(e.series.values, {x: x})
|
||||
header = header && header.name || x;
|
||||
|
||||
var $tooltip = $('<div>').addClass('o_tooltip');
|
||||
|
||||
$('<b>')
|
||||
.addClass('o_tooltip_title')
|
||||
.html(header)
|
||||
.appendTo($tooltip)
|
||||
$('<div>')
|
||||
.addClass('o_tooltip_content')
|
||||
.html('Balance ' + y)
|
||||
.appendTo($tooltip)
|
||||
return $tooltip[0].outerHTML;
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
nv.utils.offWindowResize(this.on_resize);
|
||||
this._super();
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -10,12 +10,87 @@
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
.o_kanban_graph_section {
|
||||
padding: 16px;
|
||||
}
|
||||
.o_dashboard_star {
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.o_kanban_graph_section {
|
||||
padding-top: 20px;
|
||||
|
||||
.nvtooltip {
|
||||
padding: 0 8px 0 8px;
|
||||
.o_tooltip_content {
|
||||
color: @odoo-brand-primary;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.o_graph_linechart {
|
||||
|
||||
svg {
|
||||
height: 75px;
|
||||
|
||||
// X axis
|
||||
g.nv-x.nv-axis {
|
||||
transform: translateY(50px);
|
||||
|
||||
// Remove max and min labels
|
||||
g.nv-axisMaxMin {
|
||||
display: none;
|
||||
}
|
||||
g.tick.major {
|
||||
// Don't know why, but leads to strange bold text
|
||||
// stroke: @odoo-brand-primary;
|
||||
|
||||
line {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// !important are needed because nvd3 uses inline style on elements
|
||||
|
||||
// Remove strokes
|
||||
g.nv-linesWrap {
|
||||
g.nv-group.nv-series-0 {
|
||||
fill-opacity: 0.3 !important;
|
||||
fill: @odoo-brand-primary !important;
|
||||
stroke: @odoo-brand-primary !important;
|
||||
|
||||
.nv-point {
|
||||
visibility: hidden;
|
||||
r: 3;
|
||||
stroke: @odoo-brand-primary !important;
|
||||
fill: white;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.nv-point:nth-child(5n+1) {
|
||||
visibility: visible;
|
||||
fill-opacity: .95 !important;
|
||||
stroke-opacity: .95 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_graph_barchart {
|
||||
|
||||
svg {
|
||||
height: 75px;
|
||||
overflow: visible;
|
||||
g.nv-barsWrap {
|
||||
g.nv-group.nv-series-0 {
|
||||
g.past {
|
||||
opacity: 0.5;
|
||||
fill: @odoo-brand-primary !important;
|
||||
}
|
||||
g.future {
|
||||
opacity: 0.5;
|
||||
fill: @odoo-brand-optional !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,14 +260,12 @@
|
||||
</t>
|
||||
<t t-name="JournalBodyGraph">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 o_kanban_graph_section">
|
||||
<t t-if="dashboard.show_import">
|
||||
<button t-if="journal_type == 'bank'" type="object" name="import_statement" class="btn btn-primary btn-sm">Import Statement</button>
|
||||
<button t-if="journal_type == 'cash'" type="object" name="create_cash_bank" class="btn btn-primary btn-sm">Register Transactions</button>
|
||||
</t>
|
||||
<div t-if="!dashboard.show_import">
|
||||
<field name="kanban_dashboard_graph" t-att-graph_type="_.contains(['cash','bank'],journal_type) ? 'line' : 'bar'" widget="dashboard_graph"></field>
|
||||
</div>
|
||||
<div t-if="dashboard.show_import" class="col-xs-12 o_kanban_primary_left">
|
||||
<button t-if="journal_type == 'bank'" type="object" name="import_statement" class="btn btn-primary btn-sm">Import Statement</button>
|
||||
<button t-if="journal_type == 'cash'" type="object" name="create_cash_bank" class="btn btn-primary btn-sm">Register Transactions</button>
|
||||
</div>
|
||||
<div t-if="!dashboard.show_import" class="o_kanban_graph_section">
|
||||
<field name="kanban_dashboard_graph" t-att-graph_type="_.contains(['cash','bank'],journal_type) ? 'line' : 'bar'" widget="dashboard_graph"></field>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user