'Pivot table report widget
@param r: the S3Request
@param method: the widget method
@param widget_id: the widget ID
@param visible: whether the widget is initially visible
@param attr: controller attributes'

def widget(self, r, method=None, widget_id=None, visible=True, **attr):

    output = {}
    resource = self.resource
    get_config = resource.get_config
    maxrows = 20
    maxcols = 20
    report_vars = ('rows', 'cols', 'fact', 'totals')
    get_vars = dict(((k, v) for (k, v) in r.get_vars.iteritems() if (k in report_vars)))
    report_options = get_config('report_options', {})
    defaults = report_options.get('defaults', {})
    if (not any(((k in get_vars) for k in ('rows', 'cols', 'fact')))):
        get_vars = defaults
    get_vars['chart'] = r.get_vars.get('chart', defaults.get('chart', None))
    get_vars['table'] = r.get_vars.get('table', defaults.get('table', None))
    if get_vars:
        rows = get_vars.get('rows', None)
        cols = get_vars.get('cols', None)
        layer = get_vars.get('fact', 'id')
        try:
            facts = S3PivotTableFact.parse(layer)
        except SyntaxError:
            current.log.error(sys.exc_info()[1])
            facts = None
        if ((not facts) or (not any([rows, cols]))):
            pivottable = None
        else:
            prefix = resource.prefix_selector
            get_vars['rows'] = (prefix(rows) if rows else None)
            get_vars['cols'] = (prefix(cols) if cols else None)
            get_vars['fact'] = ','.join((('%s(%s)' % (fact.method, fact.selector)) for fact in facts))
            if visible:
                pivottable = S3PivotTable(resource, rows, cols, facts)
            else:
                pivottable = None
    else:
        pivottable = None
    if (pivottable is not None):
        pivotdata = pivottable.json(maxrows=maxrows, maxcols=maxcols)
    else:
        pivotdata = None
    if (r.representation in ('html', 'iframe')):
        ajax_vars = Storage(r.get_vars)
        ajax_vars.update(get_vars)
        filter_form = attr.get('filter_form', None)
        filter_tab = attr.get('filter_tab', None)
        filter_url = r.url(method='', representation='', vars=ajax_vars.fromkeys((k for k in ajax_vars if (k not in report_vars))))
        ajaxurl = attr.get('ajaxurl', r.url(method='report', representation='json', vars=ajax_vars))
        output = S3ReportForm(resource).html(pivotdata, get_vars=get_vars, filter_widgets=None, ajaxurl=ajaxurl, filter_url=filter_url, filter_form=filter_form, filter_tab=filter_tab, widget_id=widget_id)
        view = self._view(r, 'pivottable.html')
        output['title'] = None
        output = XML(current.response.render(view, output))
    else:
        r.error(415, current.ERROR.BAD_FORMAT)
    return output
