src/reportlab/graphics/charts/utils.py
author rgbecker
Thu, 27 May 2010 15:51:47 +0000
changeset 3385 e45ca0b2053c
parent 3326 ce725978d11c
child 3387 52dc490767e9
permissions -rw-r--r--
graphics: start on run time callback support
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 1683
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2004
1555
a0c3e76acdb6 Headers+versioning
rgbecker
parents: 1367
diff changeset
     2
#see license.txt for license details
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 1683
diff changeset
     3
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/charts/utils.py
3032
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 3019
diff changeset
     4
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 1683
diff changeset
     5
__version__=''' $Id$ '''
3032
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 3019
diff changeset
     6
__doc__="Utilities used here and there."
827
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
     7
from time import mktime, gmtime, strftime
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
     8
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
     9
### Dinu's stuff used in some line plots (likely to vansih).
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    10
827
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    11
def mkTimeTuple(timeString):
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    12
    "Convert a 'dd/mm/yyyy' formatted string to a tuple for use in the time module."
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    13
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    14
    list = [0] * 9
3385
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
    15
    dd, mm, yyyy = map(int, timeString.split('/'))
827
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    16
    list[:3] = [yyyy, mm, dd]
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
    17
827
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    18
    return tuple(list)
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    19
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    20
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    21
def str2seconds(timeString):
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    22
    "Convert a number of seconds since the epoch into a date string."
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    23
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    24
    return mktime(mkTimeTuple(timeString))
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    25
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    26
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    27
def seconds2str(seconds):
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    28
    "Convert a date string into the number of seconds since the epoch."
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    29
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    30
    return strftime('%Y-%m-%d', gmtime(seconds))
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    31
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    32
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    33
### Aaron's rounding function for making nice values on axes.
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    34
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    35
from math import log10
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    36
827
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    37
def nextRoundNumber(x):
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    38
    """Return the first 'nice round number' greater than or equal to x
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    39
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    40
    Used in selecting apropriate tick mark intervals; we say we want
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    41
    an interval which places ticks at least 10 points apart, work out
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    42
    what that is in chart space, and ask for the nextRoundNumber().
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    43
    Tries the series 1,2,5,10,20,50,100.., going up or down as needed.
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    44
    """
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
    45
827
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    46
    #guess to nearest order of magnitude
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    47
    if x in (0, 1):
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    48
        return x
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    49
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    50
    if x < 0:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    51
        return -1.0 * nextRoundNumber(-x)
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    52
    else:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    53
        lg = int(log10(x))
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    54
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    55
        if lg == 0:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    56
            if x < 1:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    57
                base = 0.1
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    58
            else:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    59
                base = 1.0
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    60
        elif lg < 0:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    61
            base = 10.0 ** (lg - 1)
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    62
        else:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    63
            base = 10.0 ** lg    # e.g. base(153) = 100
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    64
        # base will always be lower than x
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    65
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    66
        if base >= x:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    67
            return base * 1.0
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    68
        elif (base * 2) >= x:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    69
            return base * 2.0
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    70
        elif (base * 5) >= x:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    71
            return base * 5.0
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    72
        else:
be88a17f65ca Moved utility functions into new module utils.py.
dinu_gherman
parents:
diff changeset
    73
            return base * 10.0
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    74
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    75
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    76
### Robin's stuff from rgb_ticks.
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
    77
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    78
from math import log10, floor
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    79
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    80
_intervals=(.1, .2, .25, .5)
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    81
_j_max=len(_intervals)-1
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    82
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    83
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    84
def find_interval(lo,hi,I=5):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    85
    'determine tick parameters for range [lo, hi] using I intervals'
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
    86
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    87
    if lo >= hi:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    88
        if lo==hi:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    89
            if lo==0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    90
                lo = -.1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    91
                hi =  .1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    92
            else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    93
                lo = 0.9*lo
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    94
                hi = 1.1*hi
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    95
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    96
            raise ValueError, "lo>hi"
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    97
    x=(hi - lo)/float(I)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    98
    b= (x>0 and (x<1 or x>10)) and 10**floor(log10(x)) or 1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
    99
    b = b
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   100
    while 1:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   101
        a = x/b
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   102
        if a<=_intervals[-1]: break
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   103
        b = b*10
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   104
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   105
    j = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   106
    while a>_intervals[j]: j = j + 1
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   107
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   108
    while 1:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   109
        ss = _intervals[j]*b
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   110
        n = lo/ss
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   111
        l = int(n)-(n<0)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   112
        n = ss*l
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   113
        x = ss*(l+I)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   114
        a = I*ss
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   115
        if n>0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   116
            if a>=hi:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   117
                n = 0.0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   118
                x = a
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   119
        elif hi<0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   120
            a = -a
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   121
            if lo>a:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   122
                n = a
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   123
                x = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   124
        if hi<=x and n<=lo: break
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   125
        j = j + 1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   126
        if j>_j_max:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   127
            j = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   128
            b = b*10
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   129
    return n, x, ss, lo - n + x - hi
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   130
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   131
1331
dee677d0c6a7 Allow for forceable grid override
rgbecker
parents: 832
diff changeset
   132
def find_good_grid(lower,upper,n=(4,5,6,7,8,9), grid=None):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   133
    if grid:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   134
        t = divmod(lower,grid)[0] * grid
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   135
        hi, z = divmod(upper,grid)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   136
        if z>1e-8: hi = hi+1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   137
        hi = hi*grid
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   138
    else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   139
        try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   140
            n[0]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   141
        except TypeError:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   142
            n = xrange(max(1,n-2),max(n+3,2))
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   143
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   144
        w = 1e308
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   145
        for i in n:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   146
            z=find_interval(lower,upper,i)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   147
            if z[3]<w:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   148
                t, hi, grid = z[:3]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   149
                w=z[3]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   150
    return t, hi, grid
832
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   151
fe4f27b7d484 Added Robin's stuff from rgb_ticks.py.
dinu_gherman
parents: 827
diff changeset
   152
1331
dee677d0c6a7 Allow for forceable grid override
rgbecker
parents: 832
diff changeset
   153
def ticks(lower, upper, n=(4,5,6,7,8,9), split=1, percent=0, grid=None):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   154
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   155
    return tick positions and labels for range lower<=x<=upper
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   156
    n=number of intervals to try (can be a list or sequence)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   157
    split=1 return ticks then labels else (tick,label) pairs
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   158
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   159
    t, hi, grid = find_good_grid(lower, upper, n, grid)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   160
    power = floor(log10(grid))
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   161
    if power==0: power = 1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   162
    w = grid/10.**power
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   163
    w = int(w)!=w
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   164
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   165
    if power > 3 or power < -3:
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3032
diff changeset
   166
        format = '%+'+repr(w+7)+'.0e'
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   167
    else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   168
        if power >= 0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   169
            digits = int(power)+w
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3032
diff changeset
   170
            format = '%' + repr(digits)+'.0f'
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   171
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   172
            digits = w-int(power)
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3032
diff changeset
   173
            format = '%'+repr(digits+2)+'.'+repr(digits)+'f'
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   174
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   175
    if percent: format=format+'%%'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   176
    T = []
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   177
    n = int(float(hi-t)/grid+0.1)+1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   178
    if split:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   179
        labels = []
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   180
        for i in xrange(n):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   181
            v = t+grid*i
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   182
            T.append(v)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   183
            labels.append(format % v)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   184
        return T, labels
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   185
    else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   186
        for i in xrange(n):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   187
            v = t+grid*i
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1557
diff changeset
   188
            T.append((v, format % v))
2846
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   189
        return T
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   190
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   191
def findNones(data):
3019
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   192
    m = len(data)
2846
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   193
    if None in data:
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   194
        b = 0
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   195
        while b<m and data[b] is None:
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   196
            b += 1
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   197
        if b==m: return data
3019
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   198
        l = m-1
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   199
        while data[l] is None:
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   200
            l -= 1
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   201
        l+=1
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   202
        if b or l: data = data[b:l]
2846
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   203
        I = [i for i in xrange(len(data)) if data[i] is None]
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   204
        for i in I:
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   205
            data[i] = 0.5*(data[i-1]+data[i+1])
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   206
        return b, l, data
3019
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   207
    return 0,m,data
2846
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   208
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   209
def pairFixNones(pairs):
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   210
    Y = [x[1] for x in pairs]
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   211
    b,l,nY = findNones(Y)
3019
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   212
    m = len(Y)
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   213
    if b or l<m or nY!=Y:
e303fc5232dd utild.py: fix broken moving average func
rgbecker
parents: 2964
diff changeset
   214
        if b or l<m: pairs = pairs[b:l]
2847
437c2e2335f2 graphics: fix utils and factorize some axis behaviour
rgbecker
parents: 2846
diff changeset
   215
        pairs = [(x[0],y) for x,y in zip(pairs,nY)]
2846
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   216
    return pairs
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   217
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   218
def maverage(data,n=6):
2847
437c2e2335f2 graphics: fix utils and factorize some axis behaviour
rgbecker
parents: 2846
diff changeset
   219
    data = (n-1)*[data[0]]+data
2846
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   220
    data = [float(sum(data[i-n:i]))/n for i in xrange(n,len(data)+1)]
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   221
    return data
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   222
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   223
def pairMaverage(data,n=6):
d2ce0e707ba9 charts: added axes skipEndL and some utilities
rgbecker
parents: 2332
diff changeset
   224
    return [(x[0],s) for x,s in zip(data, maverage([x[1] for x in data],n))]
3385
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   225
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   226
import weakref
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   227
from reportlab.graphics.shapes import transformPoint, inverse
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   228
class DrawTimeCollector:
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   229
    '''
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   230
    generic mechanism for collecting information about nodes at the time they are about to be drawn
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   231
    '''
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   232
    def __init__(self):
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   233
        self._nodes = weakref.WeakKeyDictionary()
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   234
        self.clear()
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   235
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   236
    def clear(self):
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   237
        self._info = []
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   238
        self._info_append = self._info.append
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   239
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   240
    def record(self,func,node,*args,**kwds):
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   241
        self._nodes[node] = (func,args,kwds)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   242
        node.__dict__['_drawTimeCallback'] = self
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   243
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   244
    def __call__(self,node,canvas,renderer):
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   245
        func = self._nodes.get(node,None)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   246
        if func:
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   247
            func, args, kwds = func
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   248
            i = func(node,canvas,renderer, *args, **kwds)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   249
            if i is not None: self._info_append(i)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   250
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   251
    @staticmethod
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   252
    def rectDrawTimeCallback(node,canvas,renderer,**kwds):
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   253
        A = getattr(canvas,'ctm',None)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   254
        if not A: return
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   255
        x1 = node.x
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   256
        y1 = node.y
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   257
        x2 = x1 + node.width
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   258
        y2 = y1 + node.height
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   259
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   260
        iA = inverse(A)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   261
        x1,y1 = transformPoint(iA,(x1,y1))
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   262
        x2,y2 = transformPoint(iA,(x2,y2))
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   263
        D = kwds.copy()
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   264
        D['rect']=(x1,y1,x2,y2)
e45ca0b2053c graphics: start on run time callback support
rgbecker
parents: 3326
diff changeset
   265
        return D