Skip to content

Data Source Operations

g$ edited this page Mar 15, 2023 · 4 revisions

Rather than playing "20 Questions" with your ObservableCollection event stream, we are going with a whole new way of submitting data to the chart for rendering.

The DataSource plays a central role again, but instead of referencing an IEnumerable it has a Dependency Property named CommandPort that you set to the value of a Data Source Operation.

The Dependency Property machinery detects the value change and submits a unit-of-work to the Chart via DispatcherQueue which provides atomic state changes represented by each operation.

These are instructions for adding and removing data from the chart. It also provides a context for coordinating the movement of all affected items simultaneously.

Item States

Before we enumerate the operations, let us go over how items are maintained for processing.

Each series maintains an internal list of "items" corresponding to your data objects and any CompositionObject. For a given operation, each item has a state associated with it, according to its purpose:

  • Enter - appearing for the first time
    • element visibility is additionally determined by ElementSelector
  • Live - present in the previous render cycle
    • element may currently be null and not rendered
    • element visibility is additionally determined by ElementSelector
    • visibility change causes Enter/Exit sequence for this position
    • Enter/Exit may be different transitions from "main" Enter/Exit
  • Exit - appeared for the last time

Each DataSource operation implies a specific sequence of updates, based on the states of existing items plus any modifications given in the operation itself, e.g. deleted (exiting) and new (entering) items.

Item Selectors

The ElementSelector (optional) is evaluated on all entering and live items, to determine whether to render geometry or a "hole". This can cause additional enters and exits on existing items if they change from "selected" to "unselected".

Element Factory

To get around the lack of XAML Style support in Composition Layer, you must supply an Element Factory to produce appropriate CompositionObject(s) to represent the series' visuals. Each series type requires a matching factory.

Animation Controller

To simplify integration of Composition Animations, you may supply (optional) an Animation Factory; this creates an IAnimationController responsible for managing and starting the different animations for:

  • Enter - component is appearing
  • Exit - component is disappearing
  • Offset - component is moving to a new offset
  • Transform - model transform is changing

Currently we only support Offset etc. because Opacity is a property of Visual and not CompositionShape.

The Default Animation Controller's enter and exit transitions use a "Spawn Point" which is the target of an Offset animation. The Spawn Point is chosen such that the element transitions to the nearest edge and out-of-view, e.g. a location outside of the axis extents. Spawn Points are in Model Space.

Series must establish a Clipping Rectangle if they wish to prevent elements from obscuring axes on the way in or out.

Operations

For consistency, operations should apply states in the same order:

  • Exit - must remove from visual tree. May trigger an animation beforehand.
  • Live - may update Offset etc. according to current position. May establish an animation.
    • May transition items to Entering or Exiting depending on ElementSelector
  • Enter - must add to visual tree. May establish an animation.

The default logic for processing operations follows this policy and handles all updates in a single pass.

Most operations reference one "end" of the element sequence:

  • Head - access the lowest-indexed end of the sequence, usually the "left" side.
  • Tail - access the highest-indexed end of the sequence, usually the "right" side.

The end selected determines the direction items translate, enter, and exit.

The list of DataSource operations follows:

  • Clear - Live items exit and chart is left empty.
  • Reset - Live items exit and new items enter.
  • Add - New items enter at the head or tail, as indicated.
  • Delete - count items exit from the head or tail, as indicated.
  • Sliding Window - Equal item count exit and enter at opposite ends, as indicated.

Item Sink

To keep you from doing "double-bookkeeping" maintaining your own copy of the chart's items, the DataSource.ItemSink dependency property allows you to attach a collection to receive the item updates as they are applied in the render pipeline. This way you have a copy of the items in the same order as they present in the chart.

Operation Complete

Rather than try to decipher ObservableCollection events or other indirect means, the DataSource.OperationComplete event gives you the "signal" (on the UI thread) that your operation has completed, and the chart state is now "stable" including the ItemSink contents. This is a good time to perform additional work based on the current chart contents, e.g., updating VM properties tied to ValueRule or ValueBand that is not series data.