Version 3.18.1
Show:

File: charts/js/BottomAxisLayout.js

            /**
             * Contains algorithms for rendering a bottom axis.
             *
             * @class BottomAxisLayout
             * @Constructor
             * @submodule axis
             */
            BottomAxisLayout = function(){};
            
            BottomAxisLayout.prototype = {
                /**
                 *  Default margins for text fields.
                 *
                 *  @private
                 *  @method _getDefaultMargins
                 *  @return Object
                 */
                _getDefaultMargins: function()
                {
                    return {
                        top: 4,
                        left: 0,
                        right: 0,
                        bottom: 0
                    };
                },
            
                /**
                 * Sets the length of the tick on either side of the axis line.
                 *
                 * @method setTickOffsets
                 * @protected
                 */
                setTickOffsets: function()
                {
                    var host = this,
                        majorTicks = host.get("styles").majorTicks,
                        tickLength = majorTicks.length,
                        halfTick = tickLength * 0.5,
                        display = majorTicks.display;
                    host.set("leftTickOffset",  0);
                    host.set("rightTickOffset",  0);
            
                    switch(display)
                    {
                        case "inside" :
                            host.set("topTickOffset", tickLength);
                            host.set("bottomTickOffset", 0);
                        break;
                        case "outside" :
                            host.set("topTickOffset", 0);
                            host.set("bottomTickOffset", tickLength);
                        break;
                        case "cross":
                            host.set("topTickOffset",  halfTick);
                            host.set("bottomTickOffset",  halfTick);
                        break;
                        default:
                            host.set("topTickOffset", 0);
                            host.set("bottomTickOffset", 0);
                        break;
                    }
                },
            
                /**
                 * Calculates the coordinates for the first point on an axis.
                 *
                 * @method getLineStart
                 * @protected
                 */
                getLineStart: function()
                {
                    var style = this.get("styles"),
                        padding = style.padding,
                        majorTicks = style.majorTicks,
                        tickLength = majorTicks.length,
                        display = majorTicks.display,
                        pt = {x:0, y:padding.top};
                    if(display === "inside")
                    {
                        pt.y += tickLength;
                    }
                    else if(display === "cross")
                    {
                        pt.y += tickLength/2;
                    }
                    return pt;
                },
            
                /**
                 * Draws a tick
                 *
                 * @method drawTick
                 * @param {Path} path reference to the path `Path` element in which to draw the tick.
                 * @param {Object} pt hash containing x and y coordinates
                 * @param {Object} tickStyles hash of properties used to draw the tick
                 * @protected
                 */
                drawTick: function(path, pt, tickStyles)
                {
                    var host = this,
                        style = host.get("styles"),
                        padding = style.padding,
                        tickLength = tickStyles.length,
                        start = {x:pt.x, y:padding.top},
                        end = {x:pt.x, y:tickLength + padding.top};
                    host.drawLine(path, start, end);
                },
            
                /**
                 * Calculates the point for a label.
                 *
                 * @method getLabelPoint
                 * @param {Object} pt Object containing x and y coordinates
                 * @return Object
                 * @protected
                 */
                getLabelPoint: function(point)
                {
                    return {x:point.x, y:point.y + this.get("bottomTickOffset")};
                },
            
                /**
                 * Updates the value for the `maxLabelSize` for use in calculating total size.
                 *
                 * @method updateMaxLabelSize
                 * @param {HTMLElement} label to measure
                 * @protected
                 */
                updateMaxLabelSize: function(labelWidth, labelHeight)
                {
                    var host = this,
                        props = this._labelRotationProps,
                        rot = props.rot,
                        absRot = props.absRot,
                        sinRadians = props.sinRadians,
                        cosRadians = props.cosRadians,
                        max;
                    if(rot === 0)
                    {
                        max = labelHeight;
                    }
                    else if(absRot === 90)
                    {
                        max = labelWidth;
                    }
                    else
                    {
                        max = (sinRadians * labelWidth) + (cosRadians * labelHeight);
                    }
                    host._maxLabelSize = Math.max(host._maxLabelSize, max);
                },
            
                /**
                 * Determines the available label height when the axis width has been explicitly set.
                 *
                 * @method getExplicitlySized
                 * @return Boolean
                 * @protected
                 */
                getExplicitlySized: function(styles)
                {
                    if(this._explicitHeight)
                    {
                        var host = this,
                            h = host._explicitHeight,
                            totalTitleSize = host._totalTitleSize,
                            bottomTickOffset = host.get("bottomTickOffset"),
                            margin = styles.label.margin.right;
                        host._maxLabelSize =  h - (bottomTickOffset + margin + totalTitleSize);
                        return true;
                    }
                    return false;
                },
            
                /**
                 * Rotate and position title.
                 *
                 * @method positionTitle
                 * @param {HTMLElement} label to rotate position
                 * @protected
                 */
                positionTitle: function(label)
                {
                    var host = this,
                        bounds = host._titleBounds,
                        margin = host.get("styles").title.margin,
                        props = host._titleRotationProps,
                        h = bounds.bottom - bounds.top,
                        labelWidth = label.offsetWidth,
                        labelHeight = label.offsetHeight,
                        x = (host.get("width") * 0.5) - (labelWidth * 0.5),
                        y = host.get("height") - labelHeight/2 - h/2;
                    props.labelWidth = labelWidth;
                    props.labelHeight = labelHeight;
                    if(margin && margin.bottom)
                    {
                        y -= margin.bottom;
                    }
                    props.x = x;
                    props.y = y;
                    props.transformOrigin = [0.5, 0.5];
                    host._rotate(label, props);
                },
            
                /**
                 * Rotate and position labels.
                 *
                 * @method positionLabel
                 * @param {HTMLElement} label to rotate position
                 * @param {Object} pt hash containing the x and y coordinates in which the label will be positioned
                 * against.
                 * @protected
                 */
                positionLabel: function(label, pt, styles, i)
                {
                    var host = this,
                        offset = parseFloat(styles.label.offset),
                        tickOffset = host.get("bottomTickOffset"),
                        labelStyles = styles.label,
                        margin = 0,
                        props = host._labelRotationProps,
                        rot = props.rot,
                        absRot = props.absRot,
                        leftOffset = Math.round(pt.x),
                        topOffset = Math.round(pt.y),
                        labelWidth = host._labelWidths[i],
                        labelHeight = host._labelHeights[i];
                    if(labelStyles.margin && labelStyles.margin.top)
                    {
                        margin = labelStyles.margin.top;
                    }
                    if(rot === 90)
                    {
                        topOffset -= labelHeight/2 * rot/90;
                        leftOffset = leftOffset + labelHeight/2 - (labelHeight * offset);
                    }
                    else if(rot === -90)
                    {
                        topOffset -= labelHeight/2 * absRot/90;
                        leftOffset = leftOffset - labelWidth + labelHeight/2 - (labelHeight * offset);
                    }
                    else if(rot > 0)
                    {
                        leftOffset = leftOffset + labelHeight/2 - (labelHeight * offset);
                        topOffset -= labelHeight/2 * rot/90;
                    }
                    else if(rot < 0)
                    {
                        leftOffset = leftOffset - labelWidth + labelHeight/2 - (labelHeight * offset);
                        topOffset -= labelHeight/2 * absRot/90;
                    }
                    else
                    {
                        leftOffset -= labelWidth * offset;
                    }
                    topOffset += margin;
                    topOffset += tickOffset;
                    props.labelWidth = labelWidth;
                    props.labelHeight = labelHeight;
                    props.x = leftOffset;
                    props.y = topOffset;
                    host._rotate(label, props);
                },
            
                /**
                 * Adjusts the coordinates of an axis label based on the rotation.
                 *
                 * @method _setRotationCoords
                 * @param {Object} props Coordinates, dimension and rotation properties of the label.
                 * @protected
                 */
                _setRotationCoords: function(props)
                {
                    var rot = props.rot,
                        absRot = props.absRot,
                        labelWidth = props.labelWidth,
                        labelHeight = props.labelHeight,
                        leftOffset,
                        topOffset;
            
                    if(rot > 0)
                    {
                        leftOffset = 0;
                        topOffset = labelHeight/2 * rot/90;
                    }
                    else if(rot < 0)
                    {
                        leftOffset = labelWidth;
                        topOffset = labelHeight/2 * absRot/90;
                    }
                    else
                    {
                        leftOffset = labelWidth * 0.5;
                        topOffset = 0;
                    }
                    props.x -= leftOffset;
                    props.y -= topOffset;
                },
            
                /**
                 * Returns the transformOrigin to use for an axis label based on the position of the axis
                 * and the rotation of the label.
                 *
                 * @method _getTransformOrigin
                 * @param {Number} rot The rotation (in degrees) of the label.
                 * @return Array
                 * @protected
                 */
                _getTransformOrigin: function(rot)
                {
                    var transformOrigin;
                    if(rot > 0)
                    {
                        transformOrigin = [0, 0.5];
                    }
                    else if(rot < 0)
                    {
                        transformOrigin = [1, 0.5];
                    }
                    else
                    {
                        transformOrigin = [0, 0];
                    }
                    return transformOrigin;
                },
            
                /**
                 * Adjusts position for inner ticks.
                 *
                 * @method offsetNodeForTick
                 * @param {Node} cb contentBox of the axis
                 * @protected
                 */
                offsetNodeForTick: function(cb)
                {
                    var host = this;
                    cb.setStyle("top", 0 - host.get("topTickOffset"));
                },
            
                /**
                 * Assigns a height based on the size of the contents.
                 *
                 * @method setCalculatedSize
                 * @protected
                 */
                setCalculatedSize: function()
                {
                    var host = this,
                        styles = host.get("styles"),
                        labelStyle = styles.label,
                        totalTitleSize = host._totalTitleSize,
                        ttl = Math.round(host.get("bottomTickOffset") + host._maxLabelSize + labelStyle.margin.top + totalTitleSize);
                    if(host._explicitHeight)
                    {
                        ttl = host._explicitHeight;
                    }
                    host.set("calculatedHeight", ttl);
                }
            };
            Y.BottomAxisLayout = BottomAxisLayout;