/** * @abstract * @class Ext.chart.axis.layout.Layout * * Interface used by Axis to process its data into a meaningful layout. */Ext.define('Ext.chart.axis.layout.Layout', { mixins: { observable: 'Ext.mixin.Observable' }, config: { /** * @cfg {Ext.chart.axis.Axis} axis The axis that the Layout is bound. */ axis: null }, constructor: function(config) { this.mixins.observable.constructor.call(this, config); }, /** * Processes the data of the series bound to the axis. * @param {Ext.chart.series.Series} series The bound series. */ processData: function(series) { var me = this, axis = me.getAxis(), direction = axis.getDirection(), boundSeries = axis.boundSeries, i, ln; if (series) { series['coordinate' + direction](); } else { for (i = 0, ln = boundSeries.length; i < ln; i++) { boundSeries[i]['coordinate' + direction](); } } }, /** * Calculates the position of major ticks for the axis. * @param {Object} context */ calculateMajorTicks: function(context) { var me = this, attr = context.attr, range = attr.max - attr.min, zoom = range / Math.max(1, attr.length) * (attr.visibleMax - attr.visibleMin), viewMin = attr.min + range * attr.visibleMin, viewMax = attr.min + range * attr.visibleMax, estStepSize = attr.estStepSize * zoom, majorTicks = me.snapEnds(context, attr.min, attr.max, estStepSize); if (majorTicks) { me.trimByRange(context, majorTicks, viewMin, viewMax); context.majorTicks = majorTicks; } }, /** * Calculates the position of sub ticks for the axis. * @param {Object} context */ calculateMinorTicks: function(context) { if (this.snapMinorEnds) { context.minorTicks = this.snapMinorEnds(context); } }, /** * Calculates the position of tick marks for the axis. * @param {Object} context * @return {*} */ calculateLayout: function(context) { var me = this, attr = context.attr; if (attr.length === 0) { return null; } if (attr.majorTicks) { me.calculateMajorTicks(context); if (attr.minorTicks) { me.calculateMinorTicks(context); } } }, /** * @method * Snaps the data bound to the axis to meaningful tick marks. * @param {Object} context * @param {Number} min * @param {Number} max * @param {Number} estStepSize */ snapEnds: Ext.emptyFn, /** * Trims the layout of the axis by the defined minimum and maximum. * @param {Object} context * @param {Object} ticks Ticks object (e.g. major ticks) to be modified. * @param {Number} trimMin * @param {Number} trimMax */ trimByRange: function(context, ticks, trimMin, trimMax) { var segmenter = context.segmenter, unit = ticks.unit, beginIdx = segmenter.diff(ticks.from, trimMin, unit), endIdx = segmenter.diff(ticks.from, trimMax, unit), begin = Math.max(0, Math.ceil(beginIdx / ticks.step)), end = Math.min(ticks.steps, Math.floor(endIdx / ticks.step)); if (end < ticks.steps) { ticks.to = segmenter.add(ticks.from, end * ticks.step, unit); } if (ticks.max > trimMax) { ticks.max = ticks.to; } if (ticks.from < trimMin) { ticks.from = segmenter.add(ticks.from, begin * ticks.step, unit); while (ticks.from < trimMin) { begin++; ticks.from = segmenter.add(ticks.from, ticks.step, unit); } } if (ticks.min < trimMin) { ticks.min = ticks.from; } ticks.steps = end - begin; }});