diff --git a/addons/web/static/src/js/pyeval.js b/addons/web/static/src/js/pyeval.js
index d5499a028b7eec8f8546ba09dec505e931d8b8b4..bad98e7b2a08fb66848c5b1946a9c9190e0c08a4 100644
--- a/addons/web/static/src/js/pyeval.js
+++ b/addons/web/static/src/js/pyeval.js
@@ -888,15 +888,9 @@
         return new $.Deferred(function (d) {setTimeout(function () {
             var result;
             try {
-                var contexts = ([instance.session.user_context] || []).concat(source.contexts);
-                // see Session.eval_context in Python
-                result = {
-                    context: instance.web.pyeval.eval('contexts', contexts),
-                    domain: instance.web.pyeval.eval('domains', source.domains),
-                    group_by: instance.web.pyeval.eval('groupbys', source.group_by_seq || [])
-                };
-
-            } catch (e) {
+                result = instance.web.pyeval.sync_eval_domains_and_contexts(source);
+            }
+            catch (e) {
                 result = { error: {
                     code: 400,
                     message: instance.web._t("Evaluation Error"),
@@ -906,9 +900,18 @@
                                 instance.web._t("Local evaluation failure\n%s\n\n%s"),
                                 e.message, JSON.stringify(source))
                     }
-                }};
+                }};                
             }
             d.resolve(result);
         }, 0); });
     };
+    instance.web.pyeval.sync_eval_domains_and_contexts = function (source) {
+        var contexts = ([instance.session.user_context] || []).concat(source.contexts);
+        // see Session.eval_context in Python
+        return {
+            context: instance.web.pyeval.eval('contexts', contexts),
+            domain: instance.web.pyeval.eval('domains', source.domains),
+            group_by: instance.web.pyeval.eval('groupbys', source.group_by_seq || [])
+        };
+    };
 })();
diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js
index 953de133ef90d2c8dde605cfd47f33778c36fc79..8ae99849bab5c5c4bd0bd94d92da88726de998eb 100644
--- a/addons/web_graph/static/src/js/graph_view.js
+++ b/addons/web_graph/static/src/js/graph_view.js
@@ -162,6 +162,10 @@ instance.web_graph.GraphView = instance.web.View.extend({
             return;
         }
 
+        var custom_groups = this.get_custom_filter_groupbys();
+        row_groupby = row_groupby.slice(custom_groups.groupby.length);
+        col_groupby = col_groupby.slice(custom_groups.col_groupby.length);
+
         if (row_gb_changed && col_gb_changed) {
             // when two changes to the search view will be done, the method do_search
             // will be called twice, once with the correct groupby and incorrect col_groupby,
@@ -233,5 +237,46 @@ instance.web_graph.GraphView = instance.web.View.extend({
             };
         });
     },
+
+    get_custom_filter_groupbys: function () {
+        var gb = [],
+            col_gb = [];
+
+        var facet = this.search_view.query.at(0);
+        if (facet) {
+            if (facet.get('category') !== 'GroupBy' && facet.get('category') !== 'ColGroupBy') {
+                gb = get_groupby(facet);
+                col_gb = get_col_groupby(facet);
+            }
+        }
+        return {
+            groupby: gb,
+            col_groupby: col_gb,
+        }
+    }
+
 });
+
+function get_groupby(facet) {
+    var field = facet.get('field'),
+        result = [];
+    if ('get_groupby' in field) {
+        result = instance.web.pyeval.sync_eval_domains_and_contexts({
+            group_by_seq: field.get_groupby(facet)
+        }).group_by;
+    }
+    return result;
+}
+function get_col_groupby(facet) {
+    var field = facet.get('field'),
+        result = [];
+    if ('get_context' in field) {
+        result = instance.web.pyeval.sync_eval_domains_and_contexts({
+            contexts: field.get_context(facet)
+        }).context.col_group_by || [];
+    }
+    return result;
+}
+
+
 };
diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js
index f0e07e06e6a1d52fe9a5d3a49b73ef877837219b..060eb70b5140571d60ddc3963e8043318991d541 100644
--- a/addons/web_graph/static/src/js/graph_widget.js
+++ b/addons/web_graph/static/src/js/graph_widget.js
@@ -594,41 +594,52 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
     // Drawing the table
     // ----------------------------------------------------------------------
     draw_table: function () {
+        var custom_gbs = this.graph_view.get_custom_filter_groupbys(),
+            frozen_rows = custom_gbs.groupby.length,
+            frozen_cols = custom_gbs.col_groupby.length;
+
         var table = this.build_table();
         var doc_fragment = $(document.createDocumentFragment());
-        this.draw_headers(table.headers, doc_fragment);
+        this.draw_headers(table.headers, doc_fragment, frozen_cols);
         this.draw_measure_row(table.measure_row, doc_fragment);
-        this.draw_rows(table.rows, doc_fragment);
+        this.draw_rows(table.rows, doc_fragment, frozen_rows);
         this.table.append(doc_fragment);
     },
 
-    make_header_cell: function (header) {
+    make_header_cell: function (header, frozen) {
         var cell = (_.has(header, 'cells') ? $('<td>') : $('<th>'))
                         .addClass('graph_border')
                         .attr('rowspan', header.height)
                         .attr('colspan', header.width);
-        var $content = $('<span>').addClass('web_graph_click')
-                                 .attr('href','#')
+        var $content = $('<span>').attr('href','#')
                                  .text(' ' + (header.title || _t('Undefined')))
                                  .css('margin-left', header.indent*30 + 'px')
                                  .attr('data-id', header.id);
         if (_.has(header, 'expanded')) {
-            $content.addClass(header.expanded ? 'fa fa-minus-square' : 'fa fa-plus-square');
+            if (('indent' in header) && header.indent >= frozen) {
+                $content.addClass(header.expanded ? 'fa fa-minus-square' : 'fa fa-plus-square');
+                $content.addClass('web_graph_click');
+            }
+            if (!('indent' in header) && header.lvl >= frozen) {
+                $content.addClass(header.expanded ? 'fa fa-minus-square' : 'fa fa-plus-square');
+                $content.addClass('web_graph_click');
+            }
         } else {
             $content.css('font-weight', 'bold');
         }
         return cell.append($content);
     },
 
-    draw_headers: function (headers, doc_fragment) {
+    draw_headers: function (headers, doc_fragment, frozen_cols) {
         var make_cell = this.make_header_cell,
             $empty_cell = $('<th>').attr('rowspan', headers.length),
             $thead = $('<thead>');
 
-        _.each(headers, function (row) {
+        _.each(headers, function (row, lvl) {
             var $row = $('<tr>');
             _.each(row, function (header) {
-                $row.append(make_cell(header));
+                header.lvl = lvl;
+                $row.append(make_cell(header, frozen_cols));
             });
             $thead.append($row);
         });
@@ -647,10 +658,10 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
         this.$thead.append($row);
     },
     
-    draw_row: function (row) {
+    draw_row: function (row, frozen_rows) {
         var $row = $('<tr>')
             .attr('data-indent', row.indent)
-            .append(this.make_header_cell(row));
+            .append(this.make_header_cell(row, frozen_rows));
         
         var cells_length = row.cells.length;
         var cells_list = [];
@@ -671,13 +682,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({
         return $row.append(cells_list.join(''));
     },
 
-    draw_rows: function (rows, doc_fragment) {
+    draw_rows: function (rows, doc_fragment, frozen_rows) {
         var rows_length = rows.length,
             $tbody = $('<tbody>');
 
         doc_fragment.append($tbody);
         for (var i = 0; i < rows_length; i++) {
-            $tbody.append(this.draw_row(rows[i]));
+            $tbody.append(this.draw_row(rows[i], frozen_rows));
         }
     },