Changeset 109
- Timestamp:
- 10/27/08 16:49:58 (4 years ago)
- Location:
- trunk
- Files:
-
- 11 modified
-
chavier/app.py (modified) (3 diffs)
-
chavier/dialogs.py (modified) (1 diff)
-
chavier/gui.py (modified) (8 diffs)
-
src/bar.py (modified) (10 diffs)
-
src/chart.py (modified) (11 diffs)
-
src/line.py (modified) (3 diffs)
-
src/pie.py (modified) (3 diffs)
-
src/scatter.py (modified) (3 diffs)
-
tests/bar.py (modified) (5 diffs)
-
tests/chart.py (modified) (4 diffs)
-
tests/line.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/chavier/app.py
r108 r109 65 65 tickCount=int, 66 66 tickPrecision=int, 67 interval=int, 67 68 range=list, 68 69 rotate=float, … … 103 104 shouldFill=bool, 104 105 barWidthFillFraction=float, 105 xOriginIsZero=bool,106 yOriginIsZero=bool,107 106 pieRadius=float, 108 107 colorScheme=str, … … 127 126 chart.addDataset(datasets) 128 127 chart.render() 129 return surface128 return chart 130 129 131 130 if __name__ == '__main__': -
trunk/chavier/dialogs.py
r108 r109 133 133 0, 1, 5, 1, 1000, 10) 134 134 self.min = self._create_spin_button('Minimum y value', 135 2, 0.5, 1, 0, 1000, 0)135 2, 0.5, 1, -1000, 1000, 0) 136 136 self.max = self._create_spin_button('Maximum y value', 137 137 2, 0.5, 1, 0, 1000, 10) -
trunk/chavier/gui.py
r108 r109 22 22 from chavier.dialogs import ( 23 23 TextInputDialog, PointDialog, OptionDialog, RandomGeneratorDialog, 24 AboutDialog, 24 AboutDialog, warning 25 25 ) 26 26 … … 29 29 self.app = app 30 30 31 self.chart = None 31 32 self.surface = None 32 33 … … 123 124 '<ctrl>g', 'Generate random points', 124 125 self.generate_random_points), 126 ('dump-chart-state', gtk.STOCK_CONVERT, '_Dump chart state', 127 '<ctrl>d', 'Dump internal chart variables', 128 self.dump_chart_state), 125 129 ('help', None, '_Help', None, 'Help', None), 126 130 ('about', gtk.STOCK_ABOUT, None, None, 'About this program', … … 168 172 <menu action="tools"> 169 173 <menuitem action="random-points"/> 174 <menuitem action="dump-chart-state"/> 170 175 </menu> 171 176 <menu action="help"> … … 357 362 358 363 def drawing_area_expose_event(self, widget, event, data=None): 359 if self. surfaceis None:364 if self.chart is None: 360 365 return 361 366 … … 364 369 event.area.width, event.area.height) 365 370 cr.clip() 366 cr.set_source_surface(self. surface, 0, 0)371 cr.set_source_surface(self.chart.surface, 0, 0) 367 372 cr.paint() 368 373 369 374 def drawing_area_size_allocate_event(self, widget, event, data=None): 370 if self. surfaceis not None:375 if self.chart is not None: 371 376 self.refresh() 372 377 373 378 def on_chart_type_change(self, action, current, data=None): 374 if self. surfaceis not None:379 if self.chart is not None: 375 380 self.refresh() 376 381 … … 478 483 chart_type = self._get_chart_type() 479 484 alloc = self.drawing_area.get_allocation() 480 self. surface= self.app.get_chart(datasets, options, chart_type,481 alloc.width, alloc.height)485 self.chart = self.app.get_chart(datasets, options, chart_type, 486 alloc.width, alloc.height) 482 487 self.drawing_area.queue_draw() 483 488 else: 484 self. surface= None489 self.chart = None 485 490 486 491 def generate_random_points(self, action=None): … … 500 505 dialog.destroy() 501 506 507 def dump_chart_state(self, action=None): 508 if self.chart is None: 509 return 510 511 alloc = self.drawing_area.get_allocation() 512 513 print 'CHART STATE' 514 print '-' * 70 515 print 'surface: %d x %d' % (alloc.width, alloc.height) 516 print 'area :', self.chart.area 517 print 518 print 'minxval:', self.chart.minxval 519 print 'maxxval:', self.chart.maxxval 520 print 'xrange :', self.chart.xrange 521 print 522 print 'minyval:', self.chart.minyval 523 print 'maxyval:', self.chart.maxyval 524 print 'yrange :', self.chart.yrange 525 502 526 def about(self, action=None): 503 527 dialog = AboutDialog(self.main_window) -
trunk/src/bar.py
r97 r109 17 17 18 18 from pycha.chart import Chart, uniqueIndices 19 from pycha.color import hex2rgb , clamp19 from pycha.color import hex2rgb 20 20 21 21 class BarChart(Chart): … … 28 28 self.barMargin = 0.0 29 29 30 def _updateXY(self): 31 super(BarChart, self)._updateXY() 32 # each dataset is centered around a line segment. that's why we 33 # need n + 1 divisions on the x axis 34 self.xscale = 1 / (self.xrange + 1.0) 35 30 36 def _updateChart(self): 31 37 """Evaluates measures for vertical bars""" … … 36 42 if len(uniqx) == 1: 37 43 xdelta = 1.0 38 self.xscale = 1.039 self.minxval = uniqx[0]40 44 barWidth = 1.0 * self.options.barWidthFillFraction 41 45 self.barWidthForSet = barWidth / len(stores) … … 44 48 xdelta = min([abs(uniqx[j] - uniqx[j-1]) 45 49 for j in range(1, len(uniqx))]) 46 self.xscale = 1.0 / (self.xrange + 1)47 50 barWidth = xdelta * self.xscale * self.options.barWidthFillFraction 48 51 self.barWidthForSet = barWidth / len(stores) … … 57 60 58 61 def drawBar(bar): 59 cx.set_line_width(self.options.stroke.width) 62 stroke_width = self.options.stroke.width 63 ux, uy = cx.device_to_user_distance(stroke_width, stroke_width) 64 if ux < uy: 65 ux = uy 66 cx.set_line_width(ux) 60 67 61 68 # gather bar proportions … … 74 81 cx.fill() 75 82 76 if self.options.shouldFill :83 if self.options.shouldFill or (not self.options.stroke.hide): 77 84 cx.rectangle(x, y, w, h) 78 cx.set_source_rgb(*self.options.colorScheme[bar.name])79 cx.fill_preserve()80 85 81 if not self.options.stroke.hide: 82 cx.set_source_rgb(*hex2rgb(self.options.stroke.color)) 83 cx.stroke() 86 if self.options.shouldFill: 87 cx.set_source_rgb(*self.options.colorScheme[bar.name]) 88 cx.fill_preserve() 89 90 if not self.options.stroke.hide: 91 cx.set_source_rgb(*hex2rgb(self.options.stroke.color)) 92 cx.stroke() 84 93 85 94 cx.save() … … 93 102 """Evaluates measures for vertical bars""" 94 103 super(VerticalBarChart, self)._updateChart() 95 96 104 for i, (name, store) in enumerate(self.datasets): 97 105 for item in store: 98 106 xval, yval = item 99 107 x = (((xval - self.minxval) * self.xscale) 100 + (i * self.barWidthForSet) + self.barMargin)108 + self.barMargin + (i * self.barWidthForSet)) 101 109 w = self.barWidthForSet 102 h = (yval - self.minyval) * self.yscale 103 y = 1.0 - h 110 h = abs(yval) * self.yscale 111 if yval > 0: 112 y = (1.0 - h) - self.area.origin 113 else: 114 y = 1 - self.area.origin 104 115 rect = Rect(x, y, w, h, xval, yval, name) 105 116 … … 127 138 xval, yval = item 128 139 y = (((xval - self.minxval) * self.xscale) 129 + (i * self.barWidthForSet) + self.barMargin) 130 x = 0.0 140 + self.barMargin + (i * self.barWidthForSet)) 131 141 h = self.barWidthForSet 132 w = (yval - self.minyval) * self.yscale 142 w = abs(yval) * self.yscale 143 if yval > 0: 144 x = self.area.origin 145 else: 146 x = self.area.origin - w 133 147 rect = Rect(x, y, w, h, xval, yval, name) 134 148 … … 153 167 return (x, y-2, w+2, h+4) 154 168 169 def _renderXAxis(self, cx): 170 """Draws the horizontal line representing the X axis""" 171 cx.new_path() 172 cx.move_to(self.area.x, self.area.y + self.area.h) 173 cx.line_to(self.area.x + self.area.w, self.area.y + self.area.h) 174 cx.close_path() 175 cx.stroke() 176 177 def _renderYAxis(self, cx): 178 # draws the vertical line representing the Y axis 179 cx.new_path() 180 cx.move_to(self.area.x + self.area.origin * self.area.w, 181 self.area.y) 182 cx.line_to(self.area.x + self.area.origin * self.area.w, 183 self.area.y + self.area.h) 184 cx.close_path() 185 cx.stroke() 155 186 156 187 class Rect(object): … … 161 192 162 193 def __str__(self): 163 return "<pycha.bar.Rect@(%.2f, %.2f) %.2fx%.2f>" % (self.x, self.y, 164 self.w, self.h) 194 return ("<pycha.bar.Rect@(%.2f, %.2f) %.2fx%.2f (%.2f, %.2f) %s>" 195 % (self.x, self.y, self.w, self.h, self.xval, self.yval, 196 self.name)) -
trunk/src/chart.py
r106 r109 139 139 def _updateXY(self): 140 140 """Calculates all kinds of metrics for the x and y axis""" 141 stores = self._getDatasetsValues() 141 x_range_is_defined = self.options.axis.x.range is not None 142 y_range_is_defined = self.options.axis.y.range is not None 143 144 if not x_range_is_defined or not y_range_is_defined: 145 stores = self._getDatasetsValues() 146 147 # gather data for the x axis 148 if x_range_is_defined: 149 self.minxval, self.maxxval = self.options.axis.x.range 150 else: 151 xdata = [pair[0] for pair in reduce(lambda a,b: a+b, stores)] 152 self.minxval = float(min(xdata)) 153 self.maxxval = float(max(xdata)) 154 if self.minxval * self.maxxval > 0 and self.minxval > 0: 155 self.minxval = 0.0 156 157 self.xrange = self.maxxval - self.minxval 158 if self.xrange == 0: 159 self.xscale = 1.0 160 else: 161 self.xscale = 1 / self.xrange 162 163 # gather data for the y axis 164 if y_range_is_defined: 165 self.minyval, self.maxyval = self.options.axis.y.range 166 else: 167 ydata = [pair[1] for pair in reduce(lambda a,b: a+b, stores)] 168 self.minyval = float(min(ydata)) 169 self.maxyval = float(max(ydata)) 170 if self.minyval * self.maxyval > 0 and self.minyval > 0: 171 self.minyval = 0.0 172 173 self.yrange = self.maxyval - self.minyval 174 if self.yrange == 0: 175 self.yscale = 1.0 176 else: 177 self.yscale = 1 / self.yrange 142 178 143 179 # calculate area data … … 146 182 height = (self.surface.get_height() 147 183 - self.options.padding.top - self.options.padding.bottom) 184 185 if self.minyval * self.maxyval < 0: # different signs 186 origin = abs(self.minyval) * self.yscale 187 else: 188 origin = 0 189 148 190 self.area = Area(self.options.padding.left, 149 191 self.options.padding.top, 150 width, height) 151 152 # gather data for the x axis 153 if self.options.axis.x.range: 154 self.minxval, self.maxxval = self.options.axis.x.range 155 self.xscale = self.maxxval - self.minxval 156 else: 157 xdata = [pair[0] for pair in reduce(lambda a,b: a+b, stores)] 158 if self.options.xOriginIsZero: 159 self.minxval = 0.0 160 else: 161 self.minxval = float(min(xdata)) 162 self.maxxval = float(max(xdata)) 163 164 self.xrange = self.maxxval - self.minxval 165 if self.xrange == 0: 166 self.xscale = 1.0 167 else: 168 self.xscale = 1 / self.xrange 169 170 # gather data for the y axis 171 if self.options.axis.y.range: 172 self.minyval, self.maxyval = self.options.axis.y.range 173 self.yscale = self.maxyval - self.minyval 174 else: 175 ydata = [pair[1] for pair in reduce(lambda a,b: a+b, stores)] 176 if self.options.yOriginIsZero: 177 self.minyval = 0.0 178 else: 179 self.minyval = float(min(ydata)) 180 self.maxyval = float(max(ydata)) 181 182 self.yrange = self.maxyval - self.minyval 183 if self.yrange == 0: 184 self.yscale = 1.0 185 else: 186 self.yscale = 1 / self.yrange 192 width, height, origin) 187 193 188 194 def _updateChart(self): … … 215 221 uniqx = range(len(uniqueIndices(stores)) + 1) 216 222 roughSeparation = self.xrange / self.options.axis.x.tickCount 217 218 223 i = j = 0 219 while i + 1< len(uniqx) and j < self.options.axis.x.tickCount:220 if (uniqx[i + 1] - self.minxval) >= (j * roughSeparation):224 while i < len(uniqx) and j < self.options.axis.x.tickCount: 225 if (uniqx[i] - self.minxval) >= (j * roughSeparation): 221 226 pos = self.xscale * (uniqx[i] - self.minxval) 222 227 if 0.0 <= pos <= 1.0: 223 self.xticks.append((pos, uniqx[i + 1]))228 self.xticks.append((pos, uniqx[i])) 224 229 j += 1 225 230 i += 1 … … 239 244 self.yticks.append((pos, label)) 240 245 246 elif self.options.axis.y.interval > 0: 247 interval = self.options.axis.y.interval 248 label = (divmod(self.minyval, interval)[0] + 1) * interval 249 pos = 1.0 - (self.yscale * (label - self.minyval)) 250 while 0.0 <= pos <= 1.0: 251 self.yticks.append((pos, label)) 252 label += interval 253 pos = 1.0 - (self.yscale * (label - self.minyval)) 254 241 255 elif self.options.axis.y.tickCount > 0: 242 256 prec = self.options.axis.y.tickPrecision … … 263 277 if self.options.background.baseColor: 264 278 cx.set_source_rgb(*hex2rgb(self.options.background.baseColor)) 265 x, y, w, h = 0, 0, self.area.w, self.area.h 266 w += self.options.padding.left + self.options.padding.right 267 h += self.options.padding.top + self.options.padding.bottom 268 cx.rectangle(x, y, w, h) 269 cx.fill() 279 cx.paint() 270 280 271 281 if self.options.background.chartColor: … … 424 434 """Draws the horizontal line representing the X axis""" 425 435 cx.new_path() 426 cx.move_to(self.area.x, self.area.y + self.area.h) 427 cx.line_to(self.area.x + self.area.w, self.area.y + self.area.h) 436 cx.move_to(self.area.x, 437 self.area.y + self.area.h * (1.0 - self.area.origin)) 438 cx.line_to(self.area.x + self.area.w, 439 self.area.y + self.area.h * (1.0 - self.area.origin)) 428 440 cx.close_path() 429 441 cx.stroke() … … 567 579 class Area(object): 568 580 """Simple rectangle to hold an area coordinates and dimensions""" 569 def __init__(self, x, y, w, h ):581 def __init__(self, x, y, w, h, origin=0.0): 570 582 self.x, self.y, self.w, self.h = x, y, w, h 583 self.origin = origin 571 584 572 585 def __str__(self): 573 return "<pycha.chart.Area@(%.2f, %.2f) %.2fx%.2f" % (self.x, self.y,574 self.w, self.h)586 msg = "<pycha.chart.Area@(%.2f, %.2f) %.2f x %.2f Origin: %.2f>" 587 return msg % (self.x, self.y, self.w, self.h, self.origin) 575 588 576 589 class Option(dict): … … 594 607 axis=Option( 595 608 lineWidth=1.0, 596 lineColor='#0 00000',609 lineColor='#0f0000', 597 610 tickSize=3.0, 598 611 labelColor='#666666', … … 614 627 tickCount=10, 615 628 tickPrecision=1, 629 interval=0, 616 630 range=None, 617 631 rotate=None, … … 635 649 left=30, 636 650 right=30, 637 top= 15,638 bottom= 15,651 top=30, 652 bottom=30, 639 653 ), 640 654 stroke=Option( … … 647 661 shouldFill=True, 648 662 barWidthFillFraction=0.75, 649 xOriginIsZero=True,650 yOriginIsZero=True,651 663 pieRadius=0.4, 652 664 colorScheme=DEFAULT_COLOR, -
trunk/src/line.py
r97 r109 17 17 18 18 from pycha.chart import Chart 19 from pycha.color import hex2rgb , clamp19 from pycha.color import hex2rgb 20 20 21 21 class LineChart(Chart): … … 47 47 if self.options.shouldFill: 48 48 # Go to the (0,0) coordinate to start drawing the area 49 cx.move_to(self.area.x, self.area.y + self.area.h) 49 #cx.move_to(self.area.x, self.area.y + self.area.h) 50 cx.move_to(self.area.x, 51 self.area.y + (1.0 - self.area.origin) * self.area.h) 50 52 51 53 for point in self.points: … … 65 67 if self.options.shouldFill: 66 68 # Close the path to the start point 67 cx.line_to(lastX * self.area.w + self.area.x,68 self.area.h + self.area.y)69 cx.line_to(self.area.x, self.area.y + self.area.h)69 y = (1.0 - self.area.origin) * self.area.h + self.area.y 70 cx.line_to(lastX * self.area.w + self.area.x, y) 71 cx.line_to(self.area.x, y) 70 72 cx.close_path() 71 73 else: -
trunk/src/pie.py
r102 r109 60 60 self.xticks = [] 61 61 if self.options.axis.x.ticks: 62 lookup = dict([(slice.xval, slice) for slice in self.slices]) 62 # lookup = dict([(slice.xval, slice) for slice in self.slices]) 63 lookup = dict([(slice.name, slice) for slice in self.slices]) 63 64 for tick in self.options.axis.x.ticks: 64 65 if not isinstance(tick, Option): … … 71 72 else: 72 73 for slice in self.slices: 73 label = '%s (%.1f%%)' % (slice.xval, slice.fraction * 100) 74 self.xticks.append((slice.xval, label)) 74 # label = '%s (%.1f%%)' % (slice.xval, slice.fraction * 100) 75 # self.xticks.append((slice.xval, label)) 76 label = '%s (%.1f%%)' % (slice.name, slice.fraction * 100) 77 self.xticks.append((slice.name, label)) 75 78 76 79 def _renderBackground(self, cx): … … 130 133 131 134 self.xlabels = [] 132 lookup = dict([(slice.xval, slice) for slice in self.slices]) 135 # lookup = dict([(slice.xval, slice) for slice in self.slices]) 136 lookup = dict([(slice.name, slice) for slice in self.slices]) 133 137 134 138 cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor)) -
trunk/src/scatter.py
r96 r109 16 16 # along with PyCha. If not, see <http://www.gnu.org/licenses/>. 17 17 18 from pycha.chart import Chart 19 from pycha.color import hex2rgb, clamp 20 from pycha.line import Point, LineChart 18 from pycha.line import LineChart 21 19 22 20 class ScatterplotChart(LineChart): … … 24 22 def _renderChart(self, cx): 25 23 """Renders a scatterplot""" 26 def drawSymbol(point, size=2):27 ox = point.x * self.area.w + self.area.x28 oy = point.y * self.area.h + self.area.y29 cx.move_to(ox-size, oy )30 cx.line_to(ox+size, oy )31 cx.move_to(ox , oy-size)32 cx.line_to(ox , oy+size)24 def drawSymbol(point, size=2): 25 ox = point.x * self.area.w + self.area.x 26 oy = point.y * self.area.h + self.area.y 27 cx.move_to(ox-size, oy ) 28 cx.line_to(ox+size, oy ) 29 cx.move_to(ox , oy-size) 30 cx.line_to(ox , oy+size) 33 31 34 32 def preparePath(storeName, size=2): … … 42 40 43 41 cx.set_line_width(self.options.stroke.width) 44 # TODO: self.options.stroke.shadow45 for key in self._getDatasetsKeys():46 cx.set_source_rgb(*self.options.colorScheme[key])47 preparePath(key)48 cx.stroke()42 # TODO: self.options.stroke.shadow 43 for key in self._getDatasetsKeys(): 44 cx.set_source_rgb(*self.options.colorScheme[key]) 45 preparePath(key) 46 cx.stroke() 49 47 50 48 cx.restore() 51 49 52 50 def _renderLines(self, cx): 53 """We don't need lines in the background""" 54 pass51 # We don't need lines in the background 52 pass -
trunk/tests/bar.py
r85 r109 62 62 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 63 63 dataset = ( 64 ('dataset1', ([0, 3], [1, 4], [2, 2], [3, 5], [4,3.5])),65 ('dataset2', ([0, 2], [1, 3], [2, 1], [3, 5], [4,2.5])),64 ('dataset1', ([0, 3], [1, 4], [2, 2], [3, 5], [4, 3.5])), 65 ('dataset2', ([0, 2], [1, 3], [2, 1], [3, 5], [4, 2.5])), 66 66 ) 67 67 ch = pycha.bar.VerticalBarChart(surface) … … 69 69 ch._updateXY() 70 70 ch._updateChart() 71 self.assertEqual(ch.minxval, 0) 72 self.assertEqual(ch.maxxval, 4) 71 73 self.assertEqual(ch.xrange, 4) 72 self.assertAlmostEqual(ch.xscale, 0.2, 4) 73 self.assertAlmostEqual(ch.yscale, 0.2, 4) 74 self.assertAlmostEqual(ch.xscale, 0.20, 4) 75 self.assertEqual(ch.minyval, 0) 76 self.assertEqual(ch.maxyval, 5) 77 self.assertEqual(ch.yrange, 5) 78 self.assertAlmostEqual(ch.yscale, 0.20, 4) 74 79 self.assertEqual(ch.minxdelta, 1) 75 80 self.assertAlmostEqual(ch.barWidthForSet, 0.075, 4) 76 81 self.assertAlmostEqual(ch.barMargin, 0.025, 4) 77 82 83 R = pycha.bar.Rect 78 84 bars = ( 79 pycha.bar.Rect(0.025, 0.4, 0.075, 0.6, 0, 3, 'dataset1'),80 pycha.bar.Rect(0.225, 0.2, 0.075, 0.8, 1, 4, 'dataset1'),81 pycha.bar.Rect(0.425, 0.6, 0.075, 0.4, 2, 2, 'dataset1'),82 pycha.bar.Rect(0.625, 0.0, 0.075, 1.0, 3, 5, 'dataset1'),83 pycha.bar.Rect(0.825, 0.3, 0.075, 0.7, 4, 3.5, 'dataset1'),84 85 pycha.bar.Rect(0.100, 0.6, 0.075, 0.4, 0, 2, 'dataset2'),86 pycha.bar.Rect(0.300, 0.4, 0.075, 0.6, 1, 3, 'dataset2'),87 pycha.bar.Rect(0.500, 0.8, 0.075, 0.2, 2, 1, 'dataset2'),88 pycha.bar.Rect(0.700, 0.0, 0.075, 1.0, 3, 5, 'dataset2'),89 pycha.bar.Rect(0.900, 0.5, 0.075, 0.5, 4, 2.5, 'dataset2'),85 R(0.025, 0.400, 0.075, 0.600, 0, 3, 'dataset1'), 86 R(0.225, 0.200, 0.075, 0.800, 1, 4, 'dataset1'), 87 R(0.425, 0.600, 0.075, 0.400, 2, 2, 'dataset1'), 88 R(0.625, 0.000, 0.075, 1.000, 3, 5, 'dataset1'), 89 R(0.825, 0.300, 0.075, 0.700, 4, 3.5, 'dataset1'), 90 91 R(0.100, 0.600, 0.075, 0.400, 0, 2, 'dataset2'), 92 R(0.300, 0.400, 0.075, 0.600, 1, 3, 'dataset2'), 93 R(0.500, 0.800, 0.075, 0.200, 2, 1, 'dataset2'), 94 R(0.700, 0.000, 0.075, 1.000, 3, 5, 'dataset2'), 95 R(0.900, 0.500, 0.075, 0.500, 4, 2.5, 'dataset2'), 90 96 ) 91 97 … … 100 106 self.assertEqual(b1.name, b2.name) 101 107 102 def test_updateTicks(self): 103 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 104 dataset = ( 105 ('dataset1', ([0, 1], [1, 1], [2, 3])), 106 ('dataset2', ([0, 2], [1, 0], [3, 4])), 108 def test_updateChartWithNegatives(self): 109 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 110 dataset = ( 111 ('dataset1', ([0, -3], [1, -1], [2, 3], [3, 5])), 107 112 ) 108 113 ch = pycha.bar.VerticalBarChart(surface) … … 110 115 ch._updateXY() 111 116 ch._updateChart() 112 ch._updateTicks() 113 xticks = [(0.125, 1), (0.375, 2), (0.625, 3)] 114 for i in range(len(xticks)): 115 self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4) 116 self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4) 117 118 def test_shadowRectangle(self): 119 ch = pycha.bar.VerticalBarChart(None) 120 shadow = ch._getShadowRectangle(10, 20, 400, 300) 121 self.assertEqual(shadow, (8, 18, 404, 302)) 122 123 class HorizontalBarTests(unittest.TestCase): 124 125 def test_updateChart(self): 126 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 127 dataset = ( 128 ('dataset1', ([0, 1], [1, 1], [2, 3])), 129 ('dataset2', ([0, 2], [1, 0], [3, 4])), 130 ) 131 ch = pycha.bar.HorizontalBarChart(surface) 132 ch.addDataset(dataset) 133 ch._updateXY() 134 ch._updateChart() 117 self.assertEqual(ch.minxval, 0) 118 self.assertEqual(ch.maxxval, 3) 135 119 self.assertEqual(ch.xrange, 3) 136 120 self.assertAlmostEqual(ch.xscale, 0.25, 4) 137 self.assertAlmostEqual(ch.yscale, 0.25, 4) 121 self.assertEqual(ch.minyval, -3) 122 self.assertEqual(ch.maxyval, 5) 123 self.assertEqual(ch.yrange, 8) 124 self.assertAlmostEqual(ch.yscale, 0.125, 4) 125 self.assertAlmostEqual(ch.area.origin, 0.375) 138 126 self.assertEqual(ch.minxdelta, 1) 139 self.assertAlmostEqual(ch.barWidthForSet, 0. 09375, 4)127 self.assertAlmostEqual(ch.barWidthForSet, 0.1875, 4) 140 128 self.assertAlmostEqual(ch.barMargin, 0.03125, 4) 141 129 130 R = pycha.bar.Rect 142 131 bars = ( 143 pycha.bar.Rect(0, 0.03125, 0.25, 0.09375, 0, 1, 'dataset1'), 144 pycha.bar.Rect(0, 0.28125, 0.25, 0.09375, 1, 1, 'dataset1'), 145 pycha.bar.Rect(0, 0.53125, 0.75, 0.09375, 2, 3, 'dataset1'), 146 147 pycha.bar.Rect(0, 0.125, 0.5, 0.09375, 0, 2, 'dataset2'), 148 pycha.bar.Rect(0, 0.375, 0.0, 0.09375, 1, 0, 'dataset2'), 149 pycha.bar.Rect(0, 0.875, 1.0, 0.09375, 3, 4, 'dataset2'), 132 R(0.03125, 0.625, 0.1875, 0.375, 0, -3, 'dataset1'), 133 R(0.28125, 0.625, 0.1875, 0.125, 1, -1, 'dataset1'), 134 R(0.53125, 0.250, 0.1875, 0.375, 2, 3, 'dataset1'), 135 R(0.78125, 0.000, 0.1875, 0.625, 3, 5, 'dataset1'), 150 136 ) 151 137 … … 166 152 ('dataset2', ([0, 2], [1, 0], [3, 4])), 167 153 ) 154 ch = pycha.bar.VerticalBarChart(surface) 155 ch.addDataset(dataset) 156 ch._updateXY() 157 ch._updateChart() 158 ch._updateTicks() 159 xticks = [(0.125, 0), (0.375, 1), (0.625, 2)] 160 for i in range(len(xticks)): 161 self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4) 162 self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4) 163 164 yticks = [ 165 (1.0, 0.0), (0.9, 0.4), (0.8, 0.8), (0.7, 1.2), (0.6, 1.6), 166 (0.5, 2.0), (0.4, 2.4), (0.3, 2.8), (0.2, 3.2), (0.1, 3.6), 167 (0.0, 4.0) 168 ] 169 for i in range(len(yticks)): 170 self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4) 171 self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4) 172 173 def test_udpateTicksWithNegatives(self): 174 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 175 dataset = ( 176 ('dataset1', ([0, -2], [1, 1], [2, 3])), 177 ) 178 ch = pycha.bar.VerticalBarChart(surface) 179 ch.addDataset(dataset) 180 ch._updateXY() 181 ch._updateChart() 182 ch._updateTicks() 183 xticks = [(0.1667, 0), (0.5000, 1), (0.8333, 2)] 184 for i in range(len(xticks)): 185 self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4) 186 self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4) 187 188 yticks = [ 189 (1.0, -2.0), (0.9, -1.5), (0.8, -1.0), (0.7, -0.5), (0.6, 0.0), 190 (0.5, 0.5), (0.4, 1.0), (0.3, 1.5), (0.2, 2.0), (0.1, 2.5), 191 (0.0, 3.0) 192 ] 193 for i in range(len(yticks)): 194 self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4) 195 self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4) 196 197 def test_shadowRectangle(self): 198 ch = pycha.bar.VerticalBarChart(None) 199 shadow = ch._getShadowRectangle(10, 20, 400, 300) 200 self.assertEqual(shadow, (8, 18, 404, 302)) 201 202 class HorizontalBarTests(unittest.TestCase): 203 204 def test_updateChart(self): 205 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 206 dataset = ( 207 ('dataset1', ([0, 1], [1, 1], [2, 3])), 208 ('dataset2', ([0, 2], [1, 0], [3, 4])), 209 ) 168 210 ch = pycha.bar.HorizontalBarChart(surface) 169 211 ch.addDataset(dataset) 170 212 ch._updateXY() 171 213 ch._updateChart() 214 self.assertEqual(ch.xrange, 3) 215 self.assertAlmostEqual(ch.xscale, 0.25, 4) 216 self.assertAlmostEqual(ch.yscale, 0.25, 4) 217 self.assertEqual(ch.minxdelta, 1) 218 self.assertAlmostEqual(ch.barWidthForSet, 0.09375, 4) 219 self.assertAlmostEqual(ch.barMargin, 0.03125, 4) 220 221 bars = ( 222 pycha.bar.Rect(0, 0.03125, 0.25, 0.09375, 0, 1, 'dataset1'), 223 pycha.bar.Rect(0, 0.28125, 0.25, 0.09375, 1, 1, 'dataset1'), 224 pycha.bar.Rect(0, 0.53125, 0.75, 0.09375, 2, 3, 'dataset1'), 225 226 pycha.bar.Rect(0, 0.125, 0.5, 0.09375, 0, 2, 'dataset2'), 227 pycha.bar.Rect(0, 0.375, 0.0, 0.09375, 1, 0, 'dataset2'), 228 pycha.bar.Rect(0, 0.875, 1.0, 0.09375, 3, 4, 'dataset2'), 229 ) 230 231 for i, bar in enumerate(bars): 232 b1, b2 = ch.bars[i], bar 233 self.assertAlmostEqual(b1.x, b2.x, 4) 234 self.assertAlmostEqual(b1.y, b2.y, 4) 235 self.assertAlmostEqual(b1.w, b2.w, 4) 236 self.assertAlmostEqual(b1.h, b2.h, 4) 237 self.assertEqual(b1.xval, b2.xval) 238 self.assertEqual(b1.yval, b2.yval) 239 self.assertEqual(b1.name, b2.name) 240 241 def test_updateChartWithNegatives(self): 242 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 243 dataset = ( 244 ('dataset1', ([0, -3], [1, -1], [2, 3], [3, 5])), 245 ) 246 247 ch = pycha.bar.HorizontalBarChart(surface) 248 ch.addDataset(dataset) 249 ch._updateXY() 250 ch._updateChart() 251 self.assertEqual(ch.minxval, 0) 252 self.assertEqual(ch.maxxval, 3) 253 self.assertEqual(ch.xrange, 3) 254 self.assertAlmostEqual(ch.xscale, 0.25, 4) 255 self.assertEqual(ch.minyval, -3) 256 self.assertEqual(ch.maxyval, 5) 257 self.assertEqual(ch.yrange, 8) 258 self.assertAlmostEqual(ch.yscale, 0.125, 4) 259 self.assertAlmostEqual(ch.area.origin, 0.375) 260 self.assertEqual(ch.minxdelta, 1) 261 self.assertAlmostEqual(ch.barWidthForSet, 0.1875, 4) 262 self.assertAlmostEqual(ch.barMargin, 0.03125, 4) 263 264 R = pycha.bar.Rect 265 bars = ( 266 R(0.000, 0.03125, 0.375, 0.1875, 0, -3, 'dataset1'), 267 R(0.250, 0.28125, 0.125, 0.1875, 1, -1, 'dataset1'), 268 R(0.375, 0.53125, 0.375, 0.1875, 2, 3, 'dataset1'), 269 R(0.375, 0.78125, 0.625, 0.1875, 3, 5, 'dataset1'), 270 ) 271 272 for i, bar in enumerate(bars): 273 b1, b2 = ch.bars[i], bar 274 self.assertAlmostEqual(b1.x, b2.x, 4) 275 self.assertAlmostEqual(b1.y, b2.y, 4) 276 self.assertAlmostEqual(b1.w, b2.w, 4) 277 self.assertAlmostEqual(b1.h, b2.h, 4) 278 self.assertEqual(b1.xval, b2.xval) 279 self.assertEqual(b1.yval, b2.yval) 280 self.assertEqual(b1.name, b2.name) 281 282 def test_updateTicks(self): 283 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 284 dataset = ( 285 ('dataset1', ([0, 1], [1, 1], [2, 3])), 286 ('dataset2', ([0, 2], [1, 0], [3, 4])), 287 ) 288 ch = pycha.bar.HorizontalBarChart(surface) 289 ch.addDataset(dataset) 290 ch._updateXY() 291 ch._updateChart() 172 292 ch._updateTicks() 173 yticks = [(0.125, 1), (0.375, 2), (0.625, 3)] 293 294 xticks = [ 295 (0.0, 0.0), (0.1, 0.4), (0.2, 0.8), (0.3, 1.2), (0.4, 1.6), 296 (0.5, 2.0), (0.6, 2.4), (0.7, 2.8), (0.8, 3.2), (0.9, 3.6), 297 (1.0, 4.0) 298 ] 299 for i in range(len(xticks)): 300 self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4) 301 self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4) 302 303 yticks = [(0.125, 0), (0.375, 1), (0.625, 2)] 304 for i in range(len(yticks)): 305 self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4) 306 self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4) 307 308 def test_udpateTicksWithNegatives(self): 309 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 310 dataset = ( 311 ('dataset1', ([0, -2], [1, 1], [2, 3])), 312 ) 313 ch = pycha.bar.HorizontalBarChart(surface) 314 ch.addDataset(dataset) 315 ch._updateXY() 316 ch._updateChart() 317 ch._updateTicks() 318 xticks = [ 319 (0.0, -2.0), (0.1, -1.5), (0.2, -1.0), (0.3, -0.5), (0.4, 0.0), 320 (0.5, 0.5), (0.6, 1.0), (0.7, 1.5), (0.8, 2.0), (0.9, 2.5), 321 (1.0, 3.0) 322 ] 323 for i in range(len(xticks)): 324 self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4) 325 self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4) 326 327 yticks = [(0.1667, 0), (0.5000, 1), (0.8333, 2)] 174 328 for i in range(len(yticks)): 175 329 self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4) -
trunk/tests/chart.py
r85 r109 45 45 self.assertEqual(area.w, 100) 46 46 self.assertEqual(area.h, 300) 47 self.assertEqual(area.origin, 0.0) 48 msg = "<pycha.chart.Area@(10.00, 20.00) 100.00 x 300.00 Origin: 0.00>" 49 self.assertEqual(str(area), msg) 47 50 48 51 class OptionTests(unittest.TestCase): … … 164 167 self.assertEqual(ch.yscale, 1/4.0) 165 168 166 # TODO: test with different options ( xOriginIsZero,axis.range, ...)169 # TODO: test with different options (axis.range, ...) 167 170 168 171 def test_updateTicks(self): … … 177 180 ch._updateXY() 178 181 ch._updateTicks() 179 xticks = [(0.0, 1), (1/3.0, 2), (2/3.0, 3)]182 xticks = [(0.0, 0), (1/3.0, 1), (2/3.0, 2)] 180 183 for i in range(len(xticks)): 181 184 self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4) … … 189 192 self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4) 190 193 191 def test_updateExplicitTicks(self):194 def _test_updateExplicitTicks(self): 192 195 """Test for bug #7""" 193 196 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) -
trunk/tests/line.py
r85 r109 48 48 ch._updateXY() 49 49 ch._updateChart() 50 50 51 self.assertEqual(ch.minxval, 0) 52 self.assertEqual(ch.maxxval, 3) 53 self.assertEqual(ch.xrange, 3) 54 self.assertAlmostEqual(ch.xscale, 1/3.0, 4) 55 self.assertEqual(ch.minyval, 0) 56 self.assertEqual(ch.maxyval, 4) 57 self.assertEqual(ch.yrange, 4) 58 self.assertAlmostEqual(ch.yscale, 0.25, 4) 59 51 60 points = ( 52 61 pycha.line.Point(0, 0.75, 0, 1, 'dataset1'), … … 65 74 self.assertEqual(p1.name, p2.name) 66 75 76 def test_updateChartWithNegatives(self): 77 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500) 78 dataset = ( 79 ('dataset1', ([0, 1], [1, -2], [2, 3])), 80 ('dataset2', ([0, 2], [1, 0], [3, -4])), 81 ) 82 ch = pycha.line.LineChart(surface) 83 ch.addDataset(dataset) 84 ch._updateXY() 85 ch._updateChart() 86 self.assertEqual(ch.minxval, 0) 87 self.assertEqual(ch.maxxval, 3) 88 self.assertEqual(ch.xrange, 3) 89 self.assertAlmostEqual(ch.xscale, 1/3.0, 4) 90 self.assertEqual(ch.minyval, -4) 91 self.assertEqual(ch.maxyval, 3) 92 self.assertEqual(ch.yrange, 7) 93 self.assertAlmostEqual(ch.yscale, 1/7.0, 4) 94 95 points = ( 96 pycha.line.Point(0, 0.2857, 0, 1, 'dataset1'), 97 pycha.line.Point(1/3.0, 0.7143, 1, -2, 'dataset1'), 98 pycha.line.Point(2/3.0, 0.0, 2, 3, 'dataset1'), 99 pycha.line.Point(0, 0.1429, 0, 2, 'dataset2'), 100 pycha.line.Point(1/3.0, 0.4286, 1, 0, 'dataset2'), 101 pycha.line.Point(1, 1.0, 3, -4, 'dataset2'), 102 ) 103 for i, point in enumerate(points): 104 p1, p2 = ch.points[i], point 105 self.assertAlmostEqual(p1.x, p2.x, 4) 106 self.assertAlmostEqual(p1.y, p2.y, 4) 107 self.assertAlmostEqual(p1.xval, p2.xval, 4) 108 self.assertAlmostEqual(p1.yval, p2.yval, 4) 109 self.assertEqual(p1.name, p2.name) 110 67 111 def test_suite(): 68 112 return unittest.TestSuite((
