On Fri, 2003-01-17 at 15:34, Omar Kilani wrote:
> Hello,
> 
> I was wondering if anyone knew of any charting/graphing code that worked
> with PyGTK 2 (utilising DrawingArea perhaps?)
> 
> I've googled, and there was once a project called 'PIDDLE' which had a
> graphing layer tacked on top of it, but it hasn't been maintained since
> June, 2002.

  I just done this quick-and-dirty example. I hope it helps.
  It would also be interesting to include it in pygtk's examples...

> 
> Regards,
> Omar Kilani
> 
> _______________________________________________
> pygtk mailing list   [EMAIL PROTECTED]
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
-- 
Gustavo Jo�o Alves Marques Carneiro
<[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

#! /usr/bin/env python

import gtk
import math

NPOINTS = 200

class PlotArea:
    def __init__(self, area, function):
	assert isinstance(area, gtk.DrawingArea)
	self.plot_x1 = 0
	self.plot_x2 = 0
	self.plot_y1 = 0
	self.plot_y2 = 0
	self.area = area
	self.area_width = 0
	self.area_height = 0
	area.connect("expose-event", self.expose_cb)
	area.connect("size-allocate", self.size_allocate_cb)
	area.connect("realize", self.realize_cb)
	self.pixmap = None
	self.function = function

    def __update_conv(self):
	self._sx = self.area_width  / (self.plot_x2 - self.plot_x1)
	self._sy = self.area_height / (self.plot_y2 - self.plot_y1)

    def set_range(self, x1, x2, y1, y2):
	self.plot_x1 = float(x1)
	self.plot_x2 = float(x2)
	self.plot_y1 = float(y1)
	self.plot_y2 = float(y2)
	self.__update_conv()

    def _convert_x(self, x):
	return (x - self.plot_x1)*self._sx

    def _convert_y(self, y):
	return self.area_height - (y - self.plot_y1)*self._sy

    def do_plot(self):
	if self.pixmap is None: return
	fg = self.area.style.fg_gc[gtk.STATE_NORMAL]
	bg = self.area.style.bg_gc[gtk.STATE_NORMAL]
	self.pixmap.draw_rectangle(gc=bg,
				   filled=1,
				   x=0, y=0,
				   width=self.area_width,
				   height=self.area_height)
	x = self.plot_x1
	print self.plot_x2, self.plot_x1
	delta = float(self.plot_x2 - self.plot_x1)/NPOINTS
	if delta <= 0: return
	wxold = None
	wyold = None
	while x <= self.plot_x2:
	    y = self.function(x)
	    wx = self._convert_x(x)
	    wy = self._convert_y(y)
	    x += delta
	    # drawing
	    if wxold is not None:
		self.pixmap.draw_line(fg, wxold, wyold, wx, wy)
	    wxold = wx
	    wyold = wy


    def realize_cb(self, widget):
	if self.pixmap is None:
	    self.pixmap = gtk.gdk.Pixmap(widget.window, self.area_width,
					 self.area_height, -1)
	    self.do_plot()

    def size_allocate_cb(self, widget, allocation):
	self.area_width = allocation.width
	self.area_height = allocation.height
	self.__update_conv()
	if widget.window is None: return
	self.pixmap = gtk.gdk.Pixmap(widget.window, self.area_width,
				     self.area_height, -1)
	self.do_plot()

    def expose_cb(self, widget, event):
	if self.pixmap is None: return
	area = event.area
	widget.window.draw_drawable(gc=widget.style.fg_gc[gtk.STATE_NORMAL],
				    src=self.pixmap,
				    xsrc=area.x, ysrc=area.y,
				    xdest=area.x, ydest=area.y,
				    width=area.width, height=area.height)
	return 1


win = gtk.Window()
area = gtk.DrawingArea()
x = PlotArea(area, math.sin);
x.set_range(0, 10, -3, 3)
win.add(area)
win.show_all()
win.connect("destroy", gtk.mainquit)


gtk.mainloop()

Reply via email to