[IMP] code for graph lib
bzr revid: fp@tinyerp.com-20120507094059-y0ogjwcocp71hfue
This commit is contained in:
parent
7463466695
commit
76b1514392
|
@ -21,6 +21,7 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
|||
this.mode="pie"; // line, bar, area, pie, radar
|
||||
this.orientation=true; // true: horizontal, false: vertical
|
||||
this.stacked=true;
|
||||
|
||||
this.spreadsheet=false; // Display data gris, allows copy to CSV
|
||||
this.forcehtml=false;
|
||||
this.legend_container;
|
||||
|
@ -37,71 +38,240 @@ instance.web_graph.GraphView = instance.web.View.extend({
|
|||
this._super();
|
||||
},
|
||||
|
||||
|
||||
|
||||
on_loaded: function(fields_view_get) {
|
||||
var self = this;
|
||||
self.fields_view = fields_view_get;
|
||||
return this.dataset.call_and_eval('fields_get', [false, {}], null, 1).pipe(function(fields_result) {
|
||||
self.fields = fields_result;
|
||||
return self.on_loaded_2();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Returns all object fields involved in the graph view
|
||||
*/
|
||||
list_fields: function () {
|
||||
var fs = [this.abscissa];
|
||||
fs.push.apply(fs, _(this.columns).pluck('name'));
|
||||
if (this.group_field) {
|
||||
fs.push(this.group_field);
|
||||
}
|
||||
return fs;
|
||||
},
|
||||
on_loaded_2: function() {
|
||||
this.chart = this.fields_view.arch.attrs.type || 'pie';
|
||||
this.orientation = this.fields_view.arch.attrs.orientation || 'vertical';
|
||||
this.$element.html(QWeb.render("GraphView", {}));
|
||||
|
||||
_.each(this.fields_view.arch.children, function (field) {
|
||||
var attrs = field.attrs;
|
||||
if (attrs.group) {
|
||||
this.group_field = attrs.name;
|
||||
} else if(!this.abscissa) {
|
||||
this.first_field = this.abscissa = attrs.name;
|
||||
} else {
|
||||
this.columns.push({
|
||||
name: attrs.name,
|
||||
operator: attrs.operator || '+'
|
||||
});
|
||||
// Should I add this, in every $(...) call ?
|
||||
container = $("#editor-render-body");
|
||||
$("#graph_bar,#graph_bar_stacked").click(
|
||||
{mode: 'bar', stacked: true, legend: 'top'}, graph_render)
|
||||
|
||||
$("#graph_bar_not_stacked").click(
|
||||
{mode: 'bar', stacked: false, legend: 'top'}, graph_render)
|
||||
|
||||
$("#graph_area,#graph_area_stacked").click(
|
||||
{mode: "area", stacked: true, legend: "top"}, graph_render);
|
||||
|
||||
$("#graph_area_not_stacked").click(
|
||||
{mode: "area", stacked: false, legend: "top"}, graph_render);
|
||||
|
||||
$("#graph_radar").click(
|
||||
{orientation: 0, mode: "radar", legend: "inside"}, graph_render);
|
||||
|
||||
$("#graph_pie").click(
|
||||
{mode: "pie", legend: "inside"}, graph_render);
|
||||
|
||||
$("#graph_legend_top").click(
|
||||
{legend: "top"}, graph_render);
|
||||
|
||||
$("#graph_legend_inside").click(
|
||||
{legend: "inside"}, graph_render);
|
||||
|
||||
$("#graph_legend_no").click(
|
||||
{legend: "no"}, graph_render);
|
||||
|
||||
$("#graph_line").click(
|
||||
{mode: "line"}, graph_render);
|
||||
|
||||
$("#graph_show_data").click(
|
||||
function() {
|
||||
spreadsheet = ! spreadsheet;
|
||||
graph_render();
|
||||
}
|
||||
}, this);
|
||||
this.ordinate = this.columns[0].name;
|
||||
this.is_loaded.resolve();
|
||||
return $.when();
|
||||
);
|
||||
$("#graph_switch").click(
|
||||
function() {
|
||||
orientation = ! orientation;
|
||||
graph_render();
|
||||
}
|
||||
);
|
||||
|
||||
$("#graph_download").click(
|
||||
function() {
|
||||
var graph;
|
||||
if (Flotr.isIE && Flotr.isIE < 9) {
|
||||
alert(
|
||||
"Your browser doesn't allow you to get a bitmap image from the plot, " +
|
||||
"you can only get a VML image that you can use in Microsoft Office."
|
||||
);
|
||||
}
|
||||
if (legend=="top") legend="inside";
|
||||
forcehtml = true;
|
||||
graph = graph_render();
|
||||
graph.download.saveImage('png');
|
||||
forcehtml = false;
|
||||
}
|
||||
);
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
get_format: function get_format(options) {
|
||||
var result = {
|
||||
show: this.legend!='no',
|
||||
}
|
||||
if (legend=="top") {
|
||||
result.noColumns = 4;
|
||||
// todo: I guess I should add something like this.renderer ?
|
||||
result.container = $("div .graph_header_legend", this)[0];
|
||||
} else if (legend=="inside") {
|
||||
result.position = 'nw';
|
||||
result.backgroundColor = '#D2E8FF';
|
||||
}
|
||||
return $.extend({
|
||||
legend: result,
|
||||
mouse: {
|
||||
track: true,
|
||||
relative: true
|
||||
},
|
||||
spreadsheet : {
|
||||
show: this.spreadsheet,
|
||||
initialTab: "data"
|
||||
},
|
||||
HtmlText : (options && options.labelsAngle)?false:!this.forcehtml,
|
||||
}, options)
|
||||
},
|
||||
|
||||
graph_get_data: function (options) {
|
||||
var i,
|
||||
d1 = [],
|
||||
d2 = [],
|
||||
d3 = [];
|
||||
for (i = -3; i < 3; i++) {
|
||||
if (this.orientation % 2) {
|
||||
d1.push([Math.random(), i]);
|
||||
d2.push([Math.random(), i]);
|
||||
d3.push([Math.random(), i]);
|
||||
} else {
|
||||
d1.push([i, Math.random()]);
|
||||
d2.push([i, Math.random()]);
|
||||
d3.push([i, Math.random()]);
|
||||
}
|
||||
};
|
||||
return [
|
||||
$.extend({ data : d2, label : 'Serie 2'}, options),
|
||||
$.extend({ data : d3, label : 'Serie 3'}, options),
|
||||
$.extend({ data : d1, label : 'Serie 1'}, options),
|
||||
];
|
||||
},
|
||||
|
||||
|
||||
graph_bar: function (container, data) {
|
||||
return Flotr.draw(container, data, get_format({
|
||||
bars : {
|
||||
show : true,
|
||||
stacked : this.stacked,
|
||||
horizontal : this.orientation,
|
||||
barWidth : 0.7,
|
||||
lineWidth : 1
|
||||
},
|
||||
grid : {
|
||||
verticalLines : this.orientation,
|
||||
horizontalLines : !this.orientation,
|
||||
outline : "sw",
|
||||
},
|
||||
labelsAngle: 45
|
||||
})
|
||||
)
|
||||
},
|
||||
|
||||
graph_pie: function (container, data) {
|
||||
return Flotr.draw(container, data, get_format({
|
||||
pie : {
|
||||
show: true
|
||||
},
|
||||
grid : {
|
||||
verticalLines : false,
|
||||
horizontalLines : false,
|
||||
outline : "",
|
||||
},
|
||||
xaxis : {showLabels: false},
|
||||
yaxis : {showLabels: false},
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
graph_radar: function (container, data) {
|
||||
return Flotr.draw(container, data, get_format({
|
||||
radar : {
|
||||
show : true,
|
||||
stacked : this.stacked
|
||||
},
|
||||
grid : {
|
||||
circular : true,
|
||||
minorHorizontalLines : true
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
graph_line: function (container, data) {
|
||||
return Flotr.draw(container, data, get_format({
|
||||
lines : {
|
||||
show : true,
|
||||
stacked : this.stacked
|
||||
},
|
||||
grid : {
|
||||
verticalLines : this.orientation,
|
||||
horizontalLines : !this.orientation,
|
||||
outline : "sw",
|
||||
},
|
||||
labelsAngle : 45
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// Render the graph and update menu styles
|
||||
graph_render: function (options) {
|
||||
var graph, data, mode_options, i;
|
||||
|
||||
if (options)
|
||||
for (i in options.data)
|
||||
this[i] = options.data[i];
|
||||
|
||||
mode_options = (this.mode=='area')?{lines: {fill: true}}:{}
|
||||
|
||||
// Render the graph
|
||||
$(".graph_header_legend").children().remove()
|
||||
data = this.get_data(mode_options);
|
||||
graph = {
|
||||
radar: graph_radar,
|
||||
pie: graph_pie,
|
||||
bar: graph_bar,
|
||||
area: graph_line,
|
||||
line: graph_line
|
||||
}[this.mode](container, data)
|
||||
|
||||
// Update styles of menus
|
||||
|
||||
$("a[id^='graph_']").removeClass("active");
|
||||
$("a[id='graph_"+mode+"']").addClass("active");
|
||||
$("a[id='graph_"+mode+(this.stacked?"_stacked":"_not_stacked")+"']").addClass("active");
|
||||
|
||||
if (this.legend=='inside')
|
||||
$("a[id='graph_legend_inside']").addClass("active");
|
||||
else if (this.legend=='top')
|
||||
$("a[id='graph_legend_top']").addClass("active");
|
||||
else
|
||||
$("a[id='graph_legend_no']").addClass("active");
|
||||
|
||||
if (this.spreadsheet)
|
||||
$("a[id='graph_show_data']").addClass("active");
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
schedule_chart: function(results) {
|
||||
var self = this;
|
||||
this.$element.html(QWeb.render("GraphView", {
|
||||
"fields_view": this.fields_view,
|
||||
"chart": this.chart,
|
||||
'element_id': this.getParent().element_id
|
||||
}));
|
||||
|
||||
var fields = _(this.columns).pluck('name').concat([this.abscissa]);
|
||||
if (this.group_field) { fields.push(this.group_field); }
|
||||
|
||||
self.graph_render(...)
|
||||
},
|
||||
|
||||
// render the graph using the domain, context and group_by
|
||||
// calls the 'graph_data_get' python controller to process all data
|
||||
do_search: function(domain, context, group_by) {
|
||||
var self = this;
|
||||
return $.when(this.is_loaded).pipe(function() {
|
||||
// TODO: handle non-empty group_by with read_group?
|
||||
if (!_(group_by).isEmpty()) {
|
||||
self.abscissa = group_by[0];
|
||||
} else {
|
||||
self.abscissa = self.first_field;
|
||||
}
|
||||
return self.dataset.read_slice(self.list_fields()).then($.proxy(self, 'schedule_chart'));
|
||||
// todo: find the right syntax to perform an Ajax call
|
||||
return self.rpc.graph_get_data(self.view_id, domain, context, group_by).then($.proxy(self, 'schedule_chart'));
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -1,49 +1,50 @@
|
|||
<template>
|
||||
<div t-name="GraphView" id="element_id-chart" class="editor-render" style="height:300px; width:300px; position:relative;">
|
||||
<div class="graph_header_legend">
|
||||
</div>
|
||||
<a href="#" class="i dropdown-menu-icon" data-toggle="dropdown">B</a>
|
||||
<div class="graph-dropdown">
|
||||
<div class="menu-section">
|
||||
Graph Mode:
|
||||
</div>
|
||||
<ul class="graph-menu">
|
||||
<li><a href="#" id="graph_pie">Pie</a></li>
|
||||
<li>
|
||||
<a href="#" id="graph_bar">Bars</a>
|
||||
<div class="i graph-menu-options">
|
||||
<a href="#" id="graph_bar_stacked">w</a>
|
||||
<a href="#" id="graph_bar_not_stacked">O</a>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="#" id="graph_line">Lines</a></li>
|
||||
<li><a href="#" id="graph_area">Areas</a>
|
||||
<div class="i graph-menu-options">
|
||||
<a href="#" id="graph_area_stacked">w</a>
|
||||
<a href="#" id="graph_area_not_stacked">O</a>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="#" id="graph_radar">Radar</a></li>
|
||||
</ul>
|
||||
<div class="menu-section">
|
||||
Legend:
|
||||
</div>
|
||||
<ul class="graph-menu">
|
||||
<li><a href="#" id="graph_legend_no">Hide</a></li>
|
||||
<li><a href="#" id="graph_legend_inside">Inside</a></li>
|
||||
<li><a href="#" id="graph_legend_top">Top</a></li>
|
||||
</ul>
|
||||
<div class="menu-section">
|
||||
Actions:
|
||||
</div>
|
||||
<ul class="graph-menu">
|
||||
<li><a href="#" id="graph_switch">Switch Axis</a></li>
|
||||
<li><a href="#" id="graph_show_data">Show Data</a></li>
|
||||
<li><a href="#" id="graph_download">Download as PNG</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="editor-render-body">
|
||||
</div>
|
||||
</div>
|
||||
<div t-name="GraphView" id="element_id-chart" class="editor-render" style="height:300px; width:300px; position:relative;">
|
||||
<h1>This is a test</h1>
|
||||
<div class="graph_header_legend">
|
||||
</div>
|
||||
<a href="#" class="i dropdown-menu-icon" data-toggle="dropdown">B</a>
|
||||
<div class="graph-dropdown">
|
||||
<div class="menu-section">
|
||||
Graph Mode:
|
||||
</div>
|
||||
<ul class="graph-menu">
|
||||
<li><a href="#" id="graph_pie">Pie</a></li>
|
||||
<li>
|
||||
<a href="#" id="graph_bar">Bars</a>
|
||||
<div class="i graph-menu-options">
|
||||
<a href="#" id="graph_bar_stacked">w</a>
|
||||
<a href="#" id="graph_bar_not_stacked">O</a>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="#" id="graph_line">Lines</a></li>
|
||||
<li><a href="#" id="graph_area">Areas</a>
|
||||
<div class="i graph-menu-options">
|
||||
<a href="#" id="graph_area_stacked">w</a>
|
||||
<a href="#" id="graph_area_not_stacked">O</a>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="#" id="graph_radar">Radar</a></li>
|
||||
</ul>
|
||||
<div class="menu-section">
|
||||
Legend:
|
||||
</div>
|
||||
<ul class="graph-menu">
|
||||
<li><a href="#" id="graph_legend_no">Hide</a></li>
|
||||
<li><a href="#" id="graph_legend_inside">Inside</a></li>
|
||||
<li><a href="#" id="graph_legend_top">Top</a></li>
|
||||
</ul>
|
||||
<div class="menu-section">
|
||||
Actions:
|
||||
</div>
|
||||
<ul class="graph-menu">
|
||||
<li><a href="#" id="graph_switch">Switch Axis</a></li>
|
||||
<li><a href="#" id="graph_show_data">Show Data</a></li>
|
||||
<li><a href="#" id="graph_download">Download as PNG</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="editor-render-body">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue