Chaco fundamentally represents the object model behind an active plot as a directed graph.  Data is filtered and mapped until it reaches a renderer, which outputs the result of the final mapping.  End-user tools can interact not only with the front-most visual elements, but also with the underlying data.  To facilitate this, all data manipulation stages support reverse mapping to some degree: (in descending order of accuracy/correspondence with query point):

    get_data_for_pt() -> a single element of the DataSeries; could be an array
    get_datarange_for_pt -> a set of as-tight-as-possible bound indices into the DataSeries
    get_object_for_pt

The renderer makes the first call about what reverse-mapping is available to an end-user tool.  If the data pipeline feeding the renderer does an irreversible mapping at some point, it should at the minimum be able to return a reference to the upstream DataSeries that feeds it.  Once a tool has a reference to the original data, it can then modify the domain object or any intermediary (by walking the pipeline of maps/filters).

The Chaco data model is concerned with the manipulation of data so that it can be appropriately displayed by a visual element.  Most data manipulation is some sort of filtering, whether it's view-independent (range restricting, quantization, etc.) or view-dependent (downsampling).  The elements of the data model fit into a pipeline that sends data forwards from data space into screen space and services requests to map screen space back into data space.


new classes:

DataRenderer (vs. Renderer)

DataMap

DataFilter

Controller

outstanding questions:
- We should rename VisualElement to "Renderer", and then distinguish a subclass "DataRenderer" for anything that draws mapped data

- The visual terminus of the data pipeline should be segregated from the event handling as much as possible.  What hooks do Renderers need to provide so that they work well with Controllers?

- We need a more general notion of selection than just an AbstractRange.  It seems to be better characterized by a Filter than a Range, really.

- What is the strategy for dealing with Controllers/tools that are specific to a particular segment in the data pipeline?  E.g. a tool that targets just the contour filter, or one that somehow knows about/twiddles the downsampling.  Should we leave it up to the tool writer to walk the pipeline, or is there a more elegant way of supporting this?


DataSource (dimension, data, views)

    AbstractDataSeries
        ScalarData
        PointData
        ImageData

    AbstractFilter
        ViewFilter
        CompoundFilter
        AbstractMaskFilter
            MaskFilter
            ImageMaskFilter

    AbstractDataMap
        AffineMap
        PolarMap

DataView
ViewProxy

AbstractRange
    ScalarRange
    ImageRange

AbstractAnnotation

AbstractPlotData  (Maybe should be renamed???)
    XYData - simple scalar vs scalar
        MultiXYData
    ImageData - 2D grid of scalar values
    ImageData2D - 2D grid of vector values
    PointData - list of 2D points for index, scalar value
    PointData2D - list of 2D points for index, vector value



?? Approach for handling secondary data objects generated from histogramming, etc.

DataViews are really the start of the Chaco data pipeline.  Without a range, a DataSource is just an array.  Once it is hooked up to a DataView, the view facilitates ranges, filtering, selection, and annotation, both by offering the appropriate data downstream to visual elements and other consumers, and by offering an API for querying meta-data about the numerical data.

Views can be hooked up to an axis.  Since an axis represents a measure of the data space, it makes sense that it is associated with the object that expresses the window into that data space.


Frames and Layout
--------------------------------
A particular type of layout makes assumptions about how its component pieces fit together.

Questions:
- Should layouts be nestable?
- Should layouts be manifest as instances (frames), or should they be functional classes that act on existing hierarchical information?  Grouping concepts like PlotGroup etc. seem related to layout functions, but multiple layouts might be able to apply to a given hierarchy of visual elements.
- Visual elements might have metadata associated with them that describe what role or slot they fill in a given layout.  E.g. a plotframe may have spots for "main plot area", "legend area", two horizontal axis regions and two vertical axis regions.  Visual elements, then can identify themselves as fulfilling some of these roles.
- Are Layout and Frame the same concepts?  Is frame more stateful, and layout more functional?


Notes
--------------------------------

- What does a DataSource need to provide to its downstream consumers?  What should it allow its consumers to say back to it?  What sorts of filters might there be (the primary use for a data pipeline)?  Look at VTK for some examples... Also, might it be useful to explicitly distinguish between data-space filters/datasources and screen-space stuff?

- Is there a useful intermediate coordinate space between data space and raster space?  Since kiva is all vector-based, perhaps it's best to keep everything in vector "render space" coordinates, and leave pixel coordinates out of the equation until the very end?  This would make it easier to do arbitrary transforms, etc.  Unfortunately, layout and things like tickmark generation need to know actual pixels.  Perhaps this should be part of the producer/consumer interface for coordinate-space elements, or taken into account as part of the layout process (hinting, etc.).

Downsampling dataviews are initialized with a raster space and an input
data set.  They generate a downsampled dataset that they cache and invalidate
whenever their range, raster space, or input data changes.
