Repository URL to install this package:
Version:
4.8.0 ▾
|
chaco
/
polar_line_renderer.py
|
---|
""" Defines the PolarLineRenderer class.
"""
from __future__ import with_statement
# Major library imports
from numpy import array, cos, pi, sin, transpose
# Enthought library imports
from enable.api import black_color_trait, LineStyle
from traits.api import Float
# Local, relative imports
from .abstract_plot_renderer import AbstractPlotRenderer
class PolarLineRenderer(AbstractPlotRenderer):
""" A renderer for polar line plots.
"""
#------------------------------------------------------------------------
# Appearance-related traits
#------------------------------------------------------------------------
# The color of the origin axis.
origin_axis_color_ = (0,0,0,1)
# The width of the origin axis.
origin_axis_width = 2.0
# The origin axis is visible.
origin_axis_visible=True
# The grid is visible.
grid_visible= True
# The orientation of the plot is horizontal; for any other value, it is
# transposed
orientation = 'h'
# The color of the line.
color = black_color_trait
# The width of the line.
line_width = Float(1.0)
# The style of the line.
line_style = LineStyle("solid")
# The style of the grid lines.
grid_style= LineStyle("dot")
def _gather_points(self):
"""
Collects the data points that are within the plot bounds and caches them
"""
# This is just a stub for now. We should really find the lines only
# inside the screen range here.
x = self.index.get_data()
y = self.value.get_data()
rad= min(self.width/2.0,self.height/2.0)
sx = x*rad+ self.x + self.width/2.0
sy = y*rad+ self.y + self.height/2.0
points = transpose(array((sx,sy)))
self._cached_data_pts = points
self._cache_valid = True
return
def _data_changed(self):
self._cache_valid = False
return
def _update_mappers(self):
#Dunno if there is anything else to do here
self._cache_valid = False
def _render(self, gc, points):
""" Actually draw the plot.
"""
with gc:
gc.set_antialias(True)
self._draw_default_axes(gc)
self._draw_default_grid(gc)
if len(points)>0:
gc.clip_to_rect(self.x, self.y, self.width, self.height)
gc.set_stroke_color(self.color_)
gc.set_line_width(self.line_width)
gc.set_line_dash(self.line_style_)
gc.begin_path()
gc.lines(points)
gc.stroke_path()
return
def map_screen(self, data_array):
""" Maps an array of data points into screen space and returns it as
an array.
Implements the AbstractPlotRenderer interface.
"""
if len(data_array) == 0:
return []
elif len(data_array) == 1:
xtmp, ytmp = transpose(data_array)
x_ary = xtmp
y_ary = ytmp
else:
x_ary, y_ary = transpose(data_array)
sx = self.index_mapper.map_screen(x_ary)
sy = self.value_mapper.map_screen(y_ary)
if self.orientation == 'h':
return transpose(array((sx, sy)))
else:
return transpose(array((sy, sx)))
def map_data(self, screen_pt):
""" Maps a screen space point into the "index" space of the plot.
Implements the AbstractPlotRenderer interface.
"""
if self.orientation == 'h':
x, y = screen_pt
else:
y,x = screen_pt
return array((self.index_mapper.map_data(x),
self.value_mapper.map_data(y)))
def _downsample(self):
return self.map_screen(self._cached_data_pts)
def _draw_plot(self, *args, **kw):
""" Draws the 'plot' layer.
"""
# Simple compatibility with new-style rendering loop
return self._draw_component(*args, **kw)
def _draw_component(self, gc, view_bounds=None, mode='normal'):
""" Renders the component.
"""
self._gather_points()
self._render(gc, self._cached_data_pts)
def _bounds_changed(self, old, new):
super(PolarLineRenderer, self)._bounds_changed(old, new)
self._update_mappers()
def _bounds_items_changed(self, event):
super(PolarLineRenderer, self)._bounds_items_changed(event)
self._update_mappers()
def _draw_default_axes(self, gc):
if not self.origin_axis_visible:
return
with gc:
gc.set_stroke_color(self.origin_axis_color_)
gc.set_line_width(self.origin_axis_width)
gc.set_line_dash(self.grid_style_)
x_data,y_data= transpose(self._cached_data_pts)
x_center=self.x + self.width/2.0
y_center=self.y + self.height/2.0
for theta in range(12):
r= min(self.width/2.0,self.height/2.0)
x= r*cos(theta*pi/6) + x_center
y= r*sin(theta*pi/6) + y_center
data_pts= array([[x_center,y_center],[x,y]])
start,end = data_pts
gc.move_to(int(start[0]), int(start[1]))
gc.line_to(int(end[0]), int(end[1]))
gc.stroke_path()
return
def _draw_default_grid(self,gc):
if not self.grid_visible:
return
with gc:
gc.set_stroke_color(self.origin_axis_color_)
gc.set_line_width(self.origin_axis_width)
gc.set_line_dash(self.grid_style_)
x_data,y_data = transpose(self._cached_data_pts)
x_center = self.x + self.width/2.0
y_center = self.y + self.height/2.0
rad = min(self.width/2.0, self.height/2.0)
for r_part in range(1,5):
r = rad*r_part/4
gc.arc(x_center, y_center, r, 0, 2*pi)
gc.stroke_path()
return