1 /** 2 * Constructs a new line mark with default properties. Lines are not typically 3 * constructed directly, but by adding to a panel or an existing mark via 4 * {@link pv.Mark#add}. 5 * 6 * @class Represents a series of connected line segments, or <i>polyline</i>, 7 * that can be stroked with a configurable color and thickness. Each 8 * articulation point in the line corresponds to a datum; for <i>n</i> points, 9 * <i>n</i>-1 connected line segments are drawn. The point is positioned using 10 * the box model. Arbitrary paths are also possible, allowing radar plots and 11 * other custom visualizations. 12 * 13 * <p>Like areas, lines can be stroked and filled with arbitrary colors. In most 14 * cases, lines are only stroked, but the fill style can be used to construct 15 * arbitrary polygons. 16 * 17 * <p>See also the <a href="../../api/Line.html">Line guide</a>. 18 * 19 * @extends pv.Mark 20 */ 21 pv.Line = function() { 22 pv.Mark.call(this); 23 }; 24 25 pv.Line.prototype = pv.extend(pv.Mark) 26 .property("lineWidth", Number) 27 .property("lineJoin", String) 28 .property("strokeStyle", pv.color) 29 .property("fillStyle", pv.color) 30 .property("segmented", Boolean) 31 .property("interpolate", String) 32 .property("eccentricity", Number) 33 .property("tension", Number); 34 35 pv.Line.prototype.type = "line"; 36 37 /** 38 * The width of stroked lines, in pixels; used in conjunction with 39 * <tt>strokeStyle</tt> to stroke the line. 40 * 41 * @type number 42 * @name pv.Line.prototype.lineWidth 43 */ 44 45 /** 46 * The style of stroked lines; used in conjunction with <tt>lineWidth</tt> to 47 * stroke the line. The default value of this property is a categorical color. 48 * 49 * @type string 50 * @name pv.Line.prototype.strokeStyle 51 * @see pv.color 52 */ 53 54 /** 55 * The type of corners where two lines meet. Accepted values are "bevel", 56 * "round" and "miter". The default value is "miter". 57 * 58 * <p>For segmented lines, only "miter" joins and "linear" interpolation are 59 * currently supported. Any other value, including null, will disable joins, 60 * producing disjoint line segments. Note that the miter joins must be computed 61 * manually (at least in the current SVG renderer); since this calculation may 62 * be expensive and unnecessary for small lines, specifying null can improve 63 * performance significantly. 64 * 65 * <p>This property is <i>fixed</i>. See {@link pv.Mark}. 66 * 67 * @type string 68 * @name pv.Line.prototype.lineJoin 69 */ 70 71 /** 72 * The line fill style; if non-null, the interior of the line is closed and 73 * filled with the specified color. The default value of this property is a 74 * null, meaning that lines are not filled by default. 75 * 76 * <p>This property is <i>fixed</i>. See {@link pv.Mark}. 77 * 78 * @type string 79 * @name pv.Line.prototype.fillStyle 80 * @see pv.color 81 */ 82 83 /** 84 * Whether the line is segmented; whether variations in stroke style, line width 85 * and the other properties are treated as fixed. Rendering segmented lines is 86 * noticeably slower than non-segmented lines. 87 * 88 * <p>This property is <i>fixed</i>. See {@link pv.Mark}. 89 * 90 * @type boolean 91 * @name pv.Line.prototype.segmented 92 */ 93 94 /** 95 * How to interpolate between values. Linear interpolation ("linear") is the 96 * default, producing a straight line between points. For piecewise constant 97 * functions (i.e., step functions), either "step-before" or "step-after" can be 98 * specified. To draw a clockwise circular arc between points, specify "polar"; 99 * to draw a counterclockwise circular arc between points, specify 100 * "polar-reverse". To draw open uniform b-splines, specify "basis". To draw 101 * cardinal splines, specify "cardinal"; see also {@link #tension}. 102 * 103 * <p>This property is <i>fixed</i>. See {@link pv.Mark}. 104 * 105 * @type string 106 * @name pv.Line.prototype.interpolate 107 */ 108 109 /** 110 * The eccentricity of polar line segments; used in conjunction with 111 * interpolate("polar"). The default value of 0 means that line segments are 112 * drawn as circular arcs. A value of 1 draws a straight line. A value between 0 113 * and 1 draws an elliptical arc with the given eccentricity. 114 * 115 * @type number 116 * @name pv.Line.prototype.eccentricity 117 */ 118 119 /** 120 * The tension of cardinal splines; used in conjunction with 121 * interpolate("cardinal"). A value between 0 and 1 draws cardinal splines with 122 * the given tension. In some sense, the tension can be interpreted as the 123 * "length" of the tangent; a tension of 1 will yield all zero tangents (i.e., 124 * linear interpolation), and a tension of 0 yields a Catmull-Rom spline. The 125 * default value is 0.7. 126 * 127 * <p>This property is <i>fixed</i>. See {@link pv.Mark}. 128 * 129 * @type number 130 * @name pv.Line.prototype.tension 131 */ 132 133 /** 134 * Default properties for lines. By default, there is no fill and the stroke 135 * style is a categorical color. The default interpolation is linear. 136 * 137 * @type pv.Line 138 */ 139 pv.Line.prototype.defaults = new pv.Line() 140 .extend(pv.Mark.prototype.defaults) 141 .lineJoin("miter") 142 .lineWidth(1.5) 143 .strokeStyle(pv.Colors.category10().by(pv.parent)) 144 .interpolate("linear") 145 .eccentricity(0) 146 .tension(.7); 147 148 /** @private Reuse Area's implementation for segmented bind & build. */ 149 pv.Line.prototype.bind = pv.Area.prototype.bind; 150 pv.Line.prototype.buildInstance = pv.Area.prototype.buildInstance; 151 152 /** 153 * Constructs a new line anchor with default properties. Lines support five 154 * different anchors:<ul> 155 * 156 * <li>top 157 * <li>left 158 * <li>center 159 * <li>bottom 160 * <li>right 161 * 162 * </ul>In addition to positioning properties (left, right, top bottom), the 163 * anchors support text rendering properties (text-align, text-baseline). Text is 164 * rendered to appear outside the line. Note that this behavior is different 165 * from other mark anchors, which default to rendering text <i>inside</i> the 166 * mark. 167 * 168 * <p>For consistency with the other mark types, the anchor positions are 169 * defined in terms of their opposite edge. For example, the top anchor defines 170 * the bottom property, such that a bar added to the top anchor grows upward. 171 * 172 * @param {string} name the anchor name; either a string or a property function. 173 * @returns {pv.Anchor} 174 */ 175 pv.Line.prototype.anchor = function(name) { 176 return pv.Area.prototype.anchor.call(this, name) 177 .textAlign(function(d) { 178 switch (this.name()) { 179 case "left": return "right"; 180 case "bottom": 181 case "top": 182 case "center": return "center"; 183 case "right": return "left"; 184 } 185 }) 186 .textBaseline(function(d) { 187 switch (this.name()) { 188 case "right": 189 case "left": 190 case "center": return "middle"; 191 case "top": return "bottom"; 192 case "bottom": return "top"; 193 } 194 }); 195 }; 196