@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,808 lines (1,469 loc) • 230 kB
JavaScript
module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ({
/***/ 0:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(866);
/***/ }),
/***/ 3:
/***/ (function(module, exports) {
module.exports = function() { throw new Error("define cannot be used indirect"); };
/***/ }),
/***/ 859:
/***/ (function(module, exports) {
module.exports = require("../../kendo.drawing");
/***/ }),
/***/ 862:
/***/ (function(module, exports) {
module.exports = require("../../kendo.core");
/***/ }),
/***/ 866:
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
__webpack_require__(862),
__webpack_require__(859)
], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
})(function(){
(function ($) {
/* jshint curly:false */
window.kendo.dataviz = window.kendo.dataviz || {};
var drawing = kendo.drawing;
var util = drawing.util;
var Path = drawing.Path;
var Group = drawing.Group;
var Class = kendo.Class;
var geometry = kendo.geometry;
var Rect = geometry.Rect;
var Circle = geometry.Circle;
var geometryTransform = geometry.transform;
var Segment = geometry.Segment;
var dataviz = kendo.dataviz;
var deepExtend = kendo.deepExtend;
var isFunction = kendo.isFunction;
var __common_getter_js = kendo.getter;
var ARC = "arc";
var AXIS_LABEL_CLICK = "axisLabelClick";
var BLACK = "#000";
var BOTTOM = "bottom";
var CENTER = "center";
var CIRCLE = "circle";
var COORD_PRECISION = 3;
var CROSS = "cross";
var DATE = "date";
var DEFAULT_FONT = "12px sans-serif";
var DEFAULT_HEIGHT = 400;
var DEFAULT_PRECISION = 10;
var DEFAULT_WIDTH = 600;
var END = "end";
var FORMAT_REGEX = /\{\d+:?/;
var HEIGHT = "height";
var HIGHLIGHT_ZINDEX = 100;
var INSIDE = "inside";
var LEFT = "left";
var MAX_VALUE = Number.MAX_VALUE;
var MIN_VALUE = -Number.MAX_VALUE;
var NONE = "none";
var NOTE_CLICK = "noteClick";
var NOTE_HOVER = "noteHover";
var NOTE_LEAVE = "noteLeave";
var OBJECT = "object";
var OUTSIDE = "outside";
var RIGHT = "right";
var START = "start";
var STRING = "string";
var TOP = "top";
var TRIANGLE = "triangle";
var VALUE = "value";
var WHITE = "#fff";
var WIDTH = "width";
var X = "x";
var Y = "y";
var constants = {
ARC: ARC,
AXIS_LABEL_CLICK: AXIS_LABEL_CLICK,
BLACK: BLACK,
BOTTOM: BOTTOM,
CENTER: CENTER,
CIRCLE: CIRCLE,
COORD_PRECISION: COORD_PRECISION,
CROSS: CROSS,
DATE: DATE,
DEFAULT_FONT: DEFAULT_FONT,
DEFAULT_HEIGHT: DEFAULT_HEIGHT,
DEFAULT_PRECISION: DEFAULT_PRECISION,
DEFAULT_WIDTH: DEFAULT_WIDTH,
END: END,
FORMAT_REGEX: FORMAT_REGEX,
HEIGHT: HEIGHT,
HIGHLIGHT_ZINDEX: HIGHLIGHT_ZINDEX,
INSIDE: INSIDE,
LEFT: LEFT,
MAX_VALUE: MAX_VALUE,
MIN_VALUE: MIN_VALUE,
NONE: NONE,
NOTE_CLICK: NOTE_CLICK,
NOTE_HOVER: NOTE_HOVER,
NOTE_LEAVE: NOTE_LEAVE,
OBJECT: OBJECT,
OUTSIDE: OUTSIDE,
RIGHT: RIGHT,
START: START,
STRING: STRING,
TOP: TOP,
TRIANGLE: TRIANGLE,
VALUE: VALUE,
WHITE: WHITE,
WIDTH: WIDTH,
X: X,
Y: Y
};
function isArray(value) {
return Array.isArray(value);
}
function addClass(element, classes) {
var classArray = isArray(classes) ? classes : [ classes ];
for (var idx = 0; idx < classArray.length; idx++) {
var className = classArray[idx];
if (element.className.indexOf(className) === -1) {
element.className += " " + className;
}
}
}
var SPACE_REGEX = /\s+/g;
function removeClass(element, className) {
if (element && element.className) {
element.className = element.className.replace(className, "").replace(SPACE_REGEX, " ");
}
}
function alignPathToPixel(path) {
var offset = 0.5;
if (path.options.stroke && kendo.drawing.util.defined(path.options.stroke.width)) {
if (path.options.stroke.width % 2 === 0) {
offset = 0;
}
}
for (var i = 0; i < path.segments.length; i++) {
path.segments[i].anchor().round(0).translate(offset, offset);
}
return path;
}
function clockwise(angle1, angle2) {
// True if angle2 is clockwise of angle1
// assuming angles grow in clock-wise direction
// (as in the pie and radar charts)
return -angle1.x * angle2.y + angle1.y * angle2.x < 0;
}
function isNumber(value) {
return typeof value === "number" && !isNaN(value);
}
function isString(value) {
return typeof value === STRING;
}
function convertableToNumber(value) {
return isNumber(value) || (isString(value) && isFinite(value));
}
function isObject(value) {
return typeof value === "object";
}
function styleValue(value) {
if (isNumber(value)) {
return value + "px";
}
return value;
}
var SIZE_STYLES_REGEX = /width|height|top|left|bottom|right/i;
function isSizeField(field) {
return SIZE_STYLES_REGEX.test(field);
}
function elementStyles(element, styles) {
var stylesArray = isString(styles) ? [ styles ] : styles;
if (isArray(stylesArray)) {
var result = {};
var style = window.getComputedStyle(element);
for (var idx = 0; idx < stylesArray.length; idx++) {
var field = stylesArray[idx];
result[field] = isSizeField(field) ? parseFloat(style[field]) : style[field];
}
return result;
} else if (isObject(styles)) {
for (var field$1 in styles) {
element.style[field$1] = styleValue(styles[field$1]);
}
}
}
function getSpacing(value, defaultSpacing) {
if (defaultSpacing === void 0) { defaultSpacing = 0; }
var spacing = { top: 0, right: 0, bottom: 0, left: 0 };
if (typeof(value) === "number") {
spacing[TOP] = spacing[RIGHT] = spacing[BOTTOM] = spacing[LEFT] = value;
} else {
spacing[TOP] = value[TOP] || defaultSpacing;
spacing[RIGHT] = value[RIGHT] || defaultSpacing;
spacing[BOTTOM] = value[BOTTOM] || defaultSpacing;
spacing[LEFT] = value[LEFT] || defaultSpacing;
}
return spacing;
}
var defaultImplementation = {
format: function (format, value) { return value; },
toString: function (value) { return value; },
parseDate: function (value) { return new Date(value); }
};
var current = defaultImplementation;
var IntlService = Class.extend({
});
IntlService.register = function(userImplementation) {
current = userImplementation;
};
if (Object.defineProperties) {
Object.defineProperties(IntlService, {
implementation: {
get: function() {
return current;
}
}
});
}
var FORMAT_REPLACE_REGEX = /\{(\d+)(:[^\}]+)?\}/g;
var FormatService = Class.extend({
init: function(intlService) {
this._intlService = intlService;
},
auto: function(formatString) {
var values = [], len = arguments.length - 1;
while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
var intl = this.intl;
if (isString(formatString) && formatString.match(FORMAT_REGEX)) {
return intl.format.apply(intl, [ formatString ].concat( values ));
}
return intl.toString(values[0], formatString);
},
localeAuto: function(formatString, values, locale) {
var intl = this.intl;
var result;
if (isString(formatString) && formatString.match(FORMAT_REGEX)) {
result = formatString.replace(FORMAT_REPLACE_REGEX, function(match, index, placeholderFormat) {
var value = values[parseInt(index, 10)];
return intl.toString(value, placeholderFormat ? placeholderFormat.substring(1) : "", locale);
});
} else {
result = intl.toString(values[0], formatString, locale);
}
return result;
}
});
if (Object.defineProperties) {
Object.defineProperties(FormatService.fn, {
intl: {
get: function() {
return this._intlService || IntlService.implementation;
},
set: function(value) {
this._intlService = value;
}
}
});
}
var ChartService = Class.extend({
init: function(chart, context) {
if (context === void 0) { context = {}; }
this._intlService = context.intlService;
this.sender = context.sender || chart;
this.format = new FormatService(context.intlService);
this.chart = chart;
this.rtl = Boolean(context.rtl);
},
notify: function(name, args) {
if (this.chart) {
this.chart.trigger(name, args);
}
},
isPannable: function(axis) {
var pannable = ((this.chart || {}).options || {}).pannable;
return pannable && pannable.lock !== axis;
}
});
if (Object.defineProperties) {
Object.defineProperties(ChartService.fn, {
intl: {
get: function() {
return this._intlService || IntlService.implementation;
},
set: function(value) {
this._intlService = value;
this.format.intl = value;
}
}
});
}
var current$1;
var DomEventsBuilder = Class.extend({
});
DomEventsBuilder.register = function(userImplementation) {
current$1 = userImplementation;
};
DomEventsBuilder.create = function(element, events) {
if (current$1) {
return current$1.create(element, events);
}
};
var current$2 = {
compile: function(template) {
return template;
}
};
var TemplateService = Class.extend({
});
TemplateService.register = function(userImplementation) {
current$2 = userImplementation;
};
TemplateService.compile = function(template) {
return current$2.compile(template);
};
var services = {
ChartService: ChartService,
DomEventsBuilder: DomEventsBuilder,
FormatService: FormatService,
IntlService: IntlService,
TemplateService: TemplateService
};
function getTemplate(options) {
if (options === void 0) { options = {}; }
var template;
if (options.template) {
options.template = template = TemplateService.compile(options.template);
} else if (isFunction(options.content)) {
template = options.content;
}
return template;
}
function grep(array, callback) {
var length = array.length;
var result = [];
for (var idx = 0; idx < length; idx++) {
if (callback(array[idx])) {
result .push(array[idx]);
}
}
return result;
}
function hasClasses(element, classNames) {
if (element.className) {
var names = classNames.split(" ");
for (var idx = 0; idx < names.length; idx++) {
if (element.className.indexOf(names[idx]) !== -1) {
return true;
}
}
}
}
var HashMap = function HashMap() {
this._map = {};
};
HashMap.prototype.get = function get (name) {
return this._map[this._key(name)];
};
HashMap.prototype.set = function set (name, value) {
this._map[this._key(name)] = value;
};
HashMap.prototype._key = function _key (name) {
return name instanceof Date ? name.getTime() : name;
};
function inArray(value, array) {
if (array) {
return array.indexOf(value) !== -1;
}
}
function interpolateValue(start, end, progress) {
return kendo.drawing.util.round(start + (end - start) * progress, COORD_PRECISION);
}
var TRIGGER = 'trigger';
var InstanceObserver = Class.extend({
init: function(observer, handlers) {
this.observer = observer;
this.handlerMap = deepExtend({}, this.handlerMap, handlers);
},
trigger: function(name, args) {
var ref = this;
var observer = ref.observer;
var handlerMap = ref.handlerMap;
var isDefaultPrevented;
if (handlerMap[name]) {
isDefaultPrevented = this.callObserver(handlerMap[name], args);
} else if (observer[TRIGGER]) {
isDefaultPrevented = this.callObserver(TRIGGER, name, args);
}
return isDefaultPrevented;
},
callObserver: function(fnName) {
var args = [], len = arguments.length - 1;
while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
return this.observer[fnName].apply(this.observer, args);
},
requiresHandlers: function(names) {
var this$1 = this;
if (this.observer.requiresHandlers) {
return this.observer.requiresHandlers(names);
}
for (var idx = 0; idx < names.length; idx++) {
if (this$1.handlerMap[names[idx]]) {
return true;
}
}
}
});
function map(array, callback) {
var length = array.length;
var result = [];
for (var idx = 0; idx < length; idx++) {
var value = callback(array[idx]);
if (kendo.drawing.util.defined(value)) {
result.push(value);
}
}
return result;
}
function mousewheelDelta(e) {
var delta = 0;
if (e.wheelDelta) {
delta = -e.wheelDelta / 120;
delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta);
}
if (e.detail) {
delta = kendo.drawing.util.round(e.detail / 3);
}
return delta;
}
var ref = kendo.drawing.util;
var append = ref.append;
var bindEvents = ref.bindEvents;
var defined = ref.defined;
var deg = ref.deg;
var elementOffset = ref.elementOffset;
var elementSize = ref.elementSize;
var eventElement = ref.eventElement;
var eventCoordinates = ref.eventCoordinates;
var last = ref.last;
var limitValue = ref.limitValue;
var objectKey = ref.objectKey;
var rad = ref.rad;
var round = ref.round;
var unbindEvents = ref.unbindEvents;
var valueOrDefault = ref.valueOrDefault;
var FontLoader = Class.extend({
});
FontLoader.fetchFonts = function(options, fonts, state) {
if (state === void 0) { state = { depth: 0 }; }
var MAX_DEPTH = 5;
if (!options || state.depth > MAX_DEPTH || !document.fonts) {
return;
}
Object.keys(options).forEach(function(key) {
var value = options[key];
if (key === "dataSource" || key[0] === "$" || !value) {
return;
}
if (key === "font") {
fonts.push(value);
} else if (typeof value === "object") {
state.depth++;
FontLoader.fetchFonts(value, fonts, state);
state.depth--;
}
});
};
FontLoader.loadFonts = function(fonts, callback) {
var promises = [];
if (fonts.length > 0 && document.fonts) {
try {
promises = fonts.map(function(font) {
return document.fonts.load(font);
});
} catch (e) {
// Silence font-loading errors
kendo.logToConsole(e);
}
Promise.all(promises).then(callback, callback);
} else {
callback();
}
};
FontLoader.preloadFonts = function(options, callback) {
var fonts = [];
FontLoader.fetchFonts(options, fonts);
FontLoader.loadFonts(fonts, callback);
};
function setDefaultOptions(type, options) {
var proto = type.prototype;
if (proto.options) {
proto.options = deepExtend({}, proto.options, options);
} else {
proto.options = options;
}
}
function sparseArrayLimits(arr) {
var min = MAX_VALUE;
var max = MIN_VALUE;
for (var idx = 0, length = arr.length; idx < length; idx++) {
var value = arr[idx];
if (value !== null && isFinite(value)) {
min = Math.min(min, value);
max = Math.max(max, value);
}
}
return {
min: min === MAX_VALUE ? undefined : min,
max: max === MIN_VALUE ? undefined : max
};
}
function autoMajorUnit(min, max) {
var diff = round(max - min, DEFAULT_PRECISION - 1);
if (diff === 0) {
if (max === 0) {
return 0.1;
}
diff = Math.abs(max);
}
var scale = Math.pow(10, Math.floor(Math.log(diff) / Math.log(10)));
var relativeValue = round((diff / scale), DEFAULT_PRECISION);
var scaleMultiplier = 1;
if (relativeValue < 1.904762) {
scaleMultiplier = 0.2;
} else if (relativeValue < 4.761904) {
scaleMultiplier = 0.5;
} else if (relativeValue < 9.523809) {
scaleMultiplier = 1;
} else {
scaleMultiplier = 2;
}
return round(scale * scaleMultiplier, DEFAULT_PRECISION);
}
var Point = Class.extend({
init: function(x, y) {
this.x = x || 0;
this.y = y || 0;
},
clone: function() {
return new Point(this.x, this.y);
},
equals: function(point) {
return point && this.x === point.x && this.y === point.y;
},
rotate: function(center, degrees) {
var theta = rad(degrees);
var cosT = Math.cos(theta);
var sinT = Math.sin(theta);
var cx = center.x;
var cy = center.y;
var ref = this;
var x = ref.x;
var y = ref.y;
this.x = round(
cx + (x - cx) * cosT + (y - cy) * sinT,
COORD_PRECISION
);
this.y = round(
cy + (y - cy) * cosT - (x - cx) * sinT,
COORD_PRECISION
);
return this;
},
multiply: function(a) {
this.x *= a;
this.y *= a;
return this;
},
distanceTo: function(point) {
var dx = this.x - point.x;
var dy = this.y - point.y;
return Math.sqrt(dx * dx + dy * dy);
}
});
Point.onCircle = function(center, angle, radius) {
var radians = rad(angle);
return new Point(
center.x - radius * Math.cos(radians),
center.y - radius * Math.sin(radians)
);
};
var Box = Class.extend({
init: function(x1, y1, x2, y2) {
this.x1 = x1 || 0;
this.y1 = y1 || 0;
this.x2 = x2 || 0;
this.y2 = y2 || 0;
},
equals: function(box) {
return this.x1 === box.x1 && this.x2 === box.x2 &&
this.y1 === box.y1 && this.y2 === box.y2;
},
width: function() {
return this.x2 - this.x1;
},
height: function() {
return this.y2 - this.y1;
},
translate: function(dx, dy) {
this.x1 += dx;
this.x2 += dx;
this.y1 += dy;
this.y2 += dy;
return this;
},
move: function(x, y) {
var height = this.height();
var width = this.width();
if (defined(x)) {
this.x1 = x;
this.x2 = this.x1 + width;
}
if (defined(y)) {
this.y1 = y;
this.y2 = this.y1 + height;
}
return this;
},
wrap: function(targetBox) {
this.x1 = Math.min(this.x1, targetBox.x1);
this.y1 = Math.min(this.y1, targetBox.y1);
this.x2 = Math.max(this.x2, targetBox.x2);
this.y2 = Math.max(this.y2, targetBox.y2);
return this;
},
wrapPoint: function(point) {
var arrayPoint = isArray(point);
var x = arrayPoint ? point[0] : point.x;
var y = arrayPoint ? point[1] : point.y;
this.wrap(new Box(x, y, x, y));
return this;
},
snapTo: function(targetBox, axis) {
if (axis === X || !axis) {
this.x1 = targetBox.x1;
this.x2 = targetBox.x2;
}
if (axis === Y || !axis) {
this.y1 = targetBox.y1;
this.y2 = targetBox.y2;
}
return this;
},
alignTo: function(targetBox, anchor) {
var height = this.height();
var width = this.width();
var axis = anchor === TOP || anchor === BOTTOM ? Y : X;
var offset = axis === Y ? height : width;
if (anchor === CENTER) {
var targetCenter = targetBox.center();
var center = this.center();
this.x1 += targetCenter.x - center.x;
this.y1 += targetCenter.y - center.y;
} else if (anchor === TOP || anchor === LEFT) {
this[axis + 1] = targetBox[axis + 1] - offset;
} else {
this[axis + 1] = targetBox[axis + 2];
}
this.x2 = this.x1 + width;
this.y2 = this.y1 + height;
return this;
},
shrink: function(dw, dh) {
this.x2 -= dw;
this.y2 -= dh;
return this;
},
expand: function(dw, dh) {
this.shrink(-dw, -dh);
return this;
},
pad: function(padding) {
var spacing = getSpacing(padding);
this.x1 -= spacing.left;
this.x2 += spacing.right;
this.y1 -= spacing.top;
this.y2 += spacing.bottom;
return this;
},
unpad: function(padding) {
var spacing = getSpacing(padding);
spacing.left = -spacing.left;
spacing.top = -spacing.top;
spacing.right = -spacing.right;
spacing.bottom = -spacing.bottom;
return this.pad(spacing);
},
clone: function() {
return new Box(this.x1, this.y1, this.x2, this.y2);
},
center: function() {
return new Point(
this.x1 + this.width() / 2,
this.y1 + this.height() / 2
);
},
containsPoint: function(point) {
return point.x >= this.x1 && point.x <= this.x2 &&
point.y >= this.y1 && point.y <= this.y2;
},
points: function() {
return [
new Point(this.x1, this.y1),
new Point(this.x2, this.y1),
new Point(this.x2, this.y2),
new Point(this.x1, this.y2)
];
},
getHash: function() {
return [ this.x1, this.y1, this.x2, this.y2 ].join(",");
},
overlaps: function(box) {
return !(box.y2 < this.y1 || this.y2 < box.y1 || box.x2 < this.x1 || this.x2 < box.x1);
},
rotate: function(rotation) {
var width = this.width();
var height = this.height();
var ref = this.center();
var cx = ref.x;
var cy = ref.y;
var r1 = rotatePoint(0, 0, cx, cy, rotation);
var r2 = rotatePoint(width, 0, cx, cy, rotation);
var r3 = rotatePoint(width, height, cx, cy, rotation);
var r4 = rotatePoint(0, height, cx, cy, rotation);
width = Math.max(r1.x, r2.x, r3.x, r4.x) - Math.min(r1.x, r2.x, r3.x, r4.x);
height = Math.max(r1.y, r2.y, r3.y, r4.y) - Math.min(r1.y, r2.y, r3.y, r4.y);
this.x2 = this.x1 + width;
this.y2 = this.y1 + height;
return this;
},
toRect: function() {
return new Rect([ this.x1, this.y1 ], [ this.width(), this.height() ]);
},
hasSize: function() {
return this.width() !== 0 && this.height() !== 0;
},
align: function(targetBox, axis, alignment) {
var c1 = axis + 1;
var c2 = axis + 2;
var sizeFunc = axis === X ? WIDTH : HEIGHT;
var size = this[sizeFunc]();
if (inArray(alignment, [ LEFT, TOP ])) {
this[c1] = targetBox[c1];
this[c2] = this[c1] + size;
} else if (inArray(alignment, [ RIGHT, BOTTOM ])) {
this[c2] = targetBox[c2];
this[c1] = this[c2] - size;
} else if (alignment === CENTER) {
this[c1] = targetBox[c1] + (targetBox[sizeFunc]() - size) / 2;
this[c2] = this[c1] + size;
}
}
});
function rotatePoint(x, y, cx, cy, angle) {
var theta = rad(angle);
return new Point(
cx + (x - cx) * Math.cos(theta) + (y - cy) * Math.sin(theta),
cy - (x - cx) * Math.sin(theta) + (y - cy) * Math.cos(theta)
);
}
var Ring = Class.extend({
init: function(center, innerRadius, radius, startAngle, angle) {
this.center = center;
this.innerRadius = innerRadius;
this.radius = radius;
this.startAngle = startAngle;
this.angle = angle;
},
clone: function() {
return new Ring(this.center, this.innerRadius, this.radius, this.startAngle, this.angle);
},
middle: function() {
return this.startAngle + this.angle / 2;
},
setRadius: function(newRadius, innerRadius) {
if (innerRadius) {
this.innerRadius = newRadius;
} else {
this.radius = newRadius;
}
return this;
},
point: function(angle, innerRadius) {
var radianAngle = rad(angle);
var ax = Math.cos(radianAngle);
var ay = Math.sin(radianAngle);
var radius = innerRadius ? this.innerRadius : this.radius;
var x = round(this.center.x - (ax * radius), COORD_PRECISION);
var y = round(this.center.y - (ay * radius), COORD_PRECISION);
return new Point(x, y);
},
adjacentBox: function(distance, width, height) {
var sector = this.clone().expand(distance);
var midAndle = sector.middle();
var midPoint = sector.point(midAndle);
var hw = width / 2;
var hh = height / 2;
var sa = Math.sin(rad(midAndle));
var ca = Math.cos(rad(midAndle));
var x = midPoint.x - hw;
var y = midPoint.y - hh;
if (Math.abs(sa) < 0.9) {
x += hw * -ca / Math.abs(ca);
}
if (Math.abs(ca) < 0.9) {
y += hh * -sa / Math.abs(sa);
}
return new Box(x, y, x + width, y + height);
},
containsPoint: function(p) {
var center = this.center;
var innerRadius = this.innerRadius;
var radius = this.radius;
var startAngle = this.startAngle;
var endAngle = this.startAngle + this.angle;
var dx = p.x - center.x;
var dy = p.y - center.y;
var vector = new Point(dx, dy);
var startPoint = this.point(startAngle);
var startVector = new Point(startPoint.x - center.x, startPoint.y - center.y);
var endPoint = this.point(endAngle);
var endVector = new Point(endPoint.x - center.x, endPoint.y - center.y);
var dist = round(dx * dx + dy * dy, COORD_PRECISION);
return (startVector.equals(vector) || clockwise(startVector, vector)) &&
!clockwise(endVector, vector) &&
dist >= innerRadius * innerRadius && dist <= radius * radius;
},
getBBox: function() {
var this$1 = this;
var box = new Box(MAX_VALUE, MAX_VALUE, MIN_VALUE, MIN_VALUE);
var startAngle = round(this.startAngle % 360);
var endAngle = round((startAngle + this.angle) % 360);
var innerRadius = this.innerRadius;
var allAngles = [ 0, 90, 180, 270, startAngle, endAngle ].sort(numericComparer);
var startAngleIndex = allAngles.indexOf(startAngle);
var endAngleIndex = allAngles.indexOf(endAngle);
var angles;
if (startAngle === endAngle) {
angles = allAngles;
} else {
if (startAngleIndex < endAngleIndex) {
angles = allAngles.slice(startAngleIndex, endAngleIndex + 1);
} else {
angles = [].concat(
allAngles.slice(0, endAngleIndex + 1),
allAngles.slice(startAngleIndex, allAngles.length)
);
}
}
for (var i = 0; i < angles.length; i++) {
var point = this$1.point(angles[i]);
box.wrapPoint(point);
box.wrapPoint(point, innerRadius);
}
if (!innerRadius) {
box.wrapPoint(this.center);
}
return box;
},
expand: function(value) {
this.radius += value;
return this;
}
});
function numericComparer(a, b) {
return a - b;
}
var Sector = Ring.extend({
init: function(center, radius, startAngle, angle) {
Ring.fn.init.call(this, center, 0, radius, startAngle, angle);
},
expand: function(value) {
return Ring.fn.expand.call(this, value);
},
clone: function() {
return new Sector(this.center, this.radius, this.startAngle, this.angle);
},
setRadius: function(newRadius) {
this.radius = newRadius;
return this;
}
});
var DIRECTION_ANGLE = 0.001; //any value that will make the endAngle bigger than the start angle will work here.
var ShapeBuilder = Class.extend({
createRing: function(sector, options) {
var startAngle = sector.startAngle + 180;
var endAngle = sector.angle + startAngle;
//required in order to avoid reversing the arc direction in cases like 0.000000000000001 + 100 === 100
if (sector.angle > 0 && startAngle === endAngle) {
endAngle += DIRECTION_ANGLE;
}
var center = new geometry.Point(sector.center.x, sector.center.y);
var radius = Math.max(sector.radius, 0);
var innerRadius = Math.max(sector.innerRadius, 0);
var arc = new geometry.Arc(center, {
startAngle: startAngle,
endAngle: endAngle,
radiusX: radius,
radiusY: radius
});
var path = Path.fromArc(arc, options).close();
if (innerRadius) {
arc.radiusX = arc.radiusY = innerRadius;
var innerEnd = arc.pointAt(endAngle);
path.lineTo(innerEnd.x, innerEnd.y);
path.arc(endAngle, startAngle, innerRadius, innerRadius, true);
} else {
path.lineTo(center.x, center.y);
}
return path;
}
});
ShapeBuilder.current = new ShapeBuilder();
var ChartElement = Class.extend({
init: function(options) {
this.children = [];
this.options = deepExtend({}, this.options, this.initUserOptions(options));
},
initUserOptions: function(options) {
return options;
},
reflow: function(targetBox) {
var children = this.children;
var box;
for (var i = 0; i < children.length; i++) {
var currentChild = children[i];
currentChild.reflow(targetBox);
box = box ? box.wrap(currentChild.box) : currentChild.box.clone();
}
this.box = box || targetBox;
},
destroy: function() {
var children = this.children;
if (this.animation) {
this.animation.destroy();
}
for (var i = 0; i < children.length; i++) {
children[i].destroy();
}
},
getRoot: function() {
var parent = this.parent;
return parent ? parent.getRoot() : null;
},
getSender: function() {
var service = this.getService();
if (service) {
return service.sender;
}
},
getService: function() {
var element = this;
while (element) {
if (element.chartService) {
return element.chartService;
}
element = element.parent;
}
},
translateChildren: function(dx, dy) {
var children = this.children;
var childrenCount = children.length;
for (var i = 0; i < childrenCount; i++) {
children[i].box.translate(dx, dy);
}
},
append: function() {
var arguments$1 = arguments;
var this$1 = this;
for (var i = 0; i < arguments.length; i++) {
var item = arguments$1[i];
this$1.children.push(item);
item.parent = this$1;
}
},
renderVisual: function() {
if (this.options.visible === false) {
return;
}
this.createVisual();
this.addVisual();
this.renderChildren();
this.createAnimation();
this.renderComplete();
},
addVisual: function() {
if (this.visual) {
this.visual.chartElement = this;
if (this.parent) {
this.parent.appendVisual(this.visual);
}
}
},
renderChildren: function() {
var children = this.children;
var length = children.length;
for (var i = 0; i < length; i++) {
children[i].renderVisual();
}
},
createVisual: function() {
this.visual = new Group({
zIndex: this.options.zIndex,
visible: valueOrDefault(this.options.visible, true)
});
},
createAnimation: function() {
if (this.visual && this.options.animation) {
this.animation = drawing.Animation.create(
this.visual, this.options.animation
);
}
},
appendVisual: function(childVisual) {
if (!childVisual.chartElement) {
childVisual.chartElement = this;
}
if (childVisual.options.noclip) {
this.clipRoot().visual.append(childVisual);
} else if (defined(childVisual.options.zIndex)) {
this.stackRoot().stackVisual(childVisual);
} else if (this.isStackRoot) {
this.stackVisual(childVisual);
} else if (this.visual) {
this.visual.append(childVisual);
} else {
// Allow chart elements without visuals to
// pass through child visuals
this.parent.appendVisual(childVisual);
}
},
clipRoot: function() {
if (this.parent) {
return this.parent.clipRoot();
}
return this;
},
stackRoot: function() {
if (this.parent) {
return this.parent.stackRoot();
}
return this;
},
stackVisual: function(childVisual) {
var zIndex = childVisual.options.zIndex || 0;
var visuals = this.visual.children;
var length = visuals.length;
var pos;
for (pos = 0; pos < length; pos++) {
var sibling = visuals[pos];
var here = valueOrDefault(sibling.options.zIndex, 0);
if (here > zIndex) {
break;
}
}
this.visual.insert(pos, childVisual);
},
traverse: function(callback) {
var children = this.children;
var length = children.length;
for (var i = 0; i < length; i++) {
var child = children[i];
callback(child);
if (child.traverse) {
child.traverse(callback);
}
}
},
closest: function(match) {
var element = this;
var matched = false;
while (element && !matched) {
matched = match(element);
if (!matched) {
element = element.parent;
}
}
if (matched) {
return element;
}
},
renderComplete: function() {},
hasHighlight: function() {
var options = (this.options || {}).highlight;
return !(!this.createHighlight || (options && options.visible === false));
},
toggleHighlight: function(show) {
var this$1 = this;
var options = (this.options || {}).highlight || {};
var customVisual = options.visual;
var highlight = this._highlight;
if (!highlight) {
var highlightOptions = {
fill: {
color: WHITE,
opacity: 0.2
},
stroke: {
color: WHITE,
width: 1,
opacity: 0.2
}
};
if (customVisual) {
highlight = this._highlight = customVisual(
$.extend(this.highlightVisualArgs(), {
createVisual: function () { return this$1.createHighlight(highlightOptions); },
sender: this.getSender(),
series: this.series,
dataItem: this.dataItem,
category: this.category,
value: this.value,
percentage: this.percentage,
runningTotal: this.runningTotal,
total: this.total
}
));
if (!highlight) {
return;
}
} else {
highlight = this._highlight = this.createHighlight(highlightOptions);
}
if (!defined(highlight.options.zIndex)) {
highlight.options.zIndex = valueOrDefault(options.zIndex, this.options.zIndex);
}
this.appendVisual(highlight);
}
highlight.visible(show);
},
createGradientOverlay: function(element, options, gradientOptions) {
var overlay = new Path($.extend({
stroke: {
color: "none"
},
fill: this.createGradient(gradientOptions),
closed: element.options.closed
}, options));
overlay.segments.elements(element.segments.elements());
return overlay;
},
createGradient: function(options) {
if (this.parent) {
return this.parent.createGradient(options);
}
}
});
ChartElement.prototype.options = { };
var BoxElement = ChartElement.extend({
init: function(options) {
ChartElement.fn.init.call(this, options);
this.options.margin = getSpacing(this.options.margin);
this.options.padding = getSpacing(this.options.padding);
},
reflow: function(targetBox) {
var this$1 = this;
var options = this.options;
var width = options.width;
var height = options.height;
var shrinkToFit = options.shrinkToFit;
var hasSetSize = width && height;
var margin = options.margin;
var padding = options.padding;
var borderWidth = options.border.width;
var box;
var reflowPaddingBox = function () {
this$1.align(targetBox, X, options.align);
this$1.align(targetBox, Y, options.vAlign);
this$1.paddingBox = box.clone().unpad(margin).unpad(borderWidth);
};
var contentBox = targetBox.clone();
if (hasSetSize) {
contentBox.x2 = contentBox.x1 + width;
contentBox.y2 = contentBox.y1 + height;
}
if (shrinkToFit) {
contentBox.unpad(margin).unpad(borderWidth).unpad(padding);
}
ChartElement.fn.reflow.call(this, contentBox);
if (hasSetSize) {
box = this.box = new Box(0, 0, width, height);
} else {
box = this.box;
}
if (shrinkToFit && hasSetSize) {
reflowPaddingBox();
contentBox = this.contentBox = this.paddingBox.clone().unpad(padding);
} else {
contentBox = this.contentBox = box.clone();
box.pad(padding).pad(borderWidth).pad(margin);
reflowPaddingBox();
}
this.translateChildren(
box.x1 - contentBox.x1 + margin.left + borderWidth + padding.left,
box.y1 - contentBox.y1 + margin.top + borderWidth + padding.top
);
var children = this.children;
for (var i = 0; i < children.length; i++) {
var item = children[i];
item.reflow(item.box);
}
},
align: function(targetBox, axis, alignment) {
this.box.align(targetBox, axis, alignment);
},
hasBox: function() {
var options = this.options;
return options.border.width || options.background;
},
createVisual: function() {
ChartElement.fn.createVisual.call(this);
var options = this.options;
if (options.visible && this.hasBox()) {
this.visual.append(Path.fromRect(
this.paddingBox.toRect(),
this.visualStyle()
));
}
},
visualStyle: function() {
var options = this.options;
var border = options.border || {};
return {
stroke: {
width: border.width,
color: border.color,
opacity: valueOrDefault(border.opacity, options.opacity),
dashType: border.dashType
},
fill: {
color: options.background,
opacity: options.opacity
},
cursor: options.cursor
};
}
});
setDefaultOptions(BoxElement, {
align: LEFT,
vAlign: TOP,
margin: {},
padding: {},
border: {
color: BLACK,
width: 0
},
background: "",
shrinkToFit: false,
width: 0,
height: 0,
visible: true
});
var ShapeElement = BoxElement.extend({
init: function(options, pointData) {
BoxElement.fn.init.call(this, options);
this.pointData = pointData;
},
getElement: function() {
var ref = this;
var options = ref.options;
var box = ref.paddingBox;
var type = options.type;
var rotation = options.rotation;
var center = box.center();
var halfWidth = box.width() / 2;
if (!options.visible || !this.hasBox()) {
return null;
}
var style = this.visualStyle();
var element;
if (type === CIRCLE) {
element = new drawing.Circle(
new Circle([
round(box.x1 + halfWidth, COORD_PRECISION),
round(box.y1 + box.height() / 2, COORD_PRECISION)
], halfWidth),
style
);
} else if (type === TRIANGLE) {
element = Path.fromPoints([
[ box.x1 + halfWidth, box.y1 ],
[ box.x1, box.y2 ],
[ box.x2, box.y2 ]
], style).close();
} else if (type === CROSS) {
element = new drawing.MultiPath(style);
element.moveTo(box.x1, box.y1).lineTo(box.x2, box.y2);
element.moveTo(box.x1, box.y2).lineTo(box.x2, box.y1);
} else {
element = Path.fromRect(box.toRect(), style);
}
if (rotation) {
element.transform(geometryTransform()
.rotate(-rotation, [ center.x, center.y ])
);
}
element.options.zIndex = options.zIndex;
return element;
},
createElement: function() {
var this$1 = this;
var customVisual = this.options.visual;
var pointData = this.pointData || {};
var visual;
if (customVisual) {
visual = customVisual({
value: pointData.value,
dataItem: pointData.dataItem,
sender: this.getSender(),
series: pointData.series,
category: pointData.category,
rect: this.paddingBox.toRect(),
options: this.visualOptions(),
createVisual: function () { return this$1.getElement(); }
});
} else {
visual = this.getElement();
}
return visual;
},
visualOptions: function() {
var options = this.options;
return {
background: options.background,
border: options.border,
margin: options.margin,
padding: options.padding,
type: options.type,
size: options.width,
visible: options.visible
};
},
createVisual: function() {
this.visual = this.createElement();
}
});
setDefaultOptions(ShapeElement, {
type: CIRCLE,
align: CENTER,
vAlign: CENTER
});
var LINEAR = "linear";
var RADIAL = "radial";
var GRADIENTS = {
glass: {
type: LINEAR,
rotation: 0,
stops: [ {
offset: 0,
color: WHITE,
opacity: 0
}, {
offset: 0.25,
color: WHITE,
opacity: 0.3
}, {
offset: 1,
color: WHITE,
opacity: 0
} ]
},
sharpBevel: {
type: RADIAL,
stops: [ {
offset: 0,
color: WHITE,
opacity: 0.55
}, {
offset: 0.65,
color: WHITE,
opacity: 0
}, {
offset: 0.95,
color: WHITE,
opacity: 0.25
} ]
},
roundedBevel: {
type: RADIAL,
stops: [ {
offset: 0.33,
color: WHITE,
opacity: 0.06
}, {
offset: 0.83,
color: WHITE,
opacity: 0.2
}, {
offset: 0.95,
color: WHITE,
opacity: 0
} ]
},
roundedGlass: {
type: RADIAL,
supportVML: false,
stops: [ {
offset: 0,
color: WHITE,
opacity: 0
}, {
offset: 0.5,
color: WHITE,
opacity: 0.3
}, {
offset: 0.99,
color: WHITE,
opacity: 0
} ]
},
sharpGlass: {
type: RADIAL,
supportVML: false,
stops: [ {
offset: 0,
color: WHITE,
opacity: 0.2
}, {
offset: 0.15,
color: WHITE,
opacity: 0.15
}, {
offset: 0.17,
color: WHITE,
opacity: 0.35
}, {
offset: 0.85,
color: WHITE,
opacity: 0.05
}, {
offset: 0.87,