UNPKG

@progress/kendo-charts

Version:

Kendo UI platform-independent Charts library

370 lines (297 loc) 11.7 kB
import Axis from './axis'; import AxisLabel from './axis-label'; import Box from './box'; import { BLACK, DEFAULT_PRECISION, COORD_PRECISION } from '../common/constants'; import { deepExtend, defined, limitValue, round, setDefaultOptions, valueOrDefault } from '../common'; import autoMajorUnit from './utils/auto-major-unit'; import autoAxisMin from './utils/auto-axis-min'; import autoAxisMax from './utils/auto-axis-max'; import floor from './utils/floor'; import ceil from './utils/ceil'; import limitCoordinate from './utils/limit-coordinate'; var MIN_VALUE_RANGE = Math.pow(10, -DEFAULT_PRECISION + 1); var NumericAxis = (function (Axis) { function NumericAxis(seriesMin, seriesMax, options, chartService) { Axis.call(this, Object.assign({}, options, { seriesMin: seriesMin, seriesMax: seriesMax }), chartService); } if ( Axis ) NumericAxis.__proto__ = Axis; NumericAxis.prototype = Object.create( Axis && Axis.prototype ); NumericAxis.prototype.constructor = NumericAxis; NumericAxis.prototype.initUserOptions = function initUserOptions (options) { var autoOptions = autoAxisOptions(options.seriesMin, options.seriesMax, options); this.totalOptions = totalAxisOptions(autoOptions, options); return axisOptions(autoOptions, options); }; NumericAxis.prototype.initFields = function initFields () { this.totalMin = this.totalOptions.min; this.totalMax = this.totalOptions.max; this.totalMajorUnit = this.totalOptions.majorUnit; this.seriesMin = this.options.seriesMin; this.seriesMax = this.options.seriesMax; }; NumericAxis.prototype.clone = function clone () { return new NumericAxis( this.seriesMin, this.seriesMax, Object.assign({}, this.options), this.chartService ); }; NumericAxis.prototype.startValue = function startValue () { return 0; }; NumericAxis.prototype.range = function range () { var options = this.options; return { min: options.min, max: options.max }; }; NumericAxis.prototype.getDivisions = function getDivisions (stepValue) { if (stepValue === 0) { return 1; } var options = this.options; var range = options.max - options.min; return Math.floor(round(range / stepValue, COORD_PRECISION)) + 1; }; NumericAxis.prototype.getTickPositions = function getTickPositions (unit, skipUnit) { var options = this.options; var ref = this.lineInfo(); var axisDir = ref.axisDir; var axisOrigin = ref.axisOrigin; var lineBox = ref.lineBox; var lineSize = ref.lineSize; var range = options.max - options.min; var scale = lineSize / range; var step = unit * scale; var divisions = this.getDivisions(unit); var positions = []; var pos = lineBox[axisOrigin]; var skipStep = 0; if (skipUnit) { skipStep = skipUnit / unit; } for (var idx = 0; idx < divisions; idx++) { if (idx % skipStep !== 0) { positions.push(round(pos, COORD_PRECISION)); } pos = pos + step * axisDir; } return positions; }; NumericAxis.prototype.getMajorTickPositions = function getMajorTickPositions () { return this.getTickPositions(this.options.majorUnit); }; NumericAxis.prototype.getMinorTickPositions = function getMinorTickPositions () { return this.getTickPositions(this.options.minorUnit); }; NumericAxis.prototype.getSlot = function getSlot (a, b, limit) { if ( limit === void 0 ) limit = false; var options = this.options; var ref = this.lineInfo(); var axis = ref.axis; var axisDir = ref.axisDir; var lineBox = ref.lineBox; var lineSize = ref.lineSize; var lineStart = ref.lineStart; var step = axisDir * (lineSize / (options.max - options.min)); var start = valueOrDefault(a, b || 0); var end = valueOrDefault(b, a || 0); if (limit) { start = limitValue(start, options.min, options.max); end = limitValue(end, options.min, options.max); } var p1 = Math.min(start, end) - options.min; var p2 = Math.max(start, end) - options.min; var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1); slotBox[axis + 1] = limitCoordinate(lineStart + step * (axisDir > 0 ? p1 : p2)); slotBox[axis + 2] = limitCoordinate(lineStart + step * (axisDir > 0 ? p2 : p1)); return slotBox; }; NumericAxis.prototype.getValue = function getValue (point) { var options = this.options; var max = Number(options.max); var min = Number(options.min); var offset = this.pointOffset(point); var valueOffset = offset * (max - min); if (offset < 0 || offset > 1) { return null; } var value = min + valueOffset; return round(value, DEFAULT_PRECISION); }; NumericAxis.prototype.translateRange = function translateRange (delta) { var options = this.options; var vertical = options.vertical; var reverse = options.reverse; var max = options.max; var min = options.min; var ref = this.lineInfo(); var lineSize = ref.lineSize; var range = max - min; var scale = lineSize / range; var offset = round(delta / scale, DEFAULT_PRECISION); if ((vertical || reverse) && !(vertical && reverse )) { offset = -offset; } return { min: min + offset, max: max + offset, offset: offset }; }; NumericAxis.prototype.labelsCount = function labelsCount () { return this.getDivisions(this.options.majorUnit); }; NumericAxis.prototype.createAxisLabel = function createAxisLabel (index, labelOptions, labelContext) { var options = this.options; var value = round(options.min + (index * options.majorUnit), DEFAULT_PRECISION); var text = this.axisLabelText(value, labelOptions, labelContext); return new AxisLabel(value, text, index, null, labelOptions); }; NumericAxis.prototype.shouldRenderNote = function shouldRenderNote (value) { var range = this.range(); return range.min <= value && value <= range.max; }; NumericAxis.prototype.pan = function pan (delta) { var range = this.translateRange(delta); return this.limitRange(range.min, range.max, this.totalMin, this.totalMax, range.offset); }; NumericAxis.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); if (this.isValidRange(min, max)) { return { min: min, max: max }; } }; NumericAxis.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 = round(this.options.min + minDelta, DEFAULT_PRECISION); var max = round(this.options.max - maxDelta, DEFAULT_PRECISION); if (max - min < MIN_VALUE_RANGE) { max = min + MIN_VALUE_RANGE; } return { min: min, max: max }; }; NumericAxis.prototype.zoomRange = function zoomRange (scale, cursor) { var ref = this; var totalMin = ref.totalMin; var totalMax = ref.totalMax; var range = this.scaleRange(scale, cursor); return { min: limitValue(range.min, totalMin, totalMax), max: limitValue(range.max, totalMin, totalMax), narrowRange: false }; }; NumericAxis.prototype.isValidRange = function isValidRange (min, max) { return max - min > MIN_VALUE_RANGE; }; return NumericAxis; }(Axis)); function autoAxisOptions(seriesMin, seriesMax, options) { var narrowRange = options.narrowRange; var autoMin = autoAxisMin(seriesMin, seriesMax, narrowRange); var autoMax = autoAxisMax(seriesMin, seriesMax, narrowRange); var majorUnit = autoMajorUnit(autoMin, autoMax); var autoOptions = { majorUnit: majorUnit }; if (options.roundToMajorUnit !== false) { if (autoMin < 0 && remainderClose(autoMin, majorUnit, 1 / 3)) { autoMin -= majorUnit; } if (autoMax > 0 && remainderClose(autoMax, majorUnit, 1 / 3)) { autoMax += majorUnit; } } autoOptions.min = floor(autoMin, majorUnit); autoOptions.max = ceil(autoMax, majorUnit); return autoOptions; } function totalAxisOptions(autoOptions, options) { return { min: defined(options.min) ? Math.min(autoOptions.min, options.min) : autoOptions.min, max: defined(options.max) ? Math.max(autoOptions.max, options.max) : autoOptions.max, majorUnit: autoOptions.majorUnit }; } function clearNullValues(options, fields) { for (var idx = 0; idx < fields.length; idx++) { var field = fields[idx]; if (options[field] === null) { options[field] = undefined; } } } function axisOptions(autoOptions, userOptions) { var options = userOptions; var userSetMin, userSetMax; if (userOptions) { clearNullValues(userOptions, [ 'min', 'max' ]); userSetMin = defined(userOptions.min); userSetMax = defined(userOptions.max); var userSetLimits = userSetMin || userSetMax; if (userSetLimits) { if (userOptions.min === userOptions.max) { if (userOptions.min > 0) { userOptions.min = 0; } else { userOptions.max = 1; } } } if (userOptions.majorUnit) { autoOptions.min = floor(autoOptions.min, userOptions.majorUnit); autoOptions.max = ceil(autoOptions.max, userOptions.majorUnit); } else if (userSetLimits) { options = deepExtend(autoOptions, userOptions); // Determine an auto major unit after min/max have been set autoOptions.majorUnit = autoMajorUnit(options.min, options.max); } } autoOptions.minorUnit = (options.majorUnit || autoOptions.majorUnit) / 5; var result = deepExtend(autoOptions, options); if (result.min >= result.max) { if (userSetMin && !userSetMax) { result.max = result.min + result.majorUnit; } else if (!userSetMin && userSetMax) { result.min = result.max - result.majorUnit; } } return result; } function remainderClose(value, divisor, ratio) { var remainder = round(Math.abs(value % divisor), DEFAULT_PRECISION); var threshold = divisor * (1 - ratio); return remainder === 0 || remainder > threshold; } setDefaultOptions(NumericAxis, { type: "numeric", min: 0, max: 1, vertical: true, majorGridLines: { visible: true, width: 1, color: BLACK }, labels: { format: "#.####################" }, zIndex: 1 }); export default NumericAxis;