Changeset 169 for trunk/pycha

Show
Ignore:
Timestamp:
03/17/09 05:27:31 (3 years ago)
Author:
lgs
Message:

Big refactor about how the colors scheme are created and used. See #29

Location:
trunk/pycha
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/pycha/bar.py

    r149 r169  
    8686 
    8787                if self.options.shouldFill: 
    88                     cx.set_source_rgb(*self.options.colorScheme[bar.name]) 
     88                    cx.set_source_rgb(*self.colorScheme[bar.name]) 
    8989                    cx.fill_preserve() 
    9090 
  • trunk/pycha/chart.py

    r149 r169  
    2121import cairo 
    2222 
    23 from pycha.color import (defaultColorscheme, getColorscheme, hex2rgb, 
    24                          DEFAULT_COLOR) 
     23from pycha.color import ColorScheme, hex2rgb, DEFAULT_COLOR 
    2524 
    2625 
     
    5756        self._initSurface(surface) 
    5857 
     58        self.colorScheme = None 
     59 
    5960    def addDataset(self, dataset): 
    6061        """Adds an object containing chart data to the storage hash""" 
     
    113114 
    114115    def _setColorscheme(self): 
    115         """Sets the colorScheme used for the chart using the color in the 
     116        """Sets the colorScheme used for the chart using the 
    116117        options.colorScheme option 
    117118        """ 
    118         scheme = self.options.colorScheme 
     119        name = self.options.colorScheme.name 
    119120        keys = self._getDatasetsKeys() 
    120         if isinstance(scheme, dict): 
    121             if not scheme: 
    122                 self.options.colorScheme = defaultColorscheme(keys) 
    123         elif isinstance(scheme, basestring): 
    124             self.options.colorScheme = getColorscheme(scheme, keys) 
    125         else: 
    126             raise TypeError("Color scheme is invalid!") 
     121        colorSchemeClass = ColorScheme.getColorScheme(name, None) 
     122        if colorSchemeClass is None: 
     123            raise ValueError('Color scheme is invalid!') 
     124 
     125        kwargs = dict(self.options.colorScheme.args) 
     126        self.colorScheme = colorSchemeClass(keys, **kwargs) 
    127127 
    128128    def _initSurface(self, surface): 
     
    552552        def drawKey(key, x, y, text_height): 
    553553            cx.rectangle(x, y, bullet, bullet) 
    554             cx.set_source_rgb(*self.options.colorScheme[key]) 
     554            cx.set_source_rgb(*self.colorScheme[key]) 
    555555            cx.fill_preserve() 
    556556            cx.set_source_rgb(0, 0, 0) 
     
    670670    barWidthFillFraction=0.75, 
    671671    pieRadius=0.4, 
    672     colorScheme=DEFAULT_COLOR, 
     672    colorScheme=Option( 
     673        name='gradient', 
     674        args=Option(initialColor=DEFAULT_COLOR), 
     675    ), 
    673676    title=None, 
    674677    titleFont='Tahoma', 
  • trunk/pycha/color.py

    r140 r169  
    11# Copyright(c) 2007-2009 by Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> 
     2#              2009 by Yaco S.L. <lgs@yaco.es> 
    23# 
    34# This file is part of PyCha. 
     
    5354 
    5455 
    55 def generateColorscheme(masterColor, keys): 
    56     """Generates a dictionary where the keys match the keys argument and 
    57     the values are colors derivated from the masterColor. 
    58  
    59     Each color is a lighter version of masterColor. This difference is 
    60     computed based on the number of keys. 
    61  
    62     The masterColor is given in a hex string format. 
    63     """ 
    64     r, g, b = hex2rgb(masterColor) 
    65     light = 1.0 / (len(keys)*2) 
    66     return dict([(key, lighten(r, g, b, light * i)) 
    67                  for i, key in enumerate(keys)]) 
    68  
    69  
    70 def defaultColorscheme(keys): 
    71     """Return the default color scheme (derived from a dark green)""" 
    72     return generateColorscheme(DEFAULT_COLOR, keys) 
    73  
    74  
    75 def getColorscheme(color, keys): 
    76     """Get a color scheme from the six predefined ones or makes another 
    77     one if the color is not found 
    78     """ 
    79     return generateColorscheme(colorSchemes.get(color, color), keys) 
    80  
    81  
    82 # default colors for color schemes 
    83 colorSchemes = dict( 
     56basicColors = dict( 
    8457    red='#6d1d1d', 
    8558    green=DEFAULT_COLOR, 
     
    8962    darkcyan='#305755', 
    9063    ) 
     64 
     65 
     66class ColorSchemeMetaclass(type): 
     67    """This metaclass is used to autoregister all ColorScheme classes""" 
     68 
     69    def __new__(mcs, name, bases, dict): 
     70        klass = type.__new__(mcs, name, bases, dict) 
     71        klass.registerColorScheme() 
     72        return klass 
     73 
     74 
     75class ColorScheme(dict): 
     76    """A color scheme is a dictionary where the keys match the keys 
     77    constructor argument and the values are colors""" 
     78 
     79    __metaclass__ = ColorSchemeMetaclass 
     80    __registry__ = {} 
     81 
     82    def __init__(self, keys): 
     83        super(ColorScheme, self).__init__() 
     84 
     85    @classmethod 
     86    def registerColorScheme(cls): 
     87        key = cls.__name__.replace('ColorScheme', '').lower() 
     88        if key: 
     89            cls.__registry__[key] = cls 
     90 
     91    @classmethod 
     92    def getColorScheme(cls, name, default=None): 
     93        return cls.__registry__.get(name, default) 
     94 
     95 
     96class GradientColorScheme(ColorScheme): 
     97    """In this color scheme each color is a lighter version of initialColor. 
     98 
     99    This difference is computed based on the number of keys. 
     100 
     101    The initialColor is given in a hex string format. 
     102    """ 
     103 
     104    def __init__(self, keys, initialColor=DEFAULT_COLOR): 
     105        super(GradientColorScheme, self).__init__(keys) 
     106        if initialColor in basicColors: 
     107            initialColor = basicColors[initialColor] 
     108 
     109        r, g, b = hex2rgb(initialColor) 
     110        light = 1.0 / (len(keys) * 2) 
     111 
     112        for i, key in enumerate(keys): 
     113            self[key] = lighten(r, g, b, light * i) 
  • trunk/pycha/line.py

    r140 r169  
    7474                cx.close_path() 
    7575            else: 
    76                 cx.set_source_rgb(*self.options.colorScheme[storeName]) 
     76                cx.set_source_rgb(*self.colorScheme[storeName]) 
    7777                cx.stroke() 
    7878 
     
    9393 
    9494                # fill the line 
    95                 cx.set_source_rgb(*self.options.colorScheme[storeName]) 
     95                cx.set_source_rgb(*self.colorScheme[storeName]) 
    9696                preparePath(storeName) 
    9797                cx.fill() 
  • trunk/pycha/pie.py

    r140 r169  
    112112        for slice in self.slices: 
    113113            if slice.isBigEnough(): 
    114                 cx.set_source_rgb(*self.options.colorScheme[slice.name]) 
     114                cx.set_source_rgb(*self.colorScheme[slice.name]) 
    115115                if self.options.shouldFill: 
    116116                    slice.draw(cx, self.centerx, self.centery, self.radius) 
  • trunk/pycha/scatter.py

    r140 r169  
    4444        # TODO: self.options.stroke.shadow 
    4545        for key in self._getDatasetsKeys(): 
    46             cx.set_source_rgb(*self.options.colorScheme[key]) 
     46            cx.set_source_rgb(*self.colorScheme[key]) 
    4747            preparePath(key) 
    4848            cx.stroke()