Interface Drawing

All Known Implementing Classes:
UnplannedDrawing

public interface Drawing
Does the work of drawing graphics onto a given Paper object.

The drawing operation is separated into two parts: calculating the Plan, and using that plan to do the drawing. There are two purposes to this. First, calculating the plan is a thread-safe operation, while the actual drawing may not be done at the same time as other drawing operations on the same Paper object, so calculating plans separately offers opportunities for concurrency which would not be available if drawing was monolithic. Second, the plan may be reusable between different Drawing instances. Calling code may cache plans so that they do not need to be calculated every time if changes to a plot are made which do not affect a given drawing (for instance, other layers are changed).

It is worthwhile for a Drawing implementation to perform this split into two parts only if the plan calculation is a time-consuming operation that may conveniently be separated from actual drawing. If not, it's OK to return null from calculatePlan(java.lang.Object[], uk.ac.starlink.ttools.plot2.data.DataStore).

As a general rule, we calculate plans where the work required scales with dataset size (number of points plotted), but not where it scales with plot size (number of pixels on screen). The plan/plot mechanism is really intended to cope with potentially rather slow plots (millions of rows) rather than to make normal plots run extra fast. But you can break this rule if you like.

Since:
11 Feb 2013
Author:
Mark Taylor
  • Method Details

    • calculatePlan

      @Slow Object calculatePlan(Object[] knownPlans, DataStore dataStore)
      Performs preparation for the actual drawing. Calling this method has no side effects, and it may be called in any thread without concurrency implications. If separate plan calculation is not useful, it's OK to return null.

      The knownPlans argument may offer a selection of pre-calculated plans that the calling code may have cached. Implementations may examine these to see whether one of them is the answer to the question being asked, and if so return it without further work.

      Parameters:
      knownPlans - list of zero or more plans that may have been previously calculated by this class
      dataStore - data-bearing object
      Returns:
      plan to present to the paintData method
    • paintData

      @Slow void paintData(Object plan, Paper paper, DataStore dataStore)
      Performs the actual drawing. The plan argument must be the result of an earlier call to this object's calculatePlan(java.lang.Object[], uk.ac.starlink.ttools.plot2.data.DataStore) method using the same data store. The paper argument must in general be of a particular type, according to how this drawing was generated. Usually, this drawing object will own a PaperType instance which can be used to paint to the supplied paper object.

      This method must not be called concurrently with other objects drawing to the same paper.

      Parameters:
      plan - drawing plan, from calculatePlan
      paper - graphics destination
      dataStore - data-bearing object
    • getReport

      ReportMap getReport(Object plan)
      Obtains information associated with the plot. The plan argument must be the result of an earlier call to this object's calculatePlan(java.lang.Object[], uk.ac.starlink.ttools.plot2.data.DataStore) method. The hasReports method of the corresponding Plotter indicates whether the return value may contain general-interest reports; special-purpose reports may be returned in any case.

      If there is nothing interesting to report, which will often be the case, the return value may be null, which is shorthand for an empty map.

      This ought not to be an expensive operation.

      Parameters:
      plan - drawing plan, from calculatePlan
      Returns:
      information generated by the plot, or null
      See Also: