<s> """<STR_LIT>""" <EOL> import os <EOL> import urllib <EOL> import urllib2 <EOL> import math <EOL> import random <EOL> import re <EOL> import warnings <EOL> import copy <EOL> __version__ = '<STR_LIT>' <EOL> __author__ = '<STR_LIT>' <EOL> reo_colour = re . compile ( '<STR_LIT>' ) <EOL> def _check_colour ( colour ) : <EOL> if not reo_colour . match ( colour ) : <EOL> raise InvalidParametersException ( '<STR_LIT>' '<STR_LIT>' % colour ) <EOL> def _reset_warnings ( ) : <EOL> """<STR_LIT>""" <EOL> globals ( ) [ '<STR_LIT>' ] = None <EOL> class PyGoogleChartException ( Exception ) : <EOL> pass <EOL> class DataOutOfRangeException ( PyGoogleChartException ) : <EOL> pass <EOL> class UnknownDataTypeException ( PyGoogleChartException ) : <EOL> pass <EOL> class NoDataGivenException ( PyGoogleChartException ) : <EOL> pass <EOL> class InvalidParametersException ( PyGoogleChartException ) : <EOL> pass <EOL> class BadContentTypeException ( PyGoogleChartException ) : <EOL> pass <EOL> class AbstractClassException ( PyGoogleChartException ) : <EOL> pass <EOL> class UnknownChartType ( PyGoogleChartException ) : <EOL> pass <EOL> class Data ( object ) : <EOL> def __init__ ( self , data ) : <EOL> if type ( self ) == Data : <EOL> raise AbstractClassException ( '<STR_LIT>' ) <EOL> self . data = data <EOL> @ classmethod <EOL> def float_scale_value ( cls , value , range ) : <EOL> lower , upper = range <EOL> assert ( upper > lower ) <EOL> scaled = ( value - lower ) * ( float ( cls . max_value ) / ( upper - lower ) ) <EOL> return scaled <EOL> @ classmethod <EOL> def clip_value ( cls , value ) : <EOL> return max ( <NUM_LIT:0> , min ( value , cls . max_value ) ) <EOL> @ classmethod <EOL> def int_scale_value ( cls , value , range ) : <EOL> return int ( round ( cls . float_scale_value ( value , range ) ) ) <EOL> @ classmethod <EOL> def scale_value ( cls , value , range ) : <EOL> scaled = cls . int_scale_value ( value , range ) <EOL> clipped = cls . clip_value ( scaled ) <EOL> Data . check_clip ( scaled , clipped ) <EOL> return clipped <EOL> @ staticmethod <EOL> def check_clip ( scaled , clipped ) : <EOL> if clipped != scaled : <EOL> warnings . warn ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> class SimpleData ( Data ) : <EOL> max_value = <NUM_LIT> <EOL> enc_map = '<STR_LIT>' <EOL> def __repr__ ( self ) : <EOL> encoded_data = [ ] <EOL> for data in self . data : <EOL> sub_data = [ ] <EOL> for value in data : <EOL> if value is None : <EOL> sub_data . append ( '<STR_LIT:_>' ) <EOL> elif value >= <NUM_LIT:0> and value <= self . max_value : <EOL> sub_data . append ( SimpleData . enc_map [ value ] ) <EOL> else : <EOL> raise DataOutOfRangeException ( '<STR_LIT>' <EOL> % value ) <EOL> encoded_data . append ( '<STR_LIT>' . join ( sub_data ) ) <EOL> return '<STR_LIT>' + '<STR_LIT:U+002C>' . join ( encoded_data ) <EOL> class TextData ( Data ) : <EOL> max_value = <NUM_LIT:100> <EOL> def __repr__ ( self ) : <EOL> encoded_data = [ ] <EOL> for data in self . data : <EOL> sub_data = [ ] <EOL> for value in data : <EOL> if value is None : <EOL> sub_data . append ( - <NUM_LIT:1> ) <EOL> elif value >= <NUM_LIT:0> and value <= self . max_value : <EOL> sub_data . append ( "<STR_LIT>" % float ( value ) ) <EOL> else : <EOL> raise DataOutOfRangeException ( ) <EOL> encoded_data . append ( '<STR_LIT:U+002C>' . join ( sub_data ) ) <EOL> return '<STR_LIT>' + '<STR_LIT:|>' . join ( encoded_data ) <EOL> @ classmethod <EOL> def scale_value ( cls , value , range ) : <EOL> scaled = cls . float_scale_value ( value , range ) <EOL> clipped = cls . clip_value ( scaled ) <EOL> Data . check_clip ( scaled , clipped ) <EOL> return clipped <EOL> class ExtendedData ( Data ) : <EOL> max_value = <NUM_LIT> <EOL> enc_map = '<STR_LIT>' <EOL> def __repr__ ( self ) : <EOL> encoded_data = [ ] <EOL> enc_size = len ( ExtendedData . enc_map ) <EOL> for data in self . data : <EOL> sub_data = [ ] <EOL> for value in data : <EOL> if value is None : <EOL> sub_data . append ( '<STR_LIT>' ) <EOL> elif value >= <NUM_LIT:0> and value <= self . max_value : <EOL> first , second = divmod ( int ( value ) , enc_size ) <EOL> sub_data . append ( '<STR_LIT>' % ( <EOL> ExtendedData . enc_map [ first ] , <EOL> ExtendedData . enc_map [ second ] ) ) <EOL> else : <EOL> raise DataOutOfRangeException ( '<STR_LIT>' % ( data . index ( value ) , value ) ) <EOL> encoded_data . append ( '<STR_LIT>' . join ( sub_data ) ) <EOL> return '<STR_LIT>' + '<STR_LIT:U+002C>' . join ( encoded_data ) <EOL> class Axis ( object ) : <EOL> BOTTOM = '<STR_LIT:x>' <EOL> TOP = '<STR_LIT:t>' <EOL> LEFT = '<STR_LIT:y>' <EOL> RIGHT = '<STR_LIT:r>' <EOL> TYPES = ( BOTTOM , TOP , LEFT , RIGHT ) <EOL> def __init__ ( self , axis_index , axis_type , ** kw ) : <EOL> assert ( axis_type in Axis . TYPES ) <EOL> self . has_style = False <EOL> self . axis_index = axis_index <EOL> self . axis_type = axis_type <EOL> self . positions = None <EOL> def set_index ( self , axis_index ) : <EOL> self . axis_index = axis_index <EOL> def set_positions ( self , positions ) : <EOL> self . positions = positions <EOL> def set_style ( self , colour , font_size = None , alignment = None ) : <EOL> _check_colour ( colour ) <EOL> self . colour = colour <EOL> self . font_size = font_size <EOL> self . alignment = alignment <EOL> self . has_style = True <EOL> def style_to_url ( self ) : <EOL> bits = [ ] <EOL> bits . append ( str ( self . axis_index ) ) <EOL> bits . append ( self . colour ) <EOL> if self . font_size is not None : <EOL> bits . append ( str ( self . font_size ) ) <EOL> if self . alignment is not None : <EOL> bits . append ( str ( self . alignment ) ) <EOL> return '<STR_LIT:U+002C>' . join ( bits ) <EOL> def positions_to_url ( self ) : <EOL> bits = [ ] <EOL> bits . append ( str ( self . axis_index ) ) <EOL> bits += [ str ( a ) for a in self . positions ] <EOL> return '<STR_LIT:U+002C>' . join ( bits ) <EOL> class LabelAxis ( Axis ) : <EOL> def __init__ ( self , axis_index , axis_type , values , ** kwargs ) : <EOL> Axis . __init__ ( self , axis_index , axis_type , ** kwargs ) <EOL> self . values = [ str ( a ) for a in values ] <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . axis_index , '<STR_LIT:|>' . join ( self . values ) ) <EOL> class RangeAxis ( Axis ) : <EOL> def __init__ ( self , axis_index , axis_type , low , high , ** kwargs ) : <EOL> Axis . __init__ ( self , axis_index , axis_type , ** kwargs ) <EOL> self . low = low <EOL> self . high = high <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . axis_index , self . low , self . high ) <EOL> class Chart ( object ) : <EOL> """<STR_LIT>""" <EOL> BASE_URL = '<STR_LIT>' <EOL> BACKGROUND = '<STR_LIT>' <EOL> CHART = '<STR_LIT:c>' <EOL> ALPHA = '<STR_LIT:a>' <EOL> VALID_SOLID_FILL_TYPES = ( BACKGROUND , CHART , ALPHA ) <EOL> SOLID = '<STR_LIT:s>' <EOL> LINEAR_GRADIENT = '<STR_LIT>' <EOL> LINEAR_STRIPES = '<STR_LIT>' <EOL> def __init__ ( self , width , height , title = None , legend = None , colours = None , <EOL> auto_scale = True , x_range = None , y_range = None , <EOL> colours_within_series = None ) : <EOL> if type ( self ) == Chart : <EOL> raise AbstractClassException ( '<STR_LIT>' ) <EOL> assert ( isinstance ( width , int ) ) <EOL> assert ( isinstance ( height , int ) ) <EOL> self . width = width <EOL> self . height = height <EOL> self . data = [ ] <EOL> self . set_title ( title ) <EOL> self . set_legend ( legend ) <EOL> self . set_legend_position ( None ) <EOL> self . set_colours ( colours ) <EOL> self . set_colours_within_series ( colours_within_series ) <EOL> self . auto_scale = auto_scale <EOL> self . x_range = x_range <EOL> self . y_range = y_range <EOL> self . scaled_data_class = None <EOL> self . scaled_x_range = None <EOL> self . scaled_y_range = None <EOL> self . fill_types = { <EOL> Chart . BACKGROUND : None , <EOL> Chart . CHART : None , <EOL> Chart . ALPHA : None , <EOL> } <EOL> self . fill_area = { <EOL> Chart . BACKGROUND : None , <EOL> Chart . CHART : None , <EOL> Chart . ALPHA : None , <EOL> } <EOL> self . axis = [ ] <EOL> self . markers = [ ] <EOL> self . line_styles = { } <EOL> self . grid = None <EOL> def get_url ( self , data_class = None ) : <EOL> url_bits = self . get_url_bits ( data_class = data_class ) <EOL> return self . BASE_URL + '<STR_LIT:&>' . join ( url_bits ) <EOL> def get_url_bits ( self , data_class = None ) : <EOL> url_bits = [ ] <EOL> url_bits . append ( self . type_to_url ( ) ) <EOL> url_bits . append ( '<STR_LIT>' % ( self . width , self . height ) ) <EOL> url_bits . append ( self . data_to_url ( data_class = data_class ) ) <EOL> if self . title : <EOL> url_bits . append ( '<STR_LIT>' % self . title ) <EOL> if self . legend : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( self . legend ) ) <EOL> if self . legend_position : <EOL> url_bits . append ( '<STR_LIT>' % ( self . legend_position ) ) <EOL> if self . colours : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( self . colours ) ) <EOL> if self . colours_within_series : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( self . colours_within_series ) ) <EOL> ret = self . fill_to_url ( ) <EOL> if ret : <EOL> url_bits . append ( ret ) <EOL> ret = self . axis_to_url ( ) <EOL> if ret : <EOL> url_bits . append ( ret ) <EOL> if self . markers : <EOL> url_bits . append ( self . markers_to_url ( ) ) <EOL> if self . line_styles : <EOL> style = [ ] <EOL> for index in xrange ( max ( self . line_styles ) + <NUM_LIT:1> ) : <EOL> if index in self . line_styles : <EOL> values = self . line_styles [ index ] <EOL> else : <EOL> values = ( '<STR_LIT:1>' , ) <EOL> style . append ( '<STR_LIT:U+002C>' . join ( values ) ) <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( style ) ) <EOL> if self . grid : <EOL> url_bits . append ( '<STR_LIT>' % self . grid ) <EOL> return url_bits <EOL> def download ( self , file_name ) : <EOL> opener = urllib2 . urlopen ( self . get_url ( ) ) <EOL> if opener . headers [ '<STR_LIT>' ] != '<STR_LIT>' : <EOL> raise BadContentTypeException ( '<STR_LIT>' '<STR_LIT>' % opener . headers [ '<STR_LIT>' ] ) <EOL> open ( file_name , '<STR_LIT:wb>' ) . write ( opener . read ( ) ) <EOL> def set_title ( self , title ) : <EOL> if title : <EOL> self . title = urllib . quote ( title ) <EOL> else : <EOL> self . title = None <EOL> def set_legend ( self , legend ) : <EOL> """<STR_LIT>""" <EOL> assert ( isinstance ( legend , list ) or isinstance ( legend , tuple ) or <EOL> legend is None ) <EOL> if legend : <EOL> self . legend = [ urllib . quote ( a ) for a in legend ] <EOL> else : <EOL> self . legend = None <EOL> def set_legend_position ( self , legend_position ) : <EOL> if legend_position : <EOL> self . legend_position = urllib . quote ( legend_position ) <EOL> else : <EOL> self . legend_position = None <EOL> def set_colours ( self , colours ) : <EOL> assert ( isinstance ( colours , list ) or isinstance ( colours , tuple ) or <EOL> colours is None ) <EOL> if colours : <EOL> for col in colours : <EOL> _check_colour ( col ) <EOL> self . colours = colours <EOL> def set_colours_within_series ( self , colours ) : <EOL> assert ( isinstance ( colours , list ) or isinstance ( colours , tuple ) or <EOL> colours is None ) <EOL> if colours : <EOL> for col in colours : <EOL> _check_colour ( col ) <EOL> self . colours_within_series = colours <EOL> def fill_solid ( self , area , colour ) : <EOL> assert ( area in Chart . VALID_SOLID_FILL_TYPES ) <EOL> _check_colour ( colour ) <EOL> self . fill_area [ area ] = colour <EOL> self . fill_types [ area ] = Chart . SOLID <EOL> def _check_fill_linear ( self , angle , * args ) : <EOL> assert ( isinstance ( args , list ) or isinstance ( args , tuple ) ) <EOL> assert ( angle >= <NUM_LIT:0> and angle <= <NUM_LIT> ) <EOL> assert ( len ( args ) % <NUM_LIT:2> == <NUM_LIT:0> ) <EOL> args = list ( args ) <EOL> for a in xrange ( len ( args ) / <NUM_LIT:2> ) : <EOL> col = args [ a * <NUM_LIT:2> ] <EOL> offset = args [ a * <NUM_LIT:2> + <NUM_LIT:1> ] <EOL> _check_colour ( col ) <EOL> assert ( offset >= <NUM_LIT:0> and offset <= <NUM_LIT:1> ) <EOL> args [ a * <NUM_LIT:2> + <NUM_LIT:1> ] = str ( args [ a * <NUM_LIT:2> + <NUM_LIT:1> ] ) <EOL> return args <EOL> def fill_linear_gradient ( self , area , angle , * args ) : <EOL> assert ( area in Chart . VALID_SOLID_FILL_TYPES ) <EOL> args = self . _check_fill_linear ( angle , * args ) <EOL> self . fill_types [ area ] = Chart . LINEAR_GRADIENT <EOL> self . fill_area [ area ] = '<STR_LIT:U+002C>' . join ( [ str ( angle ) ] + args ) <EOL> def fill_linear_stripes ( self , area , angle , * args ) : <EOL> assert ( area in Chart . VALID_SOLID_FILL_TYPES ) <EOL> args = self . _check_fill_linear ( angle , * args ) <EOL> self . fill_types [ area ] = Chart . LINEAR_STRIPES <EOL> self . fill_area [ area ] = '<STR_LIT:U+002C>' . join ( [ str ( angle ) ] + args ) <EOL> def fill_to_url ( self ) : <EOL> areas = [ ] <EOL> for area in ( Chart . BACKGROUND , Chart . CHART , Chart . ALPHA ) : <EOL> if self . fill_types [ area ] : <EOL> areas . append ( '<STR_LIT>' % ( area , self . fill_types [ area ] , self . fill_area [ area ] ) ) <EOL> if areas : <EOL> return '<STR_LIT>' + '<STR_LIT:|>' . join ( areas ) <EOL> def data_class_detection ( self , data ) : <EOL> """<STR_LIT>""" <EOL> assert ( isinstance ( data , list ) or isinstance ( data , tuple ) ) <EOL> if not isinstance ( self , ( LineChart , BarChart , ScatterChart ) ) : <EOL> return SimpleData <EOL> elif self . height < <NUM_LIT:100> : <EOL> return SimpleData <EOL> else : <EOL> return ExtendedData <EOL> def _filter_none ( self , data ) : <EOL> return [ r for r in data if r is not None ] <EOL> def data_x_range ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> lower = min ( [ min ( self . _filter_none ( s ) ) <EOL> for type , s in self . annotated_data ( ) <EOL> if type == '<STR_LIT:x>' ] ) <EOL> upper = max ( [ max ( self . _filter_none ( s ) ) <EOL> for type , s in self . annotated_data ( ) <EOL> if type == '<STR_LIT:x>' ] ) <EOL> return ( lower , upper ) <EOL> except ValueError : <EOL> return None <EOL> def data_y_range ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> lower = min ( [ min ( self . _filter_none ( s ) ) <EOL> for type , s in self . annotated_data ( ) <EOL> if type == '<STR_LIT:y>' ] ) <EOL> upper = max ( [ max ( self . _filter_none ( s ) ) + <NUM_LIT:1> <EOL> for type , s in self . annotated_data ( ) <EOL> if type == '<STR_LIT:y>' ] ) <EOL> return ( lower , upper ) <EOL> except ValueError : <EOL> return None <EOL> def scaled_data ( self , data_class , x_range = None , y_range = None ) : <EOL> """<STR_LIT>""" <EOL> self . scaled_data_class = data_class <EOL> if x_range is None : <EOL> x_range = self . data_x_range ( ) <EOL> if x_range and x_range [ <NUM_LIT:0> ] > <NUM_LIT:0> : <EOL> x_range = ( x_range [ <NUM_LIT:0> ] , x_range [ <NUM_LIT:1> ] ) <EOL> self . scaled_x_range = x_range <EOL> if y_range is None : <EOL> y_range = self . data_y_range ( ) <EOL> if y_range and y_range [ <NUM_LIT:0> ] > <NUM_LIT:0> : <EOL> y_range = ( y_range [ <NUM_LIT:0> ] , y_range [ <NUM_LIT:1> ] ) <EOL> self . scaled_y_range = y_range <EOL> scaled_data = [ ] <EOL> for type , dataset in self . annotated_data ( ) : <EOL> if type == '<STR_LIT:x>' : <EOL> scale_range = x_range <EOL> elif type == '<STR_LIT:y>' : <EOL> scale_range = y_range <EOL> elif type == '<STR_LIT>' : <EOL> scale_range = ( <NUM_LIT:0> , max ( dataset ) ) <EOL> scaled_dataset = [ ] <EOL> for v in dataset : <EOL> if v is None : <EOL> scaled_dataset . append ( None ) <EOL> else : <EOL> scaled_dataset . append ( <EOL> data_class . scale_value ( v , scale_range ) ) <EOL> scaled_data . append ( scaled_dataset ) <EOL> return scaled_data <EOL> def add_data ( self , data ) : <EOL> self . data . append ( data ) <EOL> return len ( self . data ) - <NUM_LIT:1> <EOL> def data_to_url ( self , data_class = None ) : <EOL> if not data_class : <EOL> data_class = self . data_class_detection ( self . data ) <EOL> if not issubclass ( data_class , Data ) : <EOL> raise UnknownDataTypeException ( ) <EOL> if self . auto_scale : <EOL> data = self . scaled_data ( data_class , self . x_range , self . y_range ) <EOL> else : <EOL> data = self . data <EOL> return repr ( data_class ( data ) ) <EOL> def annotated_data ( self ) : <EOL> for dataset in self . data : <EOL> yield ( '<STR_LIT:x>' , dataset ) <EOL> def set_axis_labels ( self , axis_type , values ) : <EOL> assert ( axis_type in Axis . TYPES ) <EOL> values = [ urllib . quote ( str ( a ) ) for a in values ] <EOL> axis_index = len ( self . axis ) <EOL> axis = LabelAxis ( axis_index , axis_type , values ) <EOL> self . axis . append ( axis ) <EOL> return axis_index <EOL> def set_axis_range ( self , axis_type , low , high ) : <EOL> assert ( axis_type in Axis . TYPES ) <EOL> axis_index = len ( self . axis ) <EOL> axis = RangeAxis ( axis_index , axis_type , low , high ) <EOL> self . axis . append ( axis ) <EOL> return axis_index <EOL> def set_axis_positions ( self , axis_index , positions ) : <EOL> try : <EOL> self . axis [ axis_index ] . set_positions ( positions ) <EOL> except IndexError : <EOL> raise InvalidParametersException ( '<STR_LIT>' '<STR_LIT>' % axis ) <EOL> def set_axis_style ( self , axis_index , colour , font_size = None , alignment = None ) : <EOL> try : <EOL> self . axis [ axis_index ] . set_style ( colour , font_size , alignment ) <EOL> except IndexError : <EOL> raise InvalidParametersException ( '<STR_LIT>' '<STR_LIT>' % axis ) <EOL> def axis_to_url ( self ) : <EOL> available_axis = [ ] <EOL> label_axis = [ ] <EOL> range_axis = [ ] <EOL> positions = [ ] <EOL> styles = [ ] <EOL> index = - <NUM_LIT:1> <EOL> for axis in self . axis : <EOL> available_axis . append ( axis . axis_type ) <EOL> if isinstance ( axis , RangeAxis ) : <EOL> range_axis . append ( repr ( axis ) ) <EOL> if isinstance ( axis , LabelAxis ) : <EOL> label_axis . append ( repr ( axis ) ) <EOL> if axis . positions : <EOL> positions . append ( axis . positions_to_url ( ) ) <EOL> if axis . has_style : <EOL> styles . append ( axis . style_to_url ( ) ) <EOL> if not available_axis : <EOL> return <EOL> url_bits = [ ] <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( available_axis ) ) <EOL> if label_axis : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( label_axis ) ) <EOL> if range_axis : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( range_axis ) ) <EOL> if positions : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( positions ) ) <EOL> if styles : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( styles ) ) <EOL> return '<STR_LIT:&>' . join ( url_bits ) <EOL> def markers_to_url ( self ) : <EOL> return '<STR_LIT>' % '<STR_LIT:|>' . join ( [ '<STR_LIT:U+002C>' . join ( a ) for a in self . markers ] ) <EOL> def add_marker ( self , index , point , marker_type , colour , size , priority = <NUM_LIT:0> ) : <EOL> self . markers . append ( ( marker_type , colour , str ( index ) , str ( point ) , str ( size ) , str ( priority ) ) ) <EOL> def add_horizontal_range ( self , colour , start , stop ) : <EOL> self . markers . append ( ( '<STR_LIT:r>' , colour , '<STR_LIT:0>' , str ( start ) , str ( stop ) ) ) <EOL> def add_data_line ( self , colour , data_set , size , priority = <NUM_LIT:0> ) : <EOL> self . markers . append ( ( '<STR_LIT:D>' , colour , str ( data_set ) , '<STR_LIT:0>' , str ( size ) , str ( priority ) ) ) <EOL> def add_marker_text ( self , string , colour , data_set , data_point , size , priority = <NUM_LIT:0> ) : <EOL> self . markers . append ( ( str ( string ) , colour , str ( data_set ) , str ( data_point ) , str ( size ) , str ( priority ) ) ) <EOL> def add_vertical_range ( self , colour , start , stop ) : <EOL> self . markers . append ( ( '<STR_LIT:R>' , colour , '<STR_LIT:0>' , str ( start ) , str ( stop ) ) ) <EOL> def add_fill_range ( self , colour , index_start , index_end ) : <EOL> self . markers . append ( ( '<STR_LIT:b>' , colour , str ( index_start ) , str ( index_end ) , '<STR_LIT:1>' ) ) <EOL> def add_fill_simple ( self , colour ) : <EOL> self . markers . append ( ( '<STR_LIT:B>' , colour , '<STR_LIT:1>' , '<STR_LIT:1>' , '<STR_LIT:1>' ) ) <EOL> def set_line_style ( self , index , thickness = <NUM_LIT:1> , line_segment = None , blank_segment = None ) : <EOL> value = [ ] <EOL> value . append ( str ( thickness ) ) <EOL> if line_segment : <EOL> value . append ( str ( line_segment ) ) <EOL> value . append ( str ( blank_segment ) ) <EOL> self . line_styles [ index ] = value <EOL> def set_grid ( self , x_step , y_step , line_segment = <NUM_LIT:1> , blank_segment = <NUM_LIT:0> ) : <EOL> self . grid = '<STR_LIT>' % ( x_step , y_step , line_segment , blank_segment ) <EOL> class ScatterChart ( Chart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def annotated_data ( self ) : <EOL> yield ( '<STR_LIT:x>' , self . data [ <NUM_LIT:0> ] ) <EOL> yield ( '<STR_LIT:y>' , self . data [ <NUM_LIT:1> ] ) <EOL> if len ( self . data ) > <NUM_LIT:2> : <EOL> yield ( '<STR_LIT>' , self . data [ <NUM_LIT:2> ] ) <EOL> class LineChart ( Chart ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> if type ( self ) == LineChart : <EOL> raise AbstractClassException ( '<STR_LIT>' ) <EOL> Chart . __init__ ( self , * args , ** kwargs ) <EOL> class SimpleLineChart ( LineChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def annotated_data ( self ) : <EOL> for dataset in self . data : <EOL> yield ( '<STR_LIT:y>' , dataset ) <EOL> class SparkLineChart ( SimpleLineChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class XYLineChart ( LineChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def annotated_data ( self ) : <EOL> for i , dataset in enumerate ( self . data ) : <EOL> if i % <NUM_LIT:2> == <NUM_LIT:0> : <EOL> yield ( '<STR_LIT:x>' , dataset ) <EOL> else : <EOL> yield ( '<STR_LIT:y>' , dataset ) <EOL> class BarChart ( Chart ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> if type ( self ) == BarChart : <EOL> raise AbstractClassException ( '<STR_LIT>' ) <EOL> Chart . __init__ ( self , * args , ** kwargs ) <EOL> self . bar_width = None <EOL> self . zero_lines = { } <EOL> def set_bar_width ( self , bar_width ) : <EOL> self . bar_width = bar_width <EOL> def set_zero_line ( self , index , zero_line ) : <EOL> self . zero_lines [ index ] = zero_line <EOL> def get_url_bits ( self , data_class = None , skip_chbh = False ) : <EOL> url_bits = Chart . get_url_bits ( self , data_class = data_class ) <EOL> if not skip_chbh and self . bar_width is not None : <EOL> url_bits . append ( '<STR_LIT>' % self . bar_width ) <EOL> zero_line = [ ] <EOL> if self . zero_lines : <EOL> for index in xrange ( max ( self . zero_lines ) + <NUM_LIT:1> ) : <EOL> if index in self . zero_lines : <EOL> zero_line . append ( str ( self . zero_lines [ index ] ) ) <EOL> else : <EOL> zero_line . append ( '<STR_LIT:0>' ) <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( zero_line ) ) <EOL> return url_bits <EOL> class StackedHorizontalBarChart ( BarChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class StackedVerticalBarChart ( BarChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def annotated_data ( self ) : <EOL> for dataset in self . data : <EOL> yield ( '<STR_LIT:y>' , dataset ) <EOL> class GroupedBarChart ( BarChart ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> if type ( self ) == GroupedBarChart : <EOL> raise AbstractClassException ( '<STR_LIT>' ) <EOL> BarChart . __init__ ( self , * args , ** kwargs ) <EOL> self . bar_spacing = None <EOL> self . group_spacing = None <EOL> def set_bar_spacing ( self , spacing ) : <EOL> """<STR_LIT>""" <EOL> self . bar_spacing = spacing <EOL> def set_group_spacing ( self , spacing ) : <EOL> """<STR_LIT>""" <EOL> self . group_spacing = spacing <EOL> def get_url_bits ( self , data_class = None ) : <EOL> url_bits = BarChart . get_url_bits ( self , data_class = data_class , <EOL> skip_chbh = True ) <EOL> if self . group_spacing is not None : <EOL> if self . bar_spacing is None : <EOL> raise InvalidParametersException ( '<STR_LIT>' '<STR_LIT>' ) <EOL> if self . bar_width is None : <EOL> raise InvalidParametersException ( '<STR_LIT>' '<STR_LIT>' ) <EOL> url_bits . append ( '<STR_LIT>' <EOL> % ( self . bar_width , self . bar_spacing , self . group_spacing ) ) <EOL> elif self . bar_spacing is not None : <EOL> if self . bar_width is None : <EOL> raise InvalidParametersException ( '<STR_LIT>' '<STR_LIT>' ) <EOL> url_bits . append ( '<STR_LIT>' % ( self . bar_width , self . bar_spacing ) ) <EOL> elif self . bar_width : <EOL> url_bits . append ( '<STR_LIT>' % self . bar_width ) <EOL> return url_bits <EOL> class GroupedHorizontalBarChart ( GroupedBarChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class GroupedVerticalBarChart ( GroupedBarChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def annotated_data ( self ) : <EOL> for dataset in self . data : <EOL> yield ( '<STR_LIT:y>' , dataset ) <EOL> class PieChart ( Chart ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> if type ( self ) == PieChart : <EOL> raise AbstractClassException ( '<STR_LIT>' ) <EOL> Chart . __init__ ( self , * args , ** kwargs ) <EOL> self . pie_labels = [ ] <EOL> if self . y_range : <EOL> warnings . warn ( '<STR_LIT>' % ( self . __class__ . __name__ ) ) <EOL> def set_pie_labels ( self , labels ) : <EOL> self . pie_labels = [ urllib . quote ( a ) for a in labels ] <EOL> def get_url_bits ( self , data_class = None ) : <EOL> url_bits = Chart . get_url_bits ( self , data_class = data_class ) <EOL> if self . pie_labels : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT:|>' . join ( self . pie_labels ) ) <EOL> return url_bits <EOL> def annotated_data ( self ) : <EOL> for dataset in self . data : <EOL> yield ( '<STR_LIT:x>' , dataset ) <EOL> def scaled_data ( self , data_class , x_range = None , y_range = None ) : <EOL> if not x_range : <EOL> x_range = [ <NUM_LIT:0> , sum ( self . data [ <NUM_LIT:0> ] ) ] <EOL> return Chart . scaled_data ( self , data_class , x_range , self . y_range ) <EOL> class PieChart2D ( PieChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class PieChart3D ( PieChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class VennChart ( Chart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def annotated_data ( self ) : <EOL> for dataset in self . data : <EOL> yield ( '<STR_LIT:y>' , dataset ) <EOL> class RadarChart ( Chart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class SplineRadarChart ( RadarChart ) : <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class MapChart ( Chart ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> Chart . __init__ ( self , * args , ** kwargs ) <EOL> self . geo_area = '<STR_LIT>' <EOL> self . codes = [ ] <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def set_codes ( self , codes ) : <EOL> self . codes = codes <EOL> def get_url_bits ( self , data_class = None ) : <EOL> url_bits = Chart . get_url_bits ( self , data_class = data_class ) <EOL> url_bits . append ( '<STR_LIT>' % self . geo_area ) <EOL> if self . codes : <EOL> url_bits . append ( '<STR_LIT>' % '<STR_LIT>' . join ( self . codes ) ) <EOL> return url_bits <EOL> class GoogleOMeterChart ( PieChart ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> PieChart . __init__ ( self , * args , ** kwargs ) <EOL> if self . auto_scale and not self . x_range : <EOL> warnings . warn ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> class QRChart ( Chart ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> Chart . __init__ ( self , * args , ** kwargs ) <EOL> self . encoding = None <EOL> self . ec_level = None <EOL> self . margin = None <EOL> def type_to_url ( self ) : <EOL> return '<STR_LIT>' <EOL> def data_to_url ( self , data_class = None ) : <EOL> if not self . data : <EOL> raise NoDataGivenException ( ) <EOL> return '<STR_LIT>' % urllib . quote ( self . data [ <NUM_LIT:0> ] ) <EOL> def get_url_bits ( self , data_class = None ) : <EOL> url_bits = Chart . get_url_bits ( self , data_class = data_class ) <EOL> if self . encoding : <EOL> url_bits . append ( '<STR_LIT>' % self . encoding ) <EOL> if self . ec_level : <EOL> url_bits . append ( '<STR_LIT>' % ( self . ec_level , self . margin ) ) <EOL> return url_bits <EOL> def set_encoding ( self , encoding ) : <EOL> self . encoding = encoding <EOL> def set_ec ( self , level , margin ) : <EOL> self . ec_level = level <EOL> self . margin = margin <EOL> class ChartGrammar ( object ) : <EOL> def __init__ ( self ) : <EOL> self . grammar = None <EOL> self . chart = None <EOL> def parse ( self , grammar ) : <EOL> self . grammar = grammar <EOL> self . chart = self . create_chart_instance ( ) <EOL> for attr in self . grammar : <EOL> if attr in ( '<STR_LIT:w>' , '<STR_LIT:h>' , '<STR_LIT:type>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> continue <EOL> attr_func = '<STR_LIT>' + attr <EOL> if not hasattr ( self , attr_func ) : <EOL> warnings . warn ( '<STR_LIT>' % ( attr ) ) <EOL> continue <EOL> getattr ( self , attr_func ) ( grammar [ attr ] ) <EOL> return self . chart <EOL> def parse_data ( self , data ) : <EOL> self . chart . data = data <EOL> @ staticmethod <EOL> def get_possible_chart_types ( ) : <EOL> possible_charts = [ ] <EOL> for cls_name in globals ( ) . keys ( ) : <EOL> if not cls_name . endswith ( '<STR_LIT>' ) : <EOL> continue <EOL> cls = globals ( ) [ cls_name ] <EOL> try : <EOL> a = cls ( <NUM_LIT:1> , <NUM_LIT:1> , auto_scale = False ) <EOL> del a <EOL> except AbstractClassException : <EOL> continue <EOL> possible_charts . append ( cls_name [ : - <NUM_LIT:5> ] ) <EOL> return possible_charts <EOL> def create_chart_instance ( self , grammar = None ) : <EOL> if not grammar : <EOL> grammar = self . grammar <EOL> assert ( isinstance ( grammar , dict ) ) <EOL> assert ( '<STR_LIT:w>' in grammar ) <EOL> assert ( '<STR_LIT:h>' in grammar ) <EOL> assert ( '<STR_LIT:type>' in grammar ) <EOL> chart_type = grammar [ '<STR_LIT:type>' ] <EOL> w = grammar [ '<STR_LIT:w>' ] <EOL> h = grammar [ '<STR_LIT:h>' ] <EOL> auto_scale = grammar . get ( '<STR_LIT>' , None ) <EOL> x_range = grammar . get ( '<STR_LIT>' , None ) <EOL> y_range = grammar . get ( '<STR_LIT>' , None ) <EOL> types = ChartGrammar . get_possible_chart_types ( ) <EOL> if chart_type not in types : <EOL> raise UnknownChartType ( '<STR_LIT>' <EOL> '<STR_LIT>' % ( chart_type , '<STR_LIT:U+002C>' . join ( types ) ) ) <EOL> return globals ( ) [ chart_type + '<STR_LIT>' ] ( w , h , auto_scale = auto_scale , <EOL> x_range = x_range , y_range = y_range ) <EOL> def download ( self ) : <EOL> pass </s>
