<s> import copy <EOL> from collections import defaultdict <EOL> from itertools import groupby , izip <EOL> from django . utils . datastructures import SortedDict <EOL> from highcharts import HCOptions <EOL> from validation import clean_pcso , clean_cso , clean_x_sortf_mapf_mts <EOL> from exceptions import APIInputError <EOL> from chartdata import PivotDataPool , DataPool <EOL> class Chart ( object ) : <EOL> def __init__ ( self , datasource , series_options , chart_options = None , <EOL> x_sortf_mapf_mts = None ) : <EOL> """<STR_LIT>""" <EOL> self . user_input = locals ( ) <EOL> if not isinstance ( datasource , DataPool ) : <EOL> raise APIInputError ( "<STR_LIT>" <EOL> % datasource ) <EOL> self . datasource = datasource <EOL> self . series_options = clean_cso ( series_options , self . datasource ) <EOL> self . x_sortf_mapf_mts = clean_x_sortf_mapf_mts ( x_sortf_mapf_mts ) <EOL> self . x_axis_vqs_groups = self . _groupby_x_axis_and_vqs ( ) <EOL> self . _set_default_hcoptions ( chart_options ) <EOL> self . generate_plot ( ) <EOL> def _groupby_x_axis_and_vqs ( self ) : <EOL> """<STR_LIT>""" <EOL> dss = self . datasource . series <EOL> x_axis_vqs_groups = defaultdict ( dict ) <EOL> sort_fn = lambda ( tk , td ) : td . get ( '<STR_LIT>' , <NUM_LIT:0> ) <EOL> so = sorted ( self . series_options . items ( ) , key = sort_fn ) <EOL> x_axis_groups = groupby ( so , sort_fn ) <EOL> for ( x_axis , itr1 ) in x_axis_groups : <EOL> sort_fn = lambda ( tk , td ) : dss [ td [ '<STR_LIT>' ] ] [ '<STR_LIT>' ] <EOL> itr1 = sorted ( itr1 , key = sort_fn ) <EOL> for _vqs_num , ( _data , itr2 ) in enumerate ( groupby ( itr1 , sort_fn ) ) : <EOL> x_axis_vqs_groups [ x_axis ] [ _vqs_num ] = _x_vqs = { } <EOL> for tk , td in itr2 : <EOL> _x_vqs . setdefault ( td [ '<STR_LIT>' ] , [ ] ) . append ( tk ) <EOL> return x_axis_vqs_groups <EOL> def _set_default_hcoptions ( self , chart_options ) : <EOL> """<STR_LIT>""" <EOL> so = self . series_options <EOL> dss = self . datasource . series <EOL> self . hcoptions = HCOptions ( { } ) <EOL> if chart_options is not None : <EOL> self . hcoptions . update ( chart_options ) <EOL> self . hcoptions [ '<STR_LIT>' ] = [ ] <EOL> title = '<STR_LIT>' <EOL> for x_axis_num , vqs_group in self . x_axis_vqs_groups . items ( ) : <EOL> for vqs_num , x_y_terms in vqs_group . items ( ) : <EOL> for x_term , y_terms in x_y_terms . items ( ) : <EOL> title += '<STR_LIT:U+002CU+0020>' . join ( [ dss [ y_term ] [ '<STR_LIT>' ] . title ( ) <EOL> for y_term in y_terms ] ) <EOL> title += '<STR_LIT>' <EOL> title += dss [ x_term ] [ '<STR_LIT>' ] . title ( ) <EOL> title += '<STR_LIT>' <EOL> if not self . hcoptions [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] : <EOL> self . hcoptions [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] = title [ : - <NUM_LIT:3> ] <EOL> xAxis , yAxis = self . hcoptions [ '<STR_LIT>' ] , self . hcoptions [ '<STR_LIT>' ] <EOL> if isinstance ( xAxis , dict ) : <EOL> self . hcoptions [ '<STR_LIT>' ] = [ xAxis ] <EOL> if isinstance ( yAxis , dict ) : <EOL> self . hcoptions [ '<STR_LIT>' ] = [ yAxis ] <EOL> if not self . hcoptions [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> self . hcoptions [ '<STR_LIT>' ] [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> term_x_axis = [ ( dss [ d [ '<STR_LIT>' ] ] [ '<STR_LIT>' ] . title ( ) , <EOL> d . get ( '<STR_LIT>' , <NUM_LIT:0> ) ) <EOL> for ( k , d ) in so . items ( ) ] <EOL> term_y_axis = [ ( dss [ k ] [ '<STR_LIT>' ] . title ( ) , d . get ( '<STR_LIT>' , <NUM_LIT:0> ) ) <EOL> for ( k , d ) in so . items ( ) ] <EOL> max_x_axis = max ( t [ <NUM_LIT:1> ] for t in term_x_axis ) <EOL> max_y_axis = max ( t [ <NUM_LIT:1> ] for t in term_y_axis ) <EOL> x_axis_len = len ( self . hcoptions [ '<STR_LIT>' ] ) <EOL> y_axis_len = len ( self . hcoptions [ '<STR_LIT>' ] ) <EOL> if max_x_axis >= x_axis_len : <EOL> self . hcoptions [ '<STR_LIT>' ] . extend ( [ HCOptions ( { } ) ] * ( max_x_axis + <NUM_LIT:1> - x_axis_len ) ) <EOL> for i , x_axis in enumerate ( self . hcoptions [ '<STR_LIT>' ] ) : <EOL> if not x_axis [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] : <EOL> axis_title = set ( t [ <NUM_LIT:0> ] for t in term_x_axis if t [ <NUM_LIT:1> ] == i ) <EOL> x_axis [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] = '<STR_LIT>' . join ( axis_title ) <EOL> if max_x_axis == <NUM_LIT:1> : <EOL> if self . hcoptions [ '<STR_LIT>' ] [ <NUM_LIT:1> ] [ '<STR_LIT>' ] != False : <EOL> self . hcoptions [ '<STR_LIT>' ] [ <NUM_LIT:1> ] [ '<STR_LIT>' ] = True <EOL> if max_y_axis >= y_axis_len : <EOL> self . hcoptions [ '<STR_LIT>' ] . extend ( [ HCOptions ( { } ) ] * ( max_y_axis + <NUM_LIT:1> - y_axis_len ) ) <EOL> for i , y_axis in enumerate ( self . hcoptions [ '<STR_LIT>' ] ) : <EOL> if not y_axis [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] : <EOL> axis_title = set ( t [ <NUM_LIT:0> ] for t in term_y_axis if t [ <NUM_LIT:1> ] == i ) <EOL> y_axis [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] = '<STR_LIT>' . join ( axis_title ) <EOL> if max_y_axis == <NUM_LIT:1> : <EOL> if self . hcoptions [ '<STR_LIT>' ] [ <NUM_LIT:1> ] [ '<STR_LIT>' ] != False : <EOL> self . hcoptions [ '<STR_LIT>' ] [ <NUM_LIT:1> ] [ '<STR_LIT>' ] = True <EOL> def generate_plot ( self ) : <EOL> self . hcoptions [ '<STR_LIT>' ] = [ ] <EOL> dss = self . datasource . series <EOL> cht_typ_grp = lambda y_term : ( '<STR_LIT>' if <EOL> self . series_options [ y_term ] [ '<STR_LIT:type>' ] <EOL> in [ '<STR_LIT>' , '<STR_LIT>' ] else '<STR_LIT>' ) <EOL> for x_axis_num , vqs_groups in self . x_axis_vqs_groups . items ( ) : <EOL> y_hco_list = [ ] <EOL> try : <EOL> x_sortf , x_mapf , x_mts = self . x_sortf_mapf_mts [ x_axis_num ] <EOL> except IndexError : <EOL> x_sortf , x_mapf , x_mts = ( None , None , False ) <EOL> ptype_x_y_terms = defaultdict ( list ) <EOL> for vqs_group in vqs_groups . values ( ) : <EOL> x_term , y_terms_all = vqs_group . items ( ) [ <NUM_LIT:0> ] <EOL> y_terms_by_type = defaultdict ( list ) <EOL> for y_term in y_terms_all : <EOL> y_terms_by_type [ cht_typ_grp ( y_term ) ] . append ( y_term ) <EOL> for y_type , y_term_list in y_terms_by_type . items ( ) : <EOL> ptype_x_y_terms [ y_type ] . append ( ( x_term , y_term_list ) ) <EOL> for ptype , x_y_terms_tuples in ptype_x_y_terms . items ( ) : <EOL> y_fields_multi = [ ] <EOL> y_aliases_multi = [ ] <EOL> y_types_multi = [ ] <EOL> y_hco_list_multi = [ ] <EOL> y_values_multi = SortedDict ( ) <EOL> y_terms_multi = [ ] <EOL> for x_term , y_terms in x_y_terms_tuples : <EOL> x_vqs = dss [ x_term ] [ '<STR_LIT>' ] <EOL> x_field = dss [ x_term ] [ '<STR_LIT>' ] <EOL> y_fields = [ dss [ y_term ] [ '<STR_LIT>' ] for y_term in y_terms ] <EOL> y_aliases = [ dss [ y_term ] [ '<STR_LIT>' ] for y_term <EOL> in y_terms ] <EOL> y_types = [ self . series_options [ y_term ] . get ( '<STR_LIT:type>' , '<STR_LIT>' ) <EOL> for y_term in y_terms ] <EOL> y_hco_list = [ HCOptions ( <EOL> copy . deepcopy ( <EOL> self . series_options [ y_term ] ) ) for <EOL> y_term in y_terms ] <EOL> for opts , alias , typ in zip ( y_hco_list , y_aliases , y_types ) : <EOL> opts . pop ( '<STR_LIT>' ) <EOL> opts [ '<STR_LIT:name>' ] = alias <EOL> opts [ '<STR_LIT:type>' ] = typ <EOL> opts [ '<STR_LIT:data>' ] = [ ] <EOL> if ptype == '<STR_LIT>' or ( ptype == '<STR_LIT>' and <EOL> len ( x_y_terms_tuples ) == <NUM_LIT:1> ) : <EOL> if x_mts : <EOL> if x_mapf : <EOL> data = ( ( x_mapf ( value_dict [ x_field ] ) , <EOL> [ value_dict [ y_field ] for y_field <EOL> in y_fields ] ) <EOL> for value_dict in x_vqs ) <EOL> sort_key = ( ( lambda ( x , y ) : x_sortf ( x ) ) <EOL> if x_sortf is not None else None ) <EOL> data = sorted ( data , key = sort_key ) <EOL> else : <EOL> sort_key = ( ( lambda ( x , y ) : x_sortf ( x ) ) <EOL> if x_sortf is not None else None ) <EOL> data = sorted ( <EOL> ( ( value_dict [ x_field ] , <EOL> [ value_dict [ y_field ] for y_field in <EOL> y_fields ] ) <EOL> for value_dict in x_vqs ) , <EOL> key = sort_key ) <EOL> if x_mapf : <EOL> data = [ ( x_mapf ( x ) , y ) for ( x , y ) in data ] <EOL> if ptype == '<STR_LIT>' : <EOL> if self . series_options [ y_term ] [ '<STR_LIT:type>' ] == '<STR_LIT>' : <EOL> for x_value , y_value_tuple in data : <EOL> for opts , y_value in izip ( y_hco_list , <EOL> y_value_tuple ) : <EOL> opts [ '<STR_LIT:data>' ] . append ( ( x_value , y_value ) ) <EOL> self . hcoptions [ '<STR_LIT>' ] . extend ( y_hco_list ) <EOL> else : <EOL> for x_value , y_value_tuple in data : <EOL> for opts , y_value in izip ( y_hco_list , <EOL> y_value_tuple ) : <EOL> opts [ '<STR_LIT:data>' ] . append ( ( str ( x_value ) , <EOL> y_value ) ) <EOL> self . hcoptions [ '<STR_LIT>' ] . extend ( y_hco_list ) <EOL> if ptype == '<STR_LIT>' and len ( x_y_terms_tuples ) == <NUM_LIT:1> : <EOL> hco_x_axis = self . hcoptions [ '<STR_LIT>' ] <EOL> if len ( hco_x_axis ) - <NUM_LIT:1> < x_axis_num : <EOL> hco_x_axis . extend ( [ HCOptions ( { } ) ] * <EOL> ( x_axis_num - <EOL> ( len ( hco_x_axis ) - <EOL> <NUM_LIT:1> ) ) ) <EOL> hco_x_axis [ x_axis_num ] [ '<STR_LIT>' ] = [ ] <EOL> for x_value , y_value_tuple in data : <EOL> hco_x_axis [ x_axis_num ] [ '<STR_LIT>' ] . append ( x_value ) <EOL> for opts , y_value in izip ( y_hco_list , <EOL> y_value_tuple ) : <EOL> opts [ '<STR_LIT:data>' ] . append ( y_value ) <EOL> self . hcoptions [ '<STR_LIT>' ] . extend ( y_hco_list ) <EOL> else : <EOL> data = ( ( value_dict [ x_field ] , <EOL> [ value_dict [ y_field ] for y_field in <EOL> y_fields ] ) <EOL> for value_dict in x_vqs ) <EOL> y_terms_multi . extend ( y_terms ) <EOL> y_fields_multi . extend ( y_fields ) <EOL> y_aliases_multi . extend ( y_aliases ) <EOL> y_types_multi . extend ( y_types ) <EOL> y_hco_list_multi . extend ( y_hco_list ) <EOL> len_y_terms_multi = len ( y_terms_multi ) <EOL> ext_len = len ( y_terms_multi ) - len ( y_terms ) <EOL> for x_value , y_value_tuple in data : <EOL> try : <EOL> cur_y = y_values_multi [ x_value ] <EOL> cur_y . extend ( y_value_tuple ) <EOL> except KeyError : <EOL> y_values_multi [ x_value ] = [ None ] * ext_len <EOL> y_values_multi [ x_value ] . extend ( y_value_tuple ) <EOL> for _y_vals in y_values_multi . values ( ) : <EOL> if len ( _y_vals ) != len_y_terms_multi : <EOL> _y_vals . extend ( [ None ] * len ( y_terms ) ) <EOL> if y_terms_multi : <EOL> hco_x_axis = self . hcoptions [ '<STR_LIT>' ] <EOL> if len ( hco_x_axis ) - <NUM_LIT:1> < x_axis_num : <EOL> hco_x_axis . extend ( [ HCOptions ( { } ) ] * <EOL> ( x_axis_num - ( len ( hco_x_axis ) - <NUM_LIT:1> ) ) ) <EOL> hco_x_axis [ x_axis_num ] [ '<STR_LIT>' ] = [ ] <EOL> if x_mts : <EOL> if x_mapf : <EOL> data = ( ( x_mapf ( x_value ) , y_vals ) for <EOL> ( x_value , y_vals ) in <EOL> y_values_multi . iteritems ( ) ) <EOL> sort_key = ( ( lambda ( x , y ) : x_sortf ( x ) ) if x_sortf <EOL> is not None else None ) <EOL> data = sorted ( data , key = sort_key ) <EOL> else : <EOL> data = y_values_multi . iteritems ( ) <EOL> sort_key = ( ( lambda ( x , y ) : x_sortf ( x ) ) if x_sortf <EOL> is not None else None ) <EOL> data = sorted ( data , key = sort_key ) <EOL> if x_mapf : <EOL> data = [ ( x_mapf ( x ) , y ) for ( x , y ) in data ] <EOL> for x_value , y_vals in data : <EOL> hco_x_axis [ x_axis_num ] [ '<STR_LIT>' ] . append ( x_value ) <EOL> for opts , y_value in izip ( y_hco_list_multi , y_vals ) : <EOL> opts [ '<STR_LIT:data>' ] . append ( y_value ) <EOL> self . hcoptions [ '<STR_LIT>' ] . extend ( y_hco_list_multi ) <EOL> class PivotChart ( object ) : <EOL> def __init__ ( self , datasource , series_options , chart_options = None ) : <EOL> """<STR_LIT>""" <EOL> self . user_input = locals ( ) <EOL> if not isinstance ( datasource , PivotDataPool ) : <EOL> raise APIInputError ( "<STR_LIT>" <EOL> % datasource ) <EOL> self . datasource = datasource <EOL> self . series_options = clean_pcso ( series_options , self . datasource ) <EOL> if chart_options is None : <EOL> chart_options = HCOptions ( { } ) <EOL> self . set_default_hcoptions ( ) <EOL> self . hcoptions . update ( chart_options ) <EOL> self . generate_plot ( ) <EOL> def set_default_hcoptions ( self ) : <EOL> self . hcoptions = HCOptions ( { } ) <EOL> dss = self . datasource . series <EOL> terms = self . series_options . keys ( ) <EOL> lgby_dict = dict ( ( ( t , dss [ t ] [ '<STR_LIT>' ] ) for t in terms ) ) <EOL> lgby_vname_lists = [ [ dss [ t ] [ '<STR_LIT>' ] . get ( lgby , lgby ) <EOL> for lgby in lgby_tuple ] <EOL> for ( t , lgby_tuple ) in lgby_dict . items ( ) ] <EOL> lgby_titles = ( '<STR_LIT::>' . join ( lgby_vname_list ) . title ( ) for <EOL> lgby_vname_list in lgby_vname_lists ) <EOL> term_titles = ( t . title ( ) for t in terms ) <EOL> title = '<STR_LIT>' <EOL> for t , lg in zip ( term_titles , lgby_titles ) : <EOL> if not lg : <EOL> title += "<STR_LIT>" % t <EOL> else : <EOL> title += "<STR_LIT>" % ( t , lg ) <EOL> categories = dss [ terms [ <NUM_LIT:0> ] ] [ '<STR_LIT>' ] <EOL> categories_vnames = [ dss [ terms [ <NUM_LIT:0> ] ] [ '<STR_LIT>' ] [ c ] . title ( ) <EOL> for c in categories ] <EOL> category_title = '<STR_LIT::>' . join ( categories_vnames ) <EOL> chart_title = "<STR_LIT>" % ( title [ : - <NUM_LIT:2> ] , category_title ) <EOL> self . hcoptions [ '<STR_LIT:title>' ] [ '<STR_LIT:text>' ] = chart_title <EOL> def generate_plot ( self ) : <EOL> cv_raw = self . datasource . cv_raw <EOL> hco_series = [ ] <EOL> for term , options in self . series_options . items ( ) : <EOL> dss = self . datasource . series <EOL> for lv in dss [ term ] [ '<STR_LIT>' ] : <EOL> data = [ dss [ term ] [ '<STR_LIT>' ] [ cv ] . get ( lv , None ) for cv <EOL> in cv_raw ] <EOL> term_pretty_name = term . replace ( '<STR_LIT:_>' , '<STR_LIT:U+0020>' ) <EOL> name = term_pretty_name . title ( ) if not lv else "<STR_LIT:->" . join ( lv ) <EOL> hco = copy . deepcopy ( options ) <EOL> hco [ '<STR_LIT:data>' ] = data <EOL> hco [ '<STR_LIT:name>' ] = name <EOL> hco_series . append ( hco ) <EOL> self . hcoptions [ '<STR_LIT>' ] = hco_series <EOL> self . hcoptions [ '<STR_LIT>' ] [ '<STR_LIT>' ] = [ '<STR_LIT::>' . join ( cv ) for cv in <EOL> self . datasource . cv ] </s>
