--- /dev/null
+<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-chart.axis.Axis'>/**
+</span> * @class Ext.chart.axis.Axis
+ * @extends Ext.chart.axis.Abstract
+ *
+ * Defines axis for charts. The axis position, type, style can be configured.
+ * The axes are defined in an axes array of configuration objects where the type,
+ * field, grid and other configuration options can be set. To know more about how
+ * to create a Chart please check the Chart class documentation. Here's an example for the axes part:
+ * An example of axis for a series (in this case for an area chart that has multiple layers of yFields) could be:
+ *
+ * axes: [{
+ * type: 'Numeric',
+ * grid: true,
+ * position: 'left',
+ * fields: ['data1', 'data2', 'data3'],
+ * title: 'Number of Hits',
+ * grid: {
+ * odd: {
+ * opacity: 1,
+ * fill: '#ddd',
+ * stroke: '#bbb',
+ * 'stroke-width': 1
+ * }
+ * },
+ * minimum: 0
+ * }, {
+ * type: 'Category',
+ * position: 'bottom',
+ * fields: ['name'],
+ * title: 'Month of the Year',
+ * grid: true,
+ * label: {
+ * rotate: {
+ * degrees: 315
+ * }
+ * }
+ * }]
+ *
+ * In this case we use a `Numeric` axis for displaying the values of the Area series and a `Category` axis for displaying the names of
+ * the store elements. The numeric axis is placed on the left of the screen, while the category axis is placed at the bottom of the chart.
+ * Both the category and numeric axes have `grid` set, which means that horizontal and vertical lines will cover the chart background. In the
+ * category axis the labels will be rotated so they can fit the space better.
+ */
+Ext.define('Ext.chart.axis.Axis', {
+
+ /* Begin Definitions */
+
+ extend: 'Ext.chart.axis.Abstract',
+
+ alternateClassName: 'Ext.chart.Axis',
+
+ requires: ['Ext.draw.Draw'],
+
+ /* End Definitions */
+
+<span id='Ext-chart.axis.Axis-cfg-majorTickSteps'> /**
+</span> * @cfg {Number} majorTickSteps
+ * If `minimum` and `maximum` are specified it forces the number of major ticks to the specified value.
+ */
+
+<span id='Ext-chart.axis.Axis-cfg-minorTickSteps'> /**
+</span> * @cfg {Number} minorTickSteps
+ * The number of small ticks between two major ticks. Default is zero.
+ */
+
+<span id='Ext-chart.axis.Axis-cfg-dashSize'> /**
+</span> * @cfg {Number} dashSize
+ * The size of the dash marker. Default's 3.
+ */
+ dashSize: 3,
+
+<span id='Ext-chart.axis.Axis-cfg-position'> /**
+</span> * @cfg {String} position
+ * Where to set the axis. Available options are `left`, `bottom`, `right`, `top`. Default's `bottom`.
+ */
+ position: 'bottom',
+
+ // @private
+ skipFirst: false,
+
+<span id='Ext-chart.axis.Axis-cfg-length'> /**
+</span> * @cfg {Number} length
+ * Offset axis position. Default's 0.
+ */
+ length: 0,
+
+<span id='Ext-chart.axis.Axis-cfg-width'> /**
+</span> * @cfg {Number} width
+ * Offset axis width. Default's 0.
+ */
+ width: 0,
+
+ majorTickSteps: false,
+
+ // @private
+ applyData: Ext.emptyFn,
+
+ // @private creates a structure with start, end and step points.
+ calcEnds: function() {
+ var me = this,
+ math = Math,
+ mmax = math.max,
+ mmin = math.min,
+ store = me.chart.substore || me.chart.store,
+ series = me.chart.series.items,
+ fields = me.fields,
+ ln = fields.length,
+ min = isNaN(me.minimum) ? Infinity : me.minimum,
+ max = isNaN(me.maximum) ? -Infinity : me.maximum,
+ prevMin = me.prevMin,
+ prevMax = me.prevMax,
+ aggregate = false,
+ total = 0,
+ excludes = [],
+ outfrom, outto,
+ i, l, values, rec, out;
+
+ //if one series is stacked I have to aggregate the values
+ //for the scale.
+ for (i = 0, l = series.length; !aggregate && i < l; i++) {
+ aggregate = aggregate || series[i].stacked;
+ excludes = series[i].__excludes || excludes;
+ }
+ store.each(function(record) {
+ if (aggregate) {
+ if (!isFinite(min)) {
+ min = 0;
+ }
+ for (values = [0, 0], i = 0; i < ln; i++) {
+ if (excludes[i]) {
+ continue;
+ }
+ rec = record.get(fields[i]);
+ values[+(rec > 0)] += math.abs(rec);
+ }
+ max = mmax(max, -values[0], values[1]);
+ min = mmin(min, -values[0], values[1]);
+ }
+ else {
+ for (i = 0; i < ln; i++) {
+ if (excludes[i]) {
+ continue;
+ }
+ value = record.get(fields[i]);
+ max = mmax(max, value);
+ min = mmin(min, value);
+ }
+ }
+ });
+ if (!isFinite(max)) {
+ max = me.prevMax || 0;
+ }
+ if (!isFinite(min)) {
+ min = me.prevMin || 0;
+ }
+ //normalize min max for snapEnds.
+ if (min != max && (max != (max >> 0))) {
+ max = (max >> 0) + 1;
+ }
+ out = Ext.draw.Draw.snapEnds(min, max, me.majorTickSteps !== false ? (me.majorTickSteps +1) : me.steps);
+ outfrom = out.from;
+ outto = out.to;
+ if (!isNaN(me.maximum)) {
+ //TODO(nico) users are responsible for their own minimum/maximum values set.
+ //Clipping should be added to remove lines in the chart which are below the axis.
+ out.to = me.maximum;
+ }
+ if (!isNaN(me.minimum)) {
+ //TODO(nico) users are responsible for their own minimum/maximum values set.
+ //Clipping should be added to remove lines in the chart which are below the axis.
+ out.from = me.minimum;
+ }
+
+ //Adjust after adjusting minimum and maximum
+ out.step = (out.to - out.from) / (outto - outfrom) * out.step;
+
+ if (me.adjustMaximumByMajorUnit) {
+ out.to += out.step;
+ }
+ if (me.adjustMinimumByMajorUnit) {
+ out.from -= out.step;
+ }
+ me.prevMin = min == max? 0 : min;
+ me.prevMax = max;
+ return out;
+ },
+
+<span id='Ext-chart.axis.Axis-method-drawAxis'> /**
+</span> * Renders the axis into the screen and updates it's position.
+ */
+ drawAxis: function (init) {
+ var me = this,
+ i, j,
+ x = me.x,
+ y = me.y,
+ gutterX = me.chart.maxGutter[0],
+ gutterY = me.chart.maxGutter[1],
+ dashSize = me.dashSize,
+ subDashesX = me.minorTickSteps || 0,
+ subDashesY = me.minorTickSteps || 0,
+ length = me.length,
+ position = me.position,
+ inflections = [],
+ calcLabels = false,
+ stepCalcs = me.applyData(),
+ step = stepCalcs.step,
+ steps = stepCalcs.steps,
+ from = stepCalcs.from,
+ to = stepCalcs.to,
+ trueLength,
+ currentX,
+ currentY,
+ path,
+ prev,
+ dashesX,
+ dashesY,
+ delta;
+
+ //If no steps are specified
+ //then don't draw the axis. This generally happens
+ //when an empty store.
+ if (me.hidden || isNaN(step) || (from == to)) {
+ return;
+ }
+
+ me.from = stepCalcs.from;
+ me.to = stepCalcs.to;
+ if (position == 'left' || position == 'right') {
+ currentX = Math.floor(x) + 0.5;
+ path = ["M", currentX, y, "l", 0, -length];
+ trueLength = length - (gutterY * 2);
+ }
+ else {
+ currentY = Math.floor(y) + 0.5;
+ path = ["M", x, currentY, "l", length, 0];
+ trueLength = length - (gutterX * 2);
+ }
+
+ delta = trueLength / (steps || 1);
+ dashesX = Math.max(subDashesX +1, 0);
+ dashesY = Math.max(subDashesY +1, 0);
+ if (me.type == 'Numeric') {
+ calcLabels = true;
+ me.labels = [stepCalcs.from];
+ }
+ if (position == 'right' || position == 'left') {
+ currentY = y - gutterY;
+ currentX = x - ((position == 'left') * dashSize * 2);
+ while (currentY >= y - gutterY - trueLength) {
+ path.push("M", currentX, Math.floor(currentY) + 0.5, "l", dashSize * 2 + 1, 0);
+ if (currentY != y - gutterY) {
+ for (i = 1; i < dashesY; i++) {
+ path.push("M", currentX + dashSize, Math.floor(currentY + delta * i / dashesY) + 0.5, "l", dashSize + 1, 0);
+ }
+ }
+ inflections.push([ Math.floor(x), Math.floor(currentY) ]);
+ currentY -= delta;
+ if (calcLabels) {
+ me.labels.push(me.labels[me.labels.length -1] + step);
+ }
+ if (delta === 0) {
+ break;
+ }
+ }
+ if (Math.round(currentY + delta - (y - gutterY - trueLength))) {
+ path.push("M", currentX, Math.floor(y - length + gutterY) + 0.5, "l", dashSize * 2 + 1, 0);
+ for (i = 1; i < dashesY; i++) {
+ path.push("M", currentX + dashSize, Math.floor(y - length + gutterY + delta * i / dashesY) + 0.5, "l", dashSize + 1, 0);
+ }
+ inflections.push([ Math.floor(x), Math.floor(currentY) ]);
+ if (calcLabels) {
+ me.labels.push(me.labels[me.labels.length -1] + step);
+ }
+ }
+ } else {
+ currentX = x + gutterX;
+ currentY = y - ((position == 'top') * dashSize * 2);
+ while (currentX <= x + gutterX + trueLength) {
+ path.push("M", Math.floor(currentX) + 0.5, currentY, "l", 0, dashSize * 2 + 1);
+ if (currentX != x + gutterX) {
+ for (i = 1; i < dashesX; i++) {
+ path.push("M", Math.floor(currentX - delta * i / dashesX) + 0.5, currentY, "l", 0, dashSize + 1);
+ }
+ }
+ inflections.push([ Math.floor(currentX), Math.floor(y) ]);
+ currentX += delta;
+ if (calcLabels) {
+ me.labels.push(me.labels[me.labels.length -1] + step);
+ }
+ if (delta === 0) {
+ break;
+ }
+ }
+ if (Math.round(currentX - delta - (x + gutterX + trueLength))) {
+ path.push("M", Math.floor(x + length - gutterX) + 0.5, currentY, "l", 0, dashSize * 2 + 1);
+ for (i = 1; i < dashesX; i++) {
+ path.push("M", Math.floor(x + length - gutterX - delta * i / dashesX) + 0.5, currentY, "l", 0, dashSize + 1);
+ }
+ inflections.push([ Math.floor(currentX), Math.floor(y) ]);
+ if (calcLabels) {
+ me.labels.push(me.labels[me.labels.length -1] + step);
+ }
+ }
+ }
+ if (!me.axis) {
+ me.axis = me.chart.surface.add(Ext.apply({
+ type: 'path',
+ path: path
+ }, me.axisStyle));
+ }
+ me.axis.setAttributes({
+ path: path
+ }, true);
+ me.inflections = inflections;
+ if (!init && me.grid) {
+ me.drawGrid();
+ }
+ me.axisBBox = me.axis.getBBox();
+ me.drawLabel();
+ },
+
+<span id='Ext-chart.axis.Axis-method-drawGrid'> /**
+</span> * Renders an horizontal and/or vertical grid into the Surface.
+ */
+ drawGrid: function() {
+ var me = this,
+ surface = me.chart.surface,
+ grid = me.grid,
+ odd = grid.odd,
+ even = grid.even,
+ inflections = me.inflections,
+ ln = inflections.length - ((odd || even)? 0 : 1),
+ position = me.position,
+ gutter = me.chart.maxGutter,
+ width = me.width - 2,
+ vert = false,
+ point, prevPoint,
+ i = 1,
+ path = [], styles, lineWidth, dlineWidth,
+ oddPath = [], evenPath = [];
+
+ if ((gutter[1] !== 0 && (position == 'left' || position == 'right')) ||
+ (gutter[0] !== 0 && (position == 'top' || position == 'bottom'))) {
+ i = 0;
+ ln++;
+ }
+ for (; i < ln; i++) {
+ point = inflections[i];
+ prevPoint = inflections[i - 1];
+ if (odd || even) {
+ path = (i % 2)? oddPath : evenPath;
+ styles = ((i % 2)? odd : even) || {};
+ lineWidth = (styles.lineWidth || styles['stroke-width'] || 0) / 2;
+ dlineWidth = 2 * lineWidth;
+ if (position == 'left') {
+ path.push("M", prevPoint[0] + 1 + lineWidth, prevPoint[1] + 0.5 - lineWidth,
+ "L", prevPoint[0] + 1 + width - lineWidth, prevPoint[1] + 0.5 - lineWidth,
+ "L", point[0] + 1 + width - lineWidth, point[1] + 0.5 + lineWidth,
+ "L", point[0] + 1 + lineWidth, point[1] + 0.5 + lineWidth, "Z");
+ }
+ else if (position == 'right') {
+ path.push("M", prevPoint[0] - lineWidth, prevPoint[1] + 0.5 - lineWidth,
+ "L", prevPoint[0] - width + lineWidth, prevPoint[1] + 0.5 - lineWidth,
+ "L", point[0] - width + lineWidth, point[1] + 0.5 + lineWidth,
+ "L", point[0] - lineWidth, point[1] + 0.5 + lineWidth, "Z");
+ }
+ else if (position == 'top') {
+ path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + lineWidth,
+ "L", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + width - lineWidth,
+ "L", point[0] + 0.5 - lineWidth, point[1] + 1 + width - lineWidth,
+ "L", point[0] + 0.5 - lineWidth, point[1] + 1 + lineWidth, "Z");
+ }
+ else {
+ path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - lineWidth,
+ "L", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - width + lineWidth,
+ "L", point[0] + 0.5 - lineWidth, point[1] - width + lineWidth,
+ "L", point[0] + 0.5 - lineWidth, point[1] - lineWidth, "Z");
+ }
+ } else {
+ if (position == 'left') {
+ path = path.concat(["M", point[0] + 0.5, point[1] + 0.5, "l", width, 0]);
+ }
+ else if (position == 'right') {
+ path = path.concat(["M", point[0] - 0.5, point[1] + 0.5, "l", -width, 0]);
+ }
+ else if (position == 'top') {
+ path = path.concat(["M", point[0] + 0.5, point[1] + 0.5, "l", 0, width]);
+ }
+ else {
+ path = path.concat(["M", point[0] + 0.5, point[1] - 0.5, "l", 0, -width]);
+ }
+ }
+ }
+ if (odd || even) {
+ if (oddPath.length) {
+ if (!me.gridOdd && oddPath.length) {
+ me.gridOdd = surface.add({
+ type: 'path',
+ path: oddPath
+ });
+ }
+ me.gridOdd.setAttributes(Ext.apply({
+ path: oddPath,
+ hidden: false
+ }, odd || {}), true);
+ }
+ if (evenPath.length) {
+ if (!me.gridEven) {
+ me.gridEven = surface.add({
+ type: 'path',
+ path: evenPath
+ });
+ }
+ me.gridEven.setAttributes(Ext.apply({
+ path: evenPath,
+ hidden: false
+ }, even || {}), true);
+ }
+ }
+ else {
+ if (path.length) {
+ if (!me.gridLines) {
+ me.gridLines = me.chart.surface.add({
+ type: 'path',
+ path: path,
+ "stroke-width": me.lineWidth || 1,
+ stroke: me.gridColor || '#ccc'
+ });
+ }
+ me.gridLines.setAttributes({
+ hidden: false,
+ path: path
+ }, true);
+ }
+ else if (me.gridLines) {
+ me.gridLines.hide(true);
+ }
+ }
+ },
+
+ //@private
+ getOrCreateLabel: function(i, text) {
+ var me = this,
+ labelGroup = me.labelGroup,
+ textLabel = labelGroup.getAt(i),
+ surface = me.chart.surface;
+ if (textLabel) {
+ if (text != textLabel.attr.text) {
+ textLabel.setAttributes(Ext.apply({
+ text: text
+ }, me.label), true);
+ textLabel._bbox = textLabel.getBBox();
+ }
+ }
+ else {
+ textLabel = surface.add(Ext.apply({
+ group: labelGroup,
+ type: 'text',
+ x: 0,
+ y: 0,
+ text: text
+ }, me.label));
+ surface.renderItem(textLabel);
+ textLabel._bbox = textLabel.getBBox();
+ }
+ //get untransformed bounding box
+ if (me.label.rotation) {
+ textLabel.setAttributes({
+ rotation: {
+ degrees: 0
+ }
+ }, true);
+ textLabel._ubbox = textLabel.getBBox();
+ textLabel.setAttributes(me.label, true);
+ } else {
+ textLabel._ubbox = textLabel._bbox;
+ }
+ return textLabel;
+ },
+
+ rect2pointArray: function(sprite) {
+ var surface = this.chart.surface,
+ rect = surface.getBBox(sprite, true),
+ p1 = [rect.x, rect.y],
+ p1p = p1.slice(),
+ p2 = [rect.x + rect.width, rect.y],
+ p2p = p2.slice(),
+ p3 = [rect.x + rect.width, rect.y + rect.height],
+ p3p = p3.slice(),
+ p4 = [rect.x, rect.y + rect.height],
+ p4p = p4.slice(),
+ matrix = sprite.matrix;
+ //transform the points
+ p1[0] = matrix.x.apply(matrix, p1p);
+ p1[1] = matrix.y.apply(matrix, p1p);
+
+ p2[0] = matrix.x.apply(matrix, p2p);
+ p2[1] = matrix.y.apply(matrix, p2p);
+
+ p3[0] = matrix.x.apply(matrix, p3p);
+ p3[1] = matrix.y.apply(matrix, p3p);
+
+ p4[0] = matrix.x.apply(matrix, p4p);
+ p4[1] = matrix.y.apply(matrix, p4p);
+ return [p1, p2, p3, p4];
+ },
+
+ intersect: function(l1, l2) {
+ var r1 = this.rect2pointArray(l1),
+ r2 = this.rect2pointArray(l2);
+ return !!Ext.draw.Draw.intersect(r1, r2).length;
+ },
+
+ drawHorizontalLabels: function() {
+ var me = this,
+ labelConf = me.label,
+ floor = Math.floor,
+ max = Math.max,
+ axes = me.chart.axes,
+ position = me.position,
+ inflections = me.inflections,
+ ln = inflections.length,
+ labels = me.labels,
+ labelGroup = me.labelGroup,
+ maxHeight = 0,
+ ratio,
+ gutterY = me.chart.maxGutter[1],
+ ubbox, bbox, point, prevX, prevLabel,
+ projectedWidth = 0,
+ textLabel, attr, textRight, text,
+ label, last, x, y, i, firstLabel;
+
+ last = ln - 1;
+ //get a reference to the first text label dimensions
+ point = inflections[0];
+ firstLabel = me.getOrCreateLabel(0, me.label.renderer(labels[0]));
+ ratio = Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0)) >> 0;
+
+ for (i = 0; i < ln; i++) {
+ point = inflections[i];
+ text = me.label.renderer(labels[i]);
+ textLabel = me.getOrCreateLabel(i, text);
+ bbox = textLabel._bbox;
+ maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding);
+ x = floor(point[0] - (ratio? bbox.height : bbox.width) / 2);
+ if (me.chart.maxGutter[0] == 0) {
+ if (i == 0 && axes.findIndex('position', 'left') == -1) {
+ x = point[0];
+ }
+ else if (i == last && axes.findIndex('position', 'right') == -1) {
+ x = point[0] - bbox.width;
+ }
+ }
+ if (position == 'top') {
+ y = point[1] - (me.dashSize * 2) - me.label.padding - (bbox.height / 2);
+ }
+ else {
+ y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2);
+ }
+
+ textLabel.setAttributes({
+ hidden: false,
+ x: x,
+ y: y
+ }, true);
+
+ // Skip label if there isn't available minimum space
+ if (i != 0 && (me.intersect(textLabel, prevLabel)
+ || me.intersect(textLabel, firstLabel))) {
+ textLabel.hide(true);
+ continue;
+ }
+
+ prevLabel = textLabel;
+ }
+
+ return maxHeight;
+ },
+
+ drawVerticalLabels: function() {
+ var me = this,
+ inflections = me.inflections,
+ position = me.position,
+ ln = inflections.length,
+ labels = me.labels,
+ maxWidth = 0,
+ max = Math.max,
+ floor = Math.floor,
+ ceil = Math.ceil,
+ axes = me.chart.axes,
+ gutterY = me.chart.maxGutter[1],
+ ubbox, bbox, point, prevLabel,
+ projectedWidth = 0,
+ textLabel, attr, textRight, text,
+ label, last, x, y, i;
+
+ last = ln;
+ for (i = 0; i < last; i++) {
+ point = inflections[i];
+ text = me.label.renderer(labels[i]);
+ textLabel = me.getOrCreateLabel(i, text);
+ bbox = textLabel._bbox;
+
+ maxWidth = max(maxWidth, bbox.width + me.dashSize + me.label.padding);
+ y = point[1];
+ if (gutterY < bbox.height / 2) {
+ if (i == last - 1 && axes.findIndex('position', 'top') == -1) {
+ y = me.y - me.length + ceil(bbox.height / 2);
+ }
+ else if (i == 0 && axes.findIndex('position', 'bottom') == -1) {
+ y = me.y - floor(bbox.height / 2);
+ }
+ }
+ if (position == 'left') {
+ x = point[0] - bbox.width - me.dashSize - me.label.padding - 2;
+ }
+ else {
+ x = point[0] + me.dashSize + me.label.padding + 2;
+ }
+ textLabel.setAttributes(Ext.apply({
+ hidden: false,
+ x: x,
+ y: y
+ }, me.label), true);
+ // Skip label if there isn't available minimum space
+ if (i != 0 && me.intersect(textLabel, prevLabel)) {
+ textLabel.hide(true);
+ continue;
+ }
+ prevLabel = textLabel;
+ }
+
+ return maxWidth;
+ },
+
+<span id='Ext-chart.axis.Axis-method-drawLabel'> /**
+</span> * Renders the labels in the axes.
+ */
+ drawLabel: function() {
+ var me = this,
+ position = me.position,
+ labelGroup = me.labelGroup,
+ inflections = me.inflections,
+ maxWidth = 0,
+ maxHeight = 0,
+ ln, i;
+
+ if (position == 'left' || position == 'right') {
+ maxWidth = me.drawVerticalLabels();
+ } else {
+ maxHeight = me.drawHorizontalLabels();
+ }
+
+ // Hide unused bars
+ ln = labelGroup.getCount();
+ i = inflections.length;
+ for (; i < ln; i++) {
+ labelGroup.getAt(i).hide(true);
+ }
+
+ me.bbox = {};
+ Ext.apply(me.bbox, me.axisBBox);
+ me.bbox.height = maxHeight;
+ me.bbox.width = maxWidth;
+ if (Ext.isString(me.title)) {
+ me.drawTitle(maxWidth, maxHeight);
+ }
+ },
+
+ // @private creates the elipsis for the text.
+ elipsis: function(sprite, text, desiredWidth, minWidth, center) {
+ var bbox,
+ x;
+
+ if (desiredWidth < minWidth) {
+ sprite.hide(true);
+ return false;
+ }
+ while (text.length > 4) {
+ text = text.substr(0, text.length - 4) + "...";
+ sprite.setAttributes({
+ text: text
+ }, true);
+ bbox = sprite.getBBox();
+ if (bbox.width < desiredWidth) {
+ if (typeof center == 'number') {
+ sprite.setAttributes({
+ x: Math.floor(center - (bbox.width / 2))
+ }, true);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+
+<span id='Ext-chart.axis.Axis-method-setTitle'> /**
+</span> * Updates the {@link #title} of this axis.
+ * @param {String} title
+ */
+ setTitle: function(title) {
+ this.title = title;
+ this.drawLabel();
+ },
+
+ // @private draws the title for the axis.
+ drawTitle: function(maxWidth, maxHeight) {
+ var me = this,
+ position = me.position,
+ surface = me.chart.surface,
+ displaySprite = me.displaySprite,
+ title = me.title,
+ rotate = (position == 'left' || position == 'right'),
+ x = me.x,
+ y = me.y,
+ base, bbox, pad;
+
+ if (displaySprite) {
+ displaySprite.setAttributes({text: title}, true);
+ } else {
+ base = {
+ type: 'text',
+ x: 0,
+ y: 0,
+ text: title
+ };
+ displaySprite = me.displaySprite = surface.add(Ext.apply(base, me.axisTitleStyle, me.labelTitle));
+ surface.renderItem(displaySprite);
+ }
+ bbox = displaySprite.getBBox();
+ pad = me.dashSize + me.label.padding;
+
+ if (rotate) {
+ y -= ((me.length / 2) - (bbox.height / 2));
+ if (position == 'left') {
+ x -= (maxWidth + pad + (bbox.width / 2));
+ }
+ else {
+ x += (maxWidth + pad + bbox.width - (bbox.width / 2));
+ }
+ me.bbox.width += bbox.width + 10;
+ }
+ else {
+ x += (me.length / 2) - (bbox.width * 0.5);
+ if (position == 'top') {
+ y -= (maxHeight + pad + (bbox.height * 0.3));
+ }
+ else {
+ y += (maxHeight + pad + (bbox.height * 0.8));
+ }
+ me.bbox.height += bbox.height + 10;
+ }
+ displaySprite.setAttributes({
+ translate: {
+ x: x,
+ y: y
+ }
+ }, true);
+ }
+});</pre></pre></body></html>
\ No newline at end of file