# 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())