@progress/kendo-charts
Version:
Kendo UI platform-independent Charts library
275 lines (221 loc) • 9.71 kB
JavaScript
import Axis from './axis';
import NumericAxis from './numeric-axis';
import AxisLabel from './axis-label';
import { DateLabelFormats } from './constants';
import { BLACK, DATE, COORD_PRECISION, DEFAULT_PRECISION } from '../common/constants';
import { setDefaultOptions, deepExtend, limitValue, round } from '../common';
import autoMajorUnit from './utils/auto-major-unit';
import ceil from './utils/ceil';
import { toDate, toTime, floorDate, ceilDate, duration, addDuration, addTicks, dateDiff, absoluteDateDiff, dateComparer, parseDate, parseDates, firstDay } from '../date-utils';
import { HOURS, DAYS, WEEKS, MONTHS, YEARS, TIME_PER_DAY, TIME_PER_WEEK, TIME_PER_MONTH, TIME_PER_YEAR, TIME_PER_UNIT } from '../date-utils/constants';
var MIN_VALUE_RANGE = 1000;
var DateValueAxis = (function (Axis) {
function DateValueAxis(seriesMin, seriesMax, axisOptions, chartService) {
var min = toDate(seriesMin);
var max = toDate(seriesMax);
var intlService = chartService.intl;
var options = axisOptions || {};
options = deepExtend(options || {}, {
min: parseDate(intlService, options.min),
max: parseDate(intlService, options.max),
axisCrossingValue: parseDates(intlService, options.axisCrossingValues || options.axisCrossingValue),
weekStartDay: firstDay(options, intlService)
});
options = applyDefaults(min, max, options);
Axis.call(this, options, chartService);
this.intlService = intlService;
this.seriesMin = min;
this.seriesMax = max;
var weekStartDay = options.weekStartDay || 0;
this.totalMin = toTime(floorDate(toTime(min) - 1, options.baseUnit, weekStartDay));
this.totalMax = toTime(ceilDate(toTime(max) + 1, options.baseUnit, weekStartDay));
}
if ( Axis ) DateValueAxis.__proto__ = Axis;
DateValueAxis.prototype = Object.create( Axis && Axis.prototype );
DateValueAxis.prototype.constructor = DateValueAxis;
DateValueAxis.prototype.clone = function clone () {
return new DateValueAxis(this.seriesMin, this.seriesMax, Object.assign({}, this.options), this.chartService);
};
DateValueAxis.prototype.range = function range () {
var options = this.options;
return { min: options.min, max: options.max };
};
DateValueAxis.prototype.getDivisions = function getDivisions (stepValue) {
var options = this.options;
return Math.floor(
duration(options.min, options.max, options.baseUnit) / stepValue + 1
);
};
DateValueAxis.prototype.getTickPositions = function getTickPositions (step) {
var options = this.options;
var ref = this.lineInfo();
var dir = ref.axisDir;
var lineSize = ref.lineSize;
var start = ref.lineStart;
var divisions = this.getDivisions(step);
var timeRange = dateDiff(options.max, options.min);
var scale = lineSize / timeRange;
var weekStartDay = options.weekStartDay || 0;
var positions = [ start ];
for (var i = 1; i < divisions; i++) {
var date = addDuration(options.min, i * step, options.baseUnit, weekStartDay);
var pos = start + dateDiff(date, options.min) * scale * dir;
positions.push(round(pos, COORD_PRECISION));
}
return positions;
};
DateValueAxis.prototype.getMajorTickPositions = function getMajorTickPositions () {
return this.getTickPositions(this.options.majorUnit);
};
DateValueAxis.prototype.getMinorTickPositions = function getMinorTickPositions () {
return this.getTickPositions(this.options.minorUnit);
};
DateValueAxis.prototype.getSlot = function getSlot (a, b, limit) {
return NumericAxis.prototype.getSlot.call(
this, parseDate(this.intlService, a), parseDate(this.intlService, b), limit
);
};
DateValueAxis.prototype.getValue = function getValue (point) {
var value = NumericAxis.prototype.getValue.call(this, point);
return value !== null ? toDate(value) : null;
};
DateValueAxis.prototype.labelsCount = function labelsCount () {
return this.getDivisions(this.options.majorUnit);
};
DateValueAxis.prototype.createAxisLabel = function createAxisLabel (index, labelOptions, labelContext) {
var options = this.options;
var offset = index * options.majorUnit;
var weekStartDay = options.weekStartDay || 0;
var date = options.min;
if (offset > 0) {
date = addDuration(date, offset, options.baseUnit, weekStartDay);
}
var unitFormat = labelOptions.dateFormats[options.baseUnit];
labelOptions.format = labelOptions.format || unitFormat;
var text = this.axisLabelText(date, labelOptions, labelContext);
return new AxisLabel(date, text, index, null, labelOptions);
};
DateValueAxis.prototype.translateRange = function translateRange (delta) {
var options = this.options;
var lineBox = this.lineBox();
var vertical = options.vertical;
var reverse = options.reverse;
var size = vertical ? lineBox.height() : lineBox.width();
var range = this.range();
var scale = size / dateDiff(range.max, range.min);
var offset = round(delta / scale, DEFAULT_PRECISION);
if ((vertical || reverse) && !(vertical && reverse )) {
offset = -offset;
}
var from = addTicks(options.min, offset);
var to = addTicks(options.max, offset);
return {
min: from,
max: to,
offset: offset
};
};
DateValueAxis.prototype.shouldRenderNote = function shouldRenderNote (value) {
var range = this.range();
return dateComparer(value, range.min) >= 0 && dateComparer(value, range.max) <= 0;
};
DateValueAxis.prototype.pan = function pan (delta) {
var range = this.translateRange(delta, true);
var limittedRange = this.limitRange(toTime(range.min), toTime(range.max), this.totalMin, this.totalMax, range.offset);
if (limittedRange) {
return {
min: toDate(limittedRange.min),
max: toDate(limittedRange.max)
};
}
};
DateValueAxis.prototype.pointsRange = function pointsRange (start, end) {
var startValue = this.getValue(start);
var endValue = this.getValue(end);
var min = Math.min(startValue, endValue);
var max = Math.max(startValue, endValue);
return {
min: toDate(min),
max: toDate(max)
};
};
DateValueAxis.prototype.scaleRange = function scaleRange (scale, cursor) {
var position = Math.abs(this.pointOffset(cursor));
var range = this.options.max - this.options.min;
var delta = this.scaleToDelta(scale, range);
var minDelta = position * delta;
var maxDelta = (1 - position) * delta;
var min = toDate(toTime(this.options.min) + minDelta);
var max = toDate(toTime(this.options.max) - maxDelta);
if (max - min < MIN_VALUE_RANGE) {
max = toDate(toTime(min) + MIN_VALUE_RANGE);
}
return {
min: min,
max: max
};
};
DateValueAxis.prototype.zoomRange = function zoomRange (scale, cursor) {
var range = this.scaleRange(scale, cursor);
var min = toDate(limitValue(toTime(range.min), this.totalMin, this.totalMax));
var max = toDate(limitValue(toTime(range.max), this.totalMin, this.totalMax));
return {
min: min,
max: max
};
};
return DateValueAxis;
}(Axis));
function timeUnits(delta) {
var unit = HOURS;
if (delta >= TIME_PER_YEAR) {
unit = YEARS;
} else if (delta >= TIME_PER_MONTH) {
unit = MONTHS;
} else if (delta >= TIME_PER_WEEK) {
unit = WEEKS;
} else if (delta >= TIME_PER_DAY) {
unit = DAYS;
}
return unit;
}
function applyDefaults(seriesMin, seriesMax, options) {
var min = options.min || seriesMin;
var max = options.max || seriesMax;
var baseUnit = options.baseUnit || (max && min ? timeUnits(absoluteDateDiff(max, min)) : HOURS);
var baseUnitTime = TIME_PER_UNIT[baseUnit];
var weekStartDay = options.weekStartDay || 0;
var autoMin = floorDate(toTime(min) - 1, baseUnit, weekStartDay) || toDate(max);
var autoMax = ceilDate(toTime(max) + 1, baseUnit, weekStartDay);
var userMajorUnit = options.majorUnit ? options.majorUnit : undefined;
var majorUnit = userMajorUnit || ceil(
autoMajorUnit(autoMin.getTime(), autoMax.getTime()),
baseUnitTime
) / baseUnitTime;
var actualUnits = duration(autoMin, autoMax, baseUnit);
var totalUnits = ceil(actualUnits, majorUnit);
var unitsToAdd = totalUnits - actualUnits;
var head = Math.floor(unitsToAdd / 2);
var tail = unitsToAdd - head;
if (!options.baseUnit) {
delete options.baseUnit;
}
options.baseUnit = options.baseUnit || baseUnit;
options.min = options.min || addDuration(autoMin, -head, baseUnit, weekStartDay);
options.max = options.max || addDuration(autoMax, tail, baseUnit, weekStartDay);
options.minorUnit = options.minorUnit || majorUnit / 5;
options.majorUnit = majorUnit;
return options;
}
setDefaultOptions(DateValueAxis, {
type: DATE,
majorGridLines: {
visible: true,
width: 1,
color: BLACK
},
labels: {
dateFormats: DateLabelFormats
}
});
export default DateValueAxis;