Browse Source

Added the build script.

Fixed handling of a specified date interval for the x-axis in TimeSeries.  It turns out, the problem was the child get_x_values was not being called because I was calling the parent get_data_values( 'x' ) explicitly in Plot.py.
Generalized the data_max and data_min operations.
Fixed get_time_range method to properly return both end points.
pull/8/head
SANDIA\jaraco 19 years ago
parent
commit
f086985683
  1. 34
      Plot.py
  2. 8
      TimeSeries.py
  3. 2
      __init__.py
  4. 23
      build.py
  5. 14
      testing.py
  6. 15
      testing.rb

34
Plot.py

@ -158,24 +158,33 @@ class Plot( SVG.Graph ):
super( Plot, self ).calculate_right_margin() super( Plot, self ).calculate_right_margin()
label_right = len( str( self.get_x_labels()[-1] ) ) / 2 * self.font_size * 0.6 label_right = len( str( self.get_x_labels()[-1] ) ) / 2 * self.font_size * 0.6
self.border_right = max( label_right, self.border_right ) self.border_right = max( label_right, self.border_right )
x_data_index = 0 def data_max( self, axis ):
y_data_index = 1
def data_range( self, axis ):
side = { 'x': 'right', 'y': 'top' }[axis]
data_index = getattr( self, '%s_data_index' % axis ) data_index = getattr( self, '%s_data_index' % axis )
max_value = max( map( lambda set: max( set['data'][data_index] ), self.data ) ) max_value = max( chain( *map( lambda set: set['data'][data_index], self.data ) ) )
# above is same as
#max_value = max( map( lambda set: max( set['data'][data_index] ), self.data ) )
spec_max = getattr( self, 'max_%s_value' % axis ) spec_max = getattr( self, 'max_%s_value' % axis )
if spec_max is not None: max_value = max( max_value, spec_max )
max_value = max( max_value, spec_max ) return max_value
min_value = min( map( lambda set: min( set['data'][data_index] ), self.data ) )
def data_min( self, axis ):
data_index = getattr( self, '%s_data_index' % axis )
min_value = min( chain( *map( lambda set: set['data'][data_index], self.data ) ) )
spec_min = getattr( self, 'min_%s_value' % axis ) spec_min = getattr( self, 'min_%s_value' % axis )
if spec_min is not None: if spec_min is not None:
min_value = min( min_value, spec_min ) min_value = min( min_value, spec_min )
return min_value
x_data_index = 0
y_data_index = 1
def data_range( self, axis ):
side = { 'x': 'right', 'y': 'top' }[axis]
min_value = self.data_min( axis )
max_value = self.data_max( axis )
range = max_value - min_value range = max_value - min_value
#side_pad = '%s_pad' % side
side_pad = range / 20.0 or 10 side_pad = range / 20.0 or 10
scale_range = ( max_value + side_pad ) - min_value scale_range = ( max_value + side_pad ) - min_value
@ -204,9 +213,8 @@ class Plot( SVG.Graph ):
def field_size( self, axis ): def field_size( self, axis ):
size = { 'x': 'width', 'y': 'height' }[axis] size = { 'x': 'width', 'y': 'height' }[axis]
side = { 'x': 'right', 'y': 'top' }[axis] side = { 'x': 'right', 'y': 'top' }[axis]
values = self.get_data_values( axis ) values = getattr( self, 'get_%s_values' % axis )()
data_index = getattr( self, '%s_data_index' % axis ) max_d = self.data_max( axis )
max_d = max( chain( *map( lambda set: set['data'][data_index], self.data ) ) )
dx = float( max_d - values[-1] ) / ( values[-1] - values[-2] ) dx = float( max_d - values[-1] ) / ( values[-1] - values[-2] )
graph_size = getattr( self, 'graph_%s' % size ) graph_size = getattr( self, 'graph_%s' % size )
side_font = getattr( self, '%s_font' % side ) side_font = getattr( self, '%s_font' % side )

8
TimeSeries.py

@ -152,11 +152,11 @@ class Plot( SVG.Plot.Plot ):
def get_x_labels( self ): def get_x_labels( self ):
return map( lambda t: fromtimestamp( t ).strftime( self.x_label_format ), self.get_x_values() ) return map( lambda t: fromtimestamp( t ).strftime( self.x_label_format ), self.get_x_values() )
def get_x_values( self ): def get_x_values( self ):
result = self.get_x_timescale_division_values() result = self.get_x_timescale_division_values()
if result: return result if result: return result
return SVG.Plot.float_range( *self.x_range() ) return tuple( SVG.Plot.float_range( *self.x_range() ) )
def get_x_timescale_division_values( self ): def get_x_timescale_division_values( self ):
if not self.timescale_divisions: return if not self.timescale_divisions: return
@ -167,13 +167,13 @@ class Plot( SVG.Plot.Plot ):
amount = int( m.groupdict()['amount'] ) amount = int( m.groupdict()['amount'] )
if not amount: return if not amount: return
delta = relativedelta( **{ division_units: amount } ) delta = relativedelta( **{ division_units: amount } )
result = self.get_time_range( min, max, delta ) result = tuple( self.get_time_range( min, max, delta ) )
return result return result
def get_time_range( self, start, stop, delta ): def get_time_range( self, start, stop, delta ):
start, stop = map( fromtimestamp, (start, stop ) ) start, stop = map( fromtimestamp, (start, stop ) )
current = start current = start
while current < stop: while current <= stop:
yield mktime( current.timetuple() ) yield mktime( current.timetuple() )
current += delta current += delta

2
__init__.py

@ -195,7 +195,7 @@ Copyright 2005 Sandia National Laboratories
max_y_label_height_px = self.y_label_font_size max_y_label_height_px = self.y_label_font_size
else: else:
label_lengths = map( len, self.get_y_labels() ) label_lengths = map( len, self.get_y_labels() )
max_y_label_len = reduce( max, label_lengths ) max_y_label_len = max( label_lengths )
max_y_label_height_px = 0.6 * max_y_label_len * self.y_label_font_size max_y_label_height_px = 0.6 * max_y_label_len * self.y_label_font_size
if self.show_y_labels: bl += max_y_label_height_px if self.show_y_labels: bl += max_y_label_height_px
if self.stagger_y_labels: bl += max_y_label_height_px + 10 if self.stagger_y_labels: bl += max_y_label_height_px + 10

23
build.py

@ -0,0 +1,23 @@
# -*- coding: UTF-8 -*-
""" Setup script for building SVG distribution
Copyright © 2005 Jason R. Coombs
"""
from distutils.core import setup
__author__ = 'Jason R. Coombs <jaraco@sandia.gov>'
__version__ = '$Rev: $'[6:-2]
__svnauthor__ = '$Author: $'[9:-2]
__date__ = '$Date: $'[7:-2]
setup ( name = 'SVGChart',
version = '1.0',
description = 'Python SVG Charting Support',
author = 'Jason R. Coombs',
author_email = 'jaraco@sandia.gov',
packages = ['SVG'],
package_dir = { 'SVG':'.' },
script_args = ( 'bdist_wininst', )
)

14
testing.py

@ -1,5 +1,5 @@
import sys, os import sys, os
sys.path.insert( 0, 'c:\documents and settings\jaraco\my documents\projects\jaraco' ) #sys.path.insert( 0, 'c:\documents and settings\jaraco\my documents\projects\jaraco' )
import SVG import SVG
from SVG import Plot from SVG import Plot
reload( SVG ) reload( SVG )
@ -24,11 +24,21 @@ from SVG import TimeSeries
reload( TimeSeries ) reload( TimeSeries )
g = TimeSeries.Plot( { } ) g = TimeSeries.Plot( { } )
#g.timescale_divisions = '4 hours'
g.timescale_divisions = '4 hours'
g.stagger_x_labels = True g.stagger_x_labels = True
g.x_label_format = '%d-%b'
#g.max_y_value = 200
g.add_data( { 'data': [ '2005-12-21T00:00:00', 20, '2005-12-22T00:00:00', 21 ], 'title': 'foo' } ) g.add_data( { 'data': [ '2005-12-21T00:00:00', 20, '2005-12-22T00:00:00', 21 ], 'title': 'foo' } )
res = g.burn() res = g.burn()
print g.field_width
print g.font_size
print g.right_font
print g.right_align
print g.get_x_labels()
f = open( r'c:\timeseries.py.svg', 'w' ) f = open( r'c:\timeseries.py.svg', 'w' )
f.write( res ) f.write( res )
f.close() f.close()

15
testing.rb

@ -23,10 +23,23 @@ f.close()
require 'SVG/Graph/TimeSeries' require 'SVG/Graph/TimeSeries'
g = SVG::Graph::TimeSeries.new( { } ) g = SVG::Graph::TimeSeries.new( {
:timescale_divisions => '4 hours',
:stagger_x_labels => true,
:x_label_format => '%d-%b',
} )
g.add_data( { :data=> [ '2005-12-21T00:00:00', 20, '2005-12-22T00:00:00', 21 ], :title=> 'foo' } ) g.add_data( { :data=> [ '2005-12-21T00:00:00', 20, '2005-12-22T00:00:00', 21 ], :title=> 'foo' } )
res = g.burn() res = g.burn()
print g.field_width
print "\n"
print g.inspect
print g.get_x_labels.length
print "\n"
print g.right_align
print "\n"
print g.get_x_labels
print "\n"
f = File.new( 'c:\timeseries.rb.svg', 'w' ) f = File.new( 'c:\timeseries.rb.svg', 'w' )
f.write( res ) f.write( res )
f.close() f.close()
Loading…
Cancel
Save