# Here starts the boiler plate
from zope.interface import implements # <- this is needed here to form the PlotImage component
from zope.component import getGlobalSiteManager, adapts # <- Only needed for the extension afterwards
gsm = getGlobalSiteManager() # <- Only needed for the extension afterwards
# End of Boiler plate
# Import of the sub components.
from graph_ZCA.components import BaseComponent, Image, Axis, ViewBox
# Only needed for the extension afterwards.
from graph_ZCA.interfaces import IAxis, IViewBox, IBaseComponent
from graph_ZCA.components import TickLabelComponent, AxisComponent
# Set up a new interface for the component PlotImage. Here usually properties, functions and other exposed items
# of a PlotImage instance would be documented and registered to the framework. Since the only function render is
# already documented for IBaseComponent nothing has to be done here.
class IPlotImage(IBaseComponent):
"""
Component to plot a 2d graph of a given image
"""
# Here the component itself is constructed. The component inherits from a simple BaseComponent without much importance.
# The only crucial requirement is that every component knows its parent component as self.parent, which is the first
# parameter to the constructor. The top most component has a parent of NONE.
class PlotImage( BaseComponent):
"""
Makes a 2D plot for an image
"""
implements(IPlotImage) # here the interface specified above is used.
def __init__(self, parent):
super(PlotImage, self).__init__(parent) # tribute to the super class
self.vb = ViewBox(self)() # make a ViewBox. Please notice the double Braces. These are neccessary for the framework.
# In fact here in no instance generated but a factory. And with the second brace
# the factory produces the instance.
# The PlotImage "self" is assigned as parent for the ViewBox
x_axis = Axis(self.vb)() # Same pattern here
# The axis are assigned to the viewbox
x_axis.orientation='bottom'
x_axis.start=0
x_axis.end=8
y_axis = Axis(self.vb)() # and here
y_axis.orientation='left'
y_axis.start=-5
y_axis.end=3
self.vb.addItem( x_axis ) # Finally the axis are given to the viewbox. This step may be not necessary and
# may be done automatically while assigning the parent to the axis.
self.vb.addItem( y_axis )
def render(self): # In this prototype code every component optains a render method that is used to generate
# some simple output
return self.vb.render()
# # The following statements can be uncommented to illustrate how to swap classes.
# #
# # This example shows how to swap all Axis components which parents are a ViewBoxes to be of class NewAxisComponent
# class NewAxisComponent(AxisComponent):
# adapts(IViewBox)
#
# gsm.registerAdapter(NewAxisComponent)
#
# # This example shows how to exchange the TickLabelComponent for all Axis
# class NewTickLabelComponent(TickLabelComponent):
# adapts(IAxis)
#
# def render(self):
# return " ".join([ "q%i" % i for i in range(self.axis.start, self.axis.end)])
#
# gsm.registerAdapter(NewTickLabelComponent)
image_data = [1,2,3,4]
plot = PlotImage( None)
image = Image(plot.vb)(image_data)
plot.vb.addItem(image)
print( plot.render())