StripChart.py 1.83 KB
Newer Older
Guido van Rossum's avatar
Guido van Rossum committed
1 2 3
# Module 'StripChart'

import rect
4
from Buttons import LabelAppearance, NoReactivity
Guido van Rossum's avatar
Guido van Rossum committed
5

6 7
# A StripChart doesn't really look like a label but it needs a base class.
# LabelAppearance allows it to be disabled and hilited.
Guido van Rossum's avatar
Guido van Rossum committed
8

Guido van Rossum's avatar
Guido van Rossum committed
9
class StripChart(LabelAppearance, NoReactivity):
Guido van Rossum's avatar
Guido van Rossum committed
10
	#
11
	def define(self, parent, scale):
12 13 14
		self.parent = parent
		parent.addchild(self)
		self.init_appearance()
Guido van Rossum's avatar
Guido van Rossum committed
15 16 17 18 19 20
		self.init_reactivity()
		self.ydata = []
		self.scale = scale
		self.resetbounds()
		return self
	#
Guido van Rossum's avatar
Guido van Rossum committed
21 22 23
	def destroy(self):
		self.parent = 0
	#
Guido van Rossum's avatar
Guido van Rossum committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
	def setbounds(self, bounds):
		LabelAppearance.setbounds(self, bounds)
		self.resetbounds()
	#
	def resetbounds(self):
		(left, top), (right, bottom) = self.bounds
		self.width = right-left
		self.height = bottom-top
		excess = len(self.ydata) - self.width
		if excess > 0:
			del self.ydata[:excess]
		elif excess < 0:
			while len(self.ydata) < self.width:
				self.ydata.insert(0, 0)
	#
	def append(self, y):
		self.ydata.append(y)
		excess = len(self.ydata) - self.width
		if excess > 0:
			del self.ydata[:excess]
44 45 46
			if self.bounds <> rect.empty:
				self.parent.scroll(self.bounds, (-excess, 0))
		if self.bounds <> rect.empty:
Guido van Rossum's avatar
Guido van Rossum committed
47 48 49
			(left, top), (right, bottom) = self.bounds
			i = len(self.ydata)
			area = (left+i-1, top), (left+i, bottom)
50
			self.draw(self.parent.begindrawing(), area)
Guido van Rossum's avatar
Guido van Rossum committed
51
	#
52 53
	def draw(self, d, area):
		area = rect.intersect([area, self.bounds])
Guido van Rossum's avatar
Guido van Rossum committed
54
		if area == rect.empty:
Guido van Rossum's avatar
Guido van Rossum committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
			return
		d.cliprect(area)
		d.erase(self.bounds)
		(a_left, a_top), (a_right, a_bottom) = area
		(left, top), (right, bottom) = self.bounds
		height = bottom - top
		i1 = a_left - left
		i2 = a_right - left
		for i in range(max(0, i1), min(len(self.ydata), i2)):
			split = bottom-self.ydata[i]*height/self.scale
			d.paint((left+i, split), (left+i+1, bottom))
		if not self.enabled:
			self.flipenable(d)
		if self.hilited:
			self.fliphilite(d)
		d.noclip()