[hamster-applet] fixed pixel precision



commit 12c3e4d8acb3a90371e93b8199ce54480c36556c
Author: Toms Bauģis <toms baugis gmail com>
Date:   Wed Dec 23 01:46:57 2009 +0000

    fixed pixel precision

 hamster/charting.py |  145 ++++++++++++++++++++++++--------------------------
 1 files changed, 70 insertions(+), 75 deletions(-)
---
diff --git a/hamster/charting.py b/hamster/charting.py
index 7b29cb8..88cf5d5 100644
--- a/hamster/charting.py
+++ b/hamster/charting.py
@@ -245,6 +245,9 @@ class BarChart(Chart):
             return
 
         context = self.context        
+        context.set_line_width(1)
+
+
         # determine graph dimensions
         if self.show_stack_labels:
             legend_width = self.legend_width or self.longest_label(self.keys)
@@ -277,10 +280,6 @@ class BarChart(Chart):
 
         self.context.stroke()
 
-        bar_width = min(self.graph_width / float(len(self.keys)),
-                                                             self.max_bar_width)
-        gap = bar_width * 0.05
-        
         # bars and keys
         max_bar_size = self.graph_height
         #make sure bars don't hit the ceiling
@@ -291,12 +290,23 @@ class BarChart(Chart):
         prev_label_end = None
         self.layout.set_width(-1)
 
-        for i in range(len(self.keys)):
+        exes = {}
+        x = 0
+        bar_width = min(self.graph_width / float(len(self.keys)), self.max_bar_width)
+        for i, key in enumerate(self.keys):
+            exes[key] = (x + self.graph_x, round(bar_width - 1))
+            
+            x = x + round(bar_width)
+            bar_width = min(self.max_bar_width,
+                            (self.graph_width - x) / float(max(1, len(self.keys) - i - 1)))
+
+
+        for key, bar, data in zip(self.keys, self.bars, self.data):
             self.set_color(graphics.Colors.aluminium[5]);
-            self.layout.set_text(self.keys[i])
+            self.layout.set_text(key)
             label_w, label_h = self.layout.get_pixel_size()
 
-            intended_x = (bar_width * i) + (bar_width - label_w) / 2.0 + self.graph_x
+            intended_x = exes[key][0] + (exes[key][1] - label_w) / 2
             
             if not prev_label_end or intended_x > prev_label_end:
                 self.context.move_to(intended_x, self.graph_height + 4)
@@ -307,39 +317,38 @@ class BarChart(Chart):
 
             bar_start = 0
             base_color = self.bar_base_color or (220, 220, 220)
-            bar_x = round(self.graph_x + bar_width * i + gap)
-
+            
             if self.stack_keys:
-                for j, bar in enumerate(self.bars[i]):
-                    if bar.size > 0:
-                        bar_size = round(max_bar_size * bar.size)
+                for j, stack_bar in enumerate(bar):
+                    if stack_bar.size > 0:
+                        bar_size = round(max_bar_size * stack_bar.size)
                         bar_start += bar_size
                         
                         last_color = self.stack_key_colors.get(self.stack_keys[j],
                                                                self.get_bar_color(j))
-                        self.draw_bar(bar_x,
+                        self.draw_bar(exes[key][0],
                                       self.graph_height - bar_start,
-                                      round(bar_width - (gap * 2)),
+                                      exes[key][1],
                                       bar_size,
                                       last_color)
             else:
-                bar_size = round(max_bar_size * self.bars[i].size)
+                bar_size = round(max_bar_size * bar.size)
                 bar_start = bar_size
 
-                last_color = self.key_colors.get(self.keys[i],
+                last_color = self.key_colors.get(key,
                                                   base_color)
-                self.draw_bar(bar_x,
+                self.draw_bar(exes[key][0],
                               self.graph_y + self.graph_height - bar_size,
-                              round(bar_width - (gap * 2)),
+                              exes[key][1],
                               bar_size,
                               last_color)
 
 
             if self.values_on_bars:  # it's either stack labels or values at the end for now
                 if self.stack_keys:
-                    total_value = sum(self.data[i])
+                    total_value = sum(data[i])
                 else:
-                    total_value = self.data[i]
+                    total_value = data[i]
                 
                 self.layout.set_width(-1)
                 self.layout.set_text(self.value_format % total_value)
@@ -351,7 +360,8 @@ class BarChart(Chart):
                 else:
                     label_y = self.graph_y + self.graph_height - bar_start - label_h + 5
                 
-                context.move_to(self.graph_x + (bar_width * i) + (bar_width - label_w) / 2.0, label_y)
+                context.move_to(self.exes[key][0] + (self.exes[key][1] - label_w) / 2.0,
+                                label_y)
 
                 # we are in the bar so make sure that the font color is distinguishable
                 if colorsys.rgb_to_hls(*graphics.Colors.rgb(last_color))[1] < 150:
@@ -360,18 +370,8 @@ class BarChart(Chart):
                     self.set_color(graphics.Colors.aluminium[5])        
 
                 context.show_layout(self.layout)
-    
-                # values on bars
-                if self.stack_keys:
-                    total_value = sum(self.data[i])
-                else:
-                    total_value = self.data[i]
 
 
-        #fill with white background (necessary for those dragging cases)
-        if self.background:
-            self.fill_area(0, 0, legend_width, self.height, self.background)
-
         #white grid and scale values
         self.layout.set_width(-1)
         if self.grid_stride and self.max_value:
@@ -383,7 +383,7 @@ class BarChart(Chart):
             
             context.set_line_width(1)
             for i in range(grid_stride, int(self.max_value), grid_stride):
-                y = max_bar_size * (i / self.max_value)
+                y = round(max_bar_size * (i / self.max_value)) + 0.5
 
                 if self.show_scale:
                     self.layout.set_text(self.value_format % i)
@@ -393,17 +393,13 @@ class BarChart(Chart):
                     self.set_color(graphics.Colors.aluminium[4])
                     context.show_layout(self.layout)
 
-                self.set_color((255, 255, 255))
+                self.set_color("#ffffff")
                 self.context.move_to(legend_width, y)
                 self.context.line_to(self.width, y)
 
 
         #stack keys
-        context.save()
         if self.show_stack_labels:
-            context.set_line_width(1)
-            context.set_antialias(cairo.ANTIALIAS_DEFAULT)
-
             #put series keys
             self.set_color(graphics.Colors.aluminium[5]);
             
@@ -463,7 +459,6 @@ class BarChart(Chart):
                         context.line_to(line_x2, round(y + bar_size / 2))
 
         context.stroke()
-        context.restore()
 
 
 class HorizontalBarChart(Chart):
@@ -493,14 +488,18 @@ class HorizontalBarChart(Chart):
         if not self.data:  #if we have nothing, let's go home
             return
 
-        
-        bar_width = int(self.graph_height / float(rowcount))
-        bar_width = min(bar_width, self.max_bar_width)
+        positions = {}
+        y = 0
+        bar_width = min(self.graph_height / float(len(self.keys)), self.max_bar_width)
+        for i, key in enumerate(self.keys):
+            positions[key] = (y + self.graph_y, round(bar_width - 1))
+            
+            y = y + round(bar_width)
+            bar_width = min(self.max_bar_width,
+                            (self.graph_height - y) / float(max(1, len(self.keys) - i - 1)))
 
-        
-        max_bar_size = self.graph_width - 15
-        gap = bar_width * 0.05
 
+        max_bar_size = self.graph_width - 15
 
         self.layout.set_alignment(pango.ALIGN_RIGHT)
         self.layout.set_ellipsize(pango.ELLIPSIZE_END)
@@ -520,44 +519,39 @@ class HorizontalBarChart(Chart):
             self.layout.set_text(label)
             label_w, label_h = self.layout.get_pixel_size()
 
-            context.move_to(0, (bar_width * i) + (bar_width - label_h) / 2)
+            context.move_to(0, positions[label][0] + (positions[label][1] - label_h) / 2)
             context.show_layout(self.layout)
 
             base_color = self.bar_base_color or (220, 220, 220)
 
-            gap = bar_width * 0.05
-
-            bar_y = round(self.graph_y + (bar_width * i) + gap)
-
             last_color = (255,255,255)
-
             if self.stack_keys:
                 bar_start = 0
 
                 for j, bar in enumerate(self.bars[i]):
                     if bar.size > 0:
                         bar_size = round(max_bar_size * bar.size)
-                        bar_height = round(bar_width - (gap * 2))
                         
                         last_color = self.stack_key_colors.get(self.stack_keys[j],
                                                                self.get_bar_color(j))
                         self.draw_bar(self.graph_x + bar_start,
-                                      bar_y,
+                                      positions[label][0],
                                       bar_size,
-                                      bar_height,
+                                      positions[label][1],
                                       last_color)
                         bar_start += bar_size
             else:
                 bar_size = round(max_bar_size * self.bars[i].size)
                 bar_start = bar_size
 
-                bar_height = round(bar_width - (gap * 2))
-
                 last_color = self.key_colors.get(self.keys[i],
                                                  base_color)
 
-                self.draw_bar(self.graph_x, bar_y, bar_size, bar_height,
-                                                                     last_color)
+                self.draw_bar(self.graph_x,
+                              positions[label][0],
+                              bar_size,
+                              positions[label][1],
+                              last_color)
 
             # values on bars
             if self.stack_keys:
@@ -569,7 +563,7 @@ class HorizontalBarChart(Chart):
             self.layout.set_text(self.value_format % total_value)
             label_w, label_h = self.layout.get_pixel_size()
 
-            vertical_padding = (bar_width - (bar_width + label_h) / 2.0 ) / 2.0
+            vertical_padding = max((positions[label][1] - label_h) / 2.0, 1)
             if  bar_start - vertical_padding < label_w:
                 label_x = self.graph_x + bar_start + vertical_padding
                 self.set_color(graphics.Colors.aluminium[5])        
@@ -582,7 +576,7 @@ class HorizontalBarChart(Chart):
                     
                 label_x = self.graph_x + bar_start - label_w - vertical_padding
             
-            context.move_to(label_x, self.graph_y + (bar_width * i) + (bar_width - label_h) / 2.0)
+            context.move_to(label_x, positions[label][0] + (positions[label][1] - label_h) / 2.0)
             context.show_layout(self.layout)
 
         context.stroke()
@@ -641,13 +635,19 @@ class HorizontalDayChart(Chart):
         
         self.context.translate(0.5, 0.5)
 
-        bar_width = int(self.graph_height / float(rowcount))
-        bar_width = min(bar_width, self.max_bar_width)
+        positions = {}
+        y = 0
+        bar_width = min(self.graph_height / float(len(self.keys)), self.max_bar_width)
+        for i, key in enumerate(self.keys):
+            positions[key] = (y + self.graph_y, round(bar_width - 1))
+            
+            y = y + round(bar_width)
+            bar_width = min(self.max_bar_width,
+                            (self.graph_height - y) / float(max(1, len(self.keys) - i - 1)))
+
 
         
         max_bar_size = self.graph_width - 15
-        gap = bar_width * 0.05
-
 
         self.layout.set_alignment(pango.ALIGN_RIGHT)
         self.layout.set_ellipsize(pango.ELLIPSIZE_END)
@@ -663,18 +663,11 @@ class HorizontalDayChart(Chart):
             self.layout.set_text(label)
             label_w, label_h = self.layout.get_pixel_size()
 
-            context.move_to(0, (bar_width * i) + (bar_width - label_h) / 2)
+            context.move_to(0, positions[label][0] + (positions[label][1] - label_h) / 2)
             context.show_layout(self.layout)
 
             base_color = self.bar_base_color or [220, 220, 220]
 
-            gap = bar_width * 0.05
-
-            bar_y = self.graph_y + round((bar_width * i) + gap)
-
-            
-            bar_height = round(bar_width - (gap * 2))
-            
             if isinstance(self.data[i], list) == False:
                 self.data[i] = [self.data[i]]
             
@@ -683,9 +676,9 @@ class HorizontalDayChart(Chart):
                 bar_size = round((row[1] - start_hour) * factor - bar_x)
                 
                 self.draw_bar(self.graph_x + bar_x + 0.5,
-                              bar_y + 0.5,
+                              positions[label][0] + 0.5,
                               bar_size,
-                              bar_height,
+                              positions[label][1],
                               base_color)
 
         #white grid and scale values
@@ -694,6 +687,7 @@ class HorizontalDayChart(Chart):
         context.set_line_width(1)
 
         pace = ((end_hour - start_hour) / 3) / 60 * 60
+        last_position = positions[keys[-1]]
         for i in range(start_hour + 60, end_hour, pace):
             x = round((i - start_hour) * factor)
             
@@ -703,14 +697,15 @@ class HorizontalDayChart(Chart):
             label_w, label_h = self.layout.get_pixel_size()
 
             context.move_to(self.graph_x + x - label_w / 2,
-                            bar_y + bar_height + 4)
+                            last_position[0] + last_position[1] + 4)
             self.set_color(graphics.Colors.aluminium[4])
             context.show_layout(self.layout)
 
             
             self.set_color((255, 255, 255))
             self.context.move_to(self.graph_x + x, self.graph_y)
-            self.context.line_to(self.graph_x + x, bar_y + bar_height)
+            self.context.line_to(self.graph_x + x,
+                                 last_position[0] + last_position[1])
 
                 
         context.stroke()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]