1 /** 2 * Constructs a new bar mark with default properties. Bars 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 bar: an axis-aligned rectangle that can be stroked and 7 * filled. Bars are used for many chart types, including bar charts, histograms 8 * and Gantt charts. Bars can also be used as decorations, for example to draw a 9 * frame border around a panel; in fact, a panel is a special type (a subclass) 10 * of bar. 11 * 12 * <p>Bars can be positioned in several ways. Most commonly, one of the four 13 * corners is fixed using two margins, and then the width and height properties 14 * determine the extent of the bar relative to this fixed location. For example, 15 * using the bottom and left properties fixes the bottom-left corner; the width 16 * then extends to the right, while the height extends to the top. As an 17 * alternative to the four corners, a bar can be positioned exclusively using 18 * margins; this is convenient as an inset from the containing panel, for 19 * example. See {@link pv.Mark} for details on the prioritization of redundant 20 * positioning properties. 21 * 22 * <p>See also the <a href="../../api/Bar.html">Bar guide</a>. 23 * 24 * @extends pv.Mark 25 */ 26 pv.Bar = function() { 27 pv.Mark.call(this); 28 }; 29 30 pv.Bar.prototype = pv.extend(pv.Mark) 31 .property("width") 32 .property("height") 33 .property("lineWidth") 34 .property("strokeStyle") 35 .property("fillStyle"); 36 37 pv.Bar.prototype.type = "bar"; 38 39 /** 40 * The width of the bar, in pixels. If the left position is specified, the bar 41 * extends rightward from the left edge; if the right position is specified, the 42 * bar extends leftward from the right edge. 43 * 44 * @type number 45 * @name pv.Bar.prototype.width 46 */ 47 48 /** 49 * The height of the bar, in pixels. If the bottom position is specified, the 50 * bar extends upward from the bottom edge; if the top position is specified, 51 * the bar extends downward from the top edge. 52 * 53 * @type number 54 * @name pv.Bar.prototype.height 55 */ 56 57 /** 58 * The width of stroked lines, in pixels; used in conjunction with 59 * <tt>strokeStyle</tt> to stroke the bar's border. 60 * 61 * @type number 62 * @name pv.Bar.prototype.lineWidth 63 */ 64 65 /** 66 * The style of stroked lines; used in conjunction with <tt>lineWidth</tt> to 67 * stroke the bar's border. The default value of this property is null, meaning 68 * bars are not stroked by default. 69 * 70 * @type string 71 * @name pv.Bar.prototype.strokeStyle 72 * @see pv.color 73 */ 74 75 /** 76 * The bar fill style; if non-null, the interior of the bar is filled with the 77 * specified color. The default value of this property is a categorical color. 78 * 79 * @type string 80 * @name pv.Bar.prototype.fillStyle 81 * @see pv.color 82 */ 83 84 /** 85 * Default properties for bars. By default, there is no stroke and the fill 86 * style is a categorical color. 87 * 88 * @type pv.Bar 89 */ 90 pv.Bar.prototype.defaults = new pv.Bar() 91 .extend(pv.Mark.prototype.defaults) 92 .lineWidth(1.5) 93 .fillStyle(defaultFillStyle); 94 95 /** 96 * Constructs a new bar anchor with default properties. Bars support five 97 * different anchors:<ul> 98 * 99 * <li>top 100 * <li>left 101 * <li>center 102 * <li>bottom 103 * <li>right 104 * 105 * </ul>In addition to positioning properties (left, right, top bottom), the 106 * anchors support text rendering properties (text-align, text-baseline). Text 107 * is rendered to appear inside the bar. 108 * 109 * <p>To facilitate stacking of bars, the anchors are defined in terms of their 110 * opposite edge. For example, the top anchor defines the bottom property, such 111 * that the bar grows upwards; the bottom anchor instead defines the top 112 * property, such that the bar grows downwards. Of course, in general it is more 113 * robust to use panels and the cousin accessor to define stacked bars; see 114 * {@link pv.Mark#scene} for an example. 115 * 116 * <p>Bar anchors also "smartly" specify position properties based on whether 117 * the derived mark type supports the width and height properties. If the 118 * derived mark type does not support these properties (e.g., dots), the 119 * position will be centered on the corresponding edge. Otherwise (e.g., bars), 120 * the position will be in the opposite side. 121 * 122 * @param {string} name the anchor name; either a string or a property function. 123 * @returns {pv.Anchor} 124 */ 125 pv.Bar.prototype.anchor = function(name) { 126 var bar = this; 127 return pv.Mark.prototype.anchor.call(this, name) 128 .left(function() { 129 switch (this.name()) { 130 case "bottom": 131 case "top": 132 case "center": return bar.left() + (this.properties.width ? 0 : (bar.width() / 2)); 133 case "right": return bar.left() + bar.width(); 134 } 135 return null; 136 }) 137 .right(function() { 138 switch (this.name()) { 139 case "bottom": 140 case "top": 141 case "center": return bar.right() + (this.properties.width ? 0 : (bar.width() / 2)); 142 case "left": return bar.right() + bar.width(); 143 } 144 return null; 145 }) 146 .top(function() { 147 switch (this.name()) { 148 case "left": 149 case "right": 150 case "center": return bar.top() + (this.properties.height ? 0 : (bar.height() / 2)); 151 case "bottom": return bar.top() + bar.height(); 152 } 153 return null; 154 }) 155 .bottom(function() { 156 switch (this.name()) { 157 case "left": 158 case "right": 159 case "center": return bar.bottom() + (this.properties.height ? 0 : (bar.height() / 2)); 160 case "top": return bar.bottom() + bar.height(); 161 } 162 return null; 163 }) 164 .textAlign(function() { 165 switch (this.name()) { 166 case "bottom": 167 case "top": 168 case "center": return "center"; 169 case "right": return "right"; 170 } 171 return "left"; 172 }) 173 .textBaseline(function() { 174 switch (this.name()) { 175 case "right": 176 case "left": 177 case "center": return "middle"; 178 case "top": return "top"; 179 } 180 return "bottom"; 181 }); 182 }; 183