Changeset 109 for trunk/src/chart.py
- Timestamp:
- 10/27/08 16:49:58 (4 years ago)
- Files:
-
- 1 modified
-
trunk/src/chart.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
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,
