/**
* @class Ext.chart.axis.layout.Continuous
* @extends Ext.chart.axis.layout.Layout
*
* Processor for axis data that can be interpolated.
*/
Ext.define('Ext.chart.axis.layout.Continuous', {
extend: 'Ext.chart.axis.layout.Layout',
alias: 'axisLayout.continuous',
isContinuous: true,
config: {
adjustMinimumByMajorUnit: false,
adjustMaximumByMajorUnit: false
},
getCoordFor: function(value, field, idx, items) {
return +value;
},
/**
* @method snapEnds
* @inheritdoc
*/
snapEnds: function(context, min, max, estStepSize) {
var segmenter = context.segmenter,
axis = this.getAxis(),
noAnimation = !axis.spriteAnimationCount,
majorTickSteps = axis.getMajorTickSteps(),
// if specific number of steps requested and the segmenter supports such segmentation
bucket = majorTickSteps && segmenter.exactStep
? segmenter.exactStep(min, (max - min) / majorTickSteps)
: segmenter.preferredStep(min, estStepSize),
unit = bucket.unit,
step = bucket.step,
diffSteps = segmenter.diff(min, max, unit),
steps = (majorTickSteps || diffSteps) + 1,
from;
// If 'majorTickSteps' config of the axis is set (is not 0), it means that
// we want to split the range at that number of equal intervals (segmenter.exactStep),
// and don't care if the resulting ticks are at nice round values or not.
// So 'from' (aligned) step is equal to 'min' (unaligned step).
// And 'to' is equal to 'max'.
//
// Another case where this is possible, is when the range between 'min' and
// 'max' can be represented by n steps, where n is an integer.
// For example, if the data values are [7, 17, 27, 37, 47], the data step is 10
// and, if the calculated tick step (segmenter.preferredStep) is also 10,
// there is no need to segmenter.align the 'min' to 0, so that the ticks are at
// [0, 10, 20, 30, 40, 50], because the data points are already perfectly
// spaced, so the ticks can be exactly at the data points without runing the
// aesthetics.
//
// The 'noAnimation' check is required to prevent EXTJS-25413 from happening.
// The segmentation described above is ideal for a static chart, but produces
// unwanted effects during animation.
if (majorTickSteps || (noAnimation && +segmenter.add(min, diffSteps, unit) === max)) {
from = min;
}
else {
from = segmenter.align(min, step, unit);
}
return {
// min/max are NOT aligned to step
min: segmenter.from(min),
max: segmenter.from(max),
// from/to are aligned to step
from: from,
to: segmenter.add(from, steps, unit),
step: step,
steps: steps,
unit: unit,
get: function(currentStep) {
return segmenter.add(this.from, this.step * currentStep, this.unit);
}
};
},
snapMinorEnds: function(context) {
var majorTicks = context.majorTicks,
minorTickSteps = this.getAxis().getMinorTickSteps(),
segmenter = context.segmenter,
min = majorTicks.min,
max = majorTicks.max,
from = majorTicks.from,
unit = majorTicks.unit,
step = majorTicks.step / minorTickSteps,
scaledStep = step * unit.scale,
fromMargin = from - min,
offset = Math.floor(fromMargin / scaledStep),
extraSteps = offset + Math.floor((max - majorTicks.to) / scaledStep) + 1,
steps = majorTicks.steps * minorTickSteps + extraSteps;
return {
min: min,
max: max,
from: min + fromMargin % scaledStep,
to: segmenter.add(from, steps * step, unit),
step: step,
steps: steps,
unit: unit,
get: function(current) {
// don't render minor tick in major tick position
return (current % minorTickSteps + offset + 1 !== 0)
? segmenter.add(this.from, this.step * current, unit)
: null;
}
};
}
});