1 /**
  2  * Constructs a new mark anchor with default properties.
  3  *
  4  * @class Represents an anchor on a given mark. An anchor is itself a mark, but
  5  * without a visual representation. It serves only to provide useful default
  6  * properties that can be inherited by other marks. Each type of mark can define
  7  * any number of named anchors for convenience. If the concrete mark type does
  8  * not define an anchor implementation specifically, one will be inherited from
  9  * the mark's parent class.
 10  *
 11  * <p>For example, the bar mark provides anchors for its four sides: left,
 12  * right, top and bottom. Adding a label to the top anchor of a bar,
 13  *
 14  * <pre>bar.anchor("top").add(pv.Label);</pre>
 15  *
 16  * will render a text label on the top edge of the bar; the top anchor defines
 17  * the appropriate position properties (top and left), as well as text-rendering
 18  * properties for convenience (textAlign and textBaseline).
 19  *
 20  * <p>Note that anchors do not <i>inherit</i> from their targets; the positional
 21  * properties are copied from the scene graph, which guarantees that the anchors
 22  * are positioned correctly, even if the positional properties are not defined
 23  * deterministically. (In addition, it also improves performance by avoiding
 24  * re-evaluating expensive properties.) If you want the anchor to inherit from
 25  * the target, use {@link pv.Mark#extend} before adding. For example:
 26  *
 27  * <pre>bar.anchor("top").extend(bar).add(pv.Label);</pre>
 28  *
 29  * The anchor defines it's own positional properties, but other properties (such
 30  * as the title property, say) can be inherited using the above idiom. Also note
 31  * that you can override positional properties in the anchor for custom
 32  * behavior.
 33  *
 34  * @extends pv.Mark
 35  * @param {pv.Mark} target the anchor target.
 36  */
 37 pv.Anchor = function(target) {
 38   pv.Mark.call(this);
 39   this.target = target;
 40   this.parent = target.parent;
 41 };
 42 
 43 pv.Anchor.prototype = pv.extend(pv.Mark)
 44     .property("name", String);
 45 
 46 /**
 47  * The anchor name. The set of supported anchor names is dependent on the
 48  * concrete mark type; see the mark type for details. For example, bars support
 49  * left, right, top and bottom anchors.
 50  *
 51  * <p>While anchor names are typically constants, the anchor name is a true
 52  * property, which means you can specify a function to compute the anchor name
 53  * dynamically. For instance, if you wanted to alternate top and bottom anchors,
 54  * saying
 55  *
 56  * <pre>m.anchor(function() (this.index % 2) ? "top" : "bottom").add(pv.Dot);</pre>
 57  *
 58  * would have the desired effect.
 59  *
 60  * @type string
 61  * @name pv.Anchor.prototype.name
 62  */
 63 
 64 /**
 65  * Returns the anchor target of this mark, if it is derived from an anchor;
 66  * otherwise returns null. For example, if a label is derived from a bar anchor,
 67  *
 68  * <pre>bar.anchor("top").add(pv.Label);</pre>
 69  *
 70  * then property functions on the label can refer to the bar via the
 71  * <tt>anchorTarget</tt> method. This method is also useful for mark types
 72  * defining properties on custom anchors.
 73  *
 74  * @returns {pv.Mark} the anchor target of this mark; possibly null.
 75  */
 76 pv.Anchor.prototype.anchorTarget = function() {
 77   return this.target;
 78 };
 79